[Orca-checkins] rev 126 - in trunk/orca: . src docs contrib contrib/rotate_orca_graphs contrib/orcaservices orcallator config lib lib/Orca packages packages/Digest-MD5-2.13 packages/Digest-MD5-2.13/t packages/Time-HiRes-01.20 packages/Time-HiRes-01.20/t packages/rrdtool-1.0.33 packages/rrdtool-1.0.33/tcl packages/rrdtool-1.0.33/src packages/rrdtool-1.0.33/cgilib-0.4 packages/rrdtool-1.0.33/zlib-1.1.3 packages/rrdtool-1.0.33/contrib packages/rrdtool-1.0.33/contrib/rrdview packages/rrdtool-1.0.33/contrib/rrdfetchnames packages/rrdtool-1.0.33/contrib/killspike packages/rrdtool-1.0.33/contrib/rrd-file-icon packages/rrdtool-1.0.33/contrib/snmpstats packages/rrdtool-1.0.33/contrib/trytime packages/rrdtool-1.0.33/contrib/rrdlastds packages/rrdtool-1.0.33/contrib/rrdexplorer packages/rrdtool-1.0.33/contrib/php3 packages/rrdtool-1.0.33/contrib/php3/examples packages/rrdtool-1.0.33/contrib/log2rrd packages/rrdtool-1.0.33/contrib/rrdproc packages/rrdtool-1.0.33/contrib/php4 packages/rrdtool-1.0.33/contrib/php4/build packages/rrdtool-1.0.33/contrib/php4/examples packages/rrdtool-1.0.33/contrib/add_ds packages/rrdtool-1.0.33/contrib/add_ds/add_ds packages/rrdtool-1.0.33/perl-piped packages/rrdtool-1.0.33/config packages/rrdtool-1.0.33/doc packages/rrdtool-1.0.33/perl-shared packages/rrdtool-1.0.33/perl-shared/t packages/rrdtool-1.0.33/gd1.3 packages/rrdtool-1.0.33/examples packages/rrdtool-1.0.33/libpng-1.0.9 packages/Storable-1.0.11 packages/Storable-1.0.11/t packages/TimeDate-1.10 packages/TimeDate-1.10/t packages/TimeDate-1.10/lib packages/TimeDate-1.10/lib/Date packages/TimeDate-1.10/lib/Date/Language packages/TimeDate-1.10/lib/Time

blair at orcaware.com blair at orcaware.com
Sat Jul 13 21:28:04 PDT 2002


Author: blair
Date: Fri, 28 Jun 2002 22:11:56 -0700
New Revision: 126

Added:
   trunk/orca/contrib/
   trunk/orca/contrib/Makefile.in
   trunk/orca/contrib/orcaservices/
   trunk/orca/contrib/orcaservices/Makefile.in
   trunk/orca/contrib/orcaservices/README
   trunk/orca/contrib/orcaservices/S99orcaservices.sh.in
   trunk/orca/contrib/orcaservices/orcaservices.cfg.in
   trunk/orca/contrib/orcaservices/orcaservices.pl.in
   trunk/orca/contrib/orcaservices/orcaservices_running.pl.in
   trunk/orca/contrib/orcaservices/restart_orcaservices.sh.in
   trunk/orca/contrib/orcaservices/start_orcaservices.sh.in
   trunk/orca/contrib/orcaservices/stop_orcaservices.sh.in
   trunk/orca/contrib/rotate_orca_graphs/
   trunk/orca/contrib/rotate_orca_graphs/Makefile.in
   trunk/orca/contrib/rotate_orca_graphs/rotate_orca_graphs.sh.in
   trunk/orca/packages/Storable-1.0.11/t/blessed.t
   trunk/orca/packages/Storable-1.0.11/t/compat-0.6.t
   trunk/orca/packages/Storable-1.0.11/t/lock.t
   trunk/orca/packages/Storable-1.0.11/t/overload.t
   trunk/orca/packages/Storable-1.0.11/t/recurse.t
   trunk/orca/packages/Storable-1.0.11/t/tied_hook.t
   trunk/orca/packages/Storable-1.0.11/t/tied_items.t
   trunk/orca/packages/Storable-1.0.11/t/utf8.t
   trunk/orca/packages/Time-HiRes-01.20/
   trunk/orca/packages/Time-HiRes-01.20/Changes
   trunk/orca/packages/Time-HiRes-01.20/HiRes.pm
   trunk/orca/packages/Time-HiRes-01.20/HiRes.xs
   trunk/orca/packages/Time-HiRes-01.20/MANIFEST
   trunk/orca/packages/Time-HiRes-01.20/Makefile.PL
   trunk/orca/packages/Time-HiRes-01.20/README
   trunk/orca/packages/Time-HiRes-01.20/TODO
   trunk/orca/packages/Time-HiRes-01.20/t/
   trunk/orca/packages/Time-HiRes-01.20/t/01test.t
   trunk/orca/packages/Time-HiRes-01.20/t/02export.t
   trunk/orca/packages/TimeDate-1.10/
   trunk/orca/packages/TimeDate-1.10/ChangeLog
   trunk/orca/packages/TimeDate-1.10/MANIFEST
   trunk/orca/packages/TimeDate-1.10/Makefile.PL
   trunk/orca/packages/TimeDate-1.10/README
   trunk/orca/packages/TimeDate-1.10/TimeDate.ppd
   trunk/orca/packages/TimeDate-1.10/lib/
   trunk/orca/packages/TimeDate-1.10/lib/Date/
   trunk/orca/packages/TimeDate-1.10/lib/Date/Format.pm
   trunk/orca/packages/TimeDate-1.10/lib/Date/Language.pm
   trunk/orca/packages/TimeDate-1.10/lib/Date/Language/
   trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Austrian.pm
   trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Czech.pm
   trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Dutch.pm
   trunk/orca/packages/TimeDate-1.10/lib/Date/Language/English.pm
   trunk/orca/packages/TimeDate-1.10/lib/Date/Language/French.pm
   trunk/orca/packages/TimeDate-1.10/lib/Date/Language/German.pm
   trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Italian.pm
   trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Norwegian.pm
   trunk/orca/packages/TimeDate-1.10/lib/Date/Parse.pm
   trunk/orca/packages/TimeDate-1.10/lib/Time/
   trunk/orca/packages/TimeDate-1.10/lib/Time/Zone.pm
   trunk/orca/packages/TimeDate-1.10/t/
   trunk/orca/packages/TimeDate-1.10/t/date.t
   trunk/orca/packages/TimeDate-1.10/t/format.t
   trunk/orca/packages/TimeDate-1.10/t/getdate.t
   trunk/orca/packages/TimeDate-1.10/t/lang.t
   trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/add_ds.pl
   trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/add_ds/
   trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/add_ds/add_ds.pl
   trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/add_ds/batch.pl
   trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/batch.pl
   trunk/orca/packages/rrdtool-1.0.33/contrib/killspike/killspike.pl
   trunk/orca/packages/rrdtool-1.0.33/contrib/log2rrd/log2rrd.pl
   trunk/orca/packages/rrdtool-1.0.33/contrib/php3/
   trunk/orca/packages/rrdtool-1.0.33/contrib/php3/INSTALL
   trunk/orca/packages/rrdtool-1.0.33/contrib/php3/Makefile
   trunk/orca/packages/rrdtool-1.0.33/contrib/php3/README
   trunk/orca/packages/rrdtool-1.0.33/contrib/php3/USAGE
   trunk/orca/packages/rrdtool-1.0.33/contrib/php3/VERSION
   trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/
   trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_create.php
   trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_fetch.php
   trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_graph.php
   trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_last.php
   trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_update.php
   trunk/orca/packages/rrdtool-1.0.33/contrib/php3/php3_rrdtool.c
   trunk/orca/packages/rrdtool-1.0.33/contrib/php3/php3_rrdtool.h
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/.cvsignore
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/.deps
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/INSTALL
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/README
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/USAGE
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/acinclude.m4
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/aclocal.m4
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/dynlib.mk
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/fastgen.sh
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/library.mk
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/ltlib.mk
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/program.mk
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/rules.mk
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/shtool
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/config.guess
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/config.m4
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/config.sub
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/configure
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/configure.in
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/dynlib.m4
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_create.php
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_fetch.php
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_graph.php
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_last.php
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_update.php
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/install-sh
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/ltconfig
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/ltmain.sh
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/missing
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/mkinstalldirs
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/php_config.h.in
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/php_rrdtool.h
   trunk/orca/packages/rrdtool-1.0.33/contrib/php4/rrdtool.c
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdexplorer/
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdexplorer/README.txt
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdexplorer/map.cgi
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdexplorer/png.cgi
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdfetchnames/rrdfetchnames.pl
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/rrdlastds.pl
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/rrdlastds.pl.in.orig
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/rrdlastds.pl.in.rej
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdproc/.deps/
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdview/
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdview/README
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdview/rrdview.cgi
   trunk/orca/packages/rrdtool-1.0.33/contrib/snmpstats/
   trunk/orca/packages/rrdtool-1.0.33/contrib/snmpstats/README
   trunk/orca/packages/rrdtool-1.0.33/contrib/snmpstats/SNMPstats.pl
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdinfo.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdinfo.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdinfo.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.es.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.es.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.es.txt
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/configure
   trunk/orca/packages/rrdtool-1.0.33/rrdtool.spec
   trunk/orca/packages/rrdtool-1.0.33/src/rrd.h
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_info.c
   trunk/orca/packages/rrdtool-1.0.33/tcl/
   trunk/orca/packages/rrdtool-1.0.33/tcl/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/tcl/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/tcl/README
   trunk/orca/packages/rrdtool-1.0.33/tcl/ifOctets.tcl
   trunk/orca/packages/rrdtool-1.0.33/tcl/tclrrd.c
Removed:
   trunk/orca/packages/Digest-MD5-2.13/MD2/
   trunk/orca/packages/Digest-MD5-2.13/SHA1/
   trunk/orca/packages/Digest-MD5-2.13/examples/
   trunk/orca/packages/Digest-MD5-2.13/lib/
   trunk/orca/packages/Digest-MD5-2.13/rfc2104.txt
   trunk/orca/packages/Digest-MD5-2.13/t/digest.t
   trunk/orca/packages/Digest-MD5-2.13/t/md5.t
   trunk/orca/packages/Digest-MD5-2.13/t/rfc2202.t
   trunk/orca/packages/Storable-1.0.11/patchlevel.h
   trunk/orca/packages/rrdtool-1.0.33/config/acinclude.m4
   trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/contrib/killspike/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/contrib/killspike/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/contrib/log2rrd/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/contrib/log2rrd/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrd-file-icon/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrd-file-icon/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdfetchnames/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdfetchnames/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdproc/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/contrib/rrdproc/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/ansi2knr.1
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/ansi2knr.c
Modified:
   trunk/orca/CHANGES
   trunk/orca/FAQ
   trunk/orca/INSTALL
   trunk/orca/Makefile.in
   trunk/orca/NEWS
   trunk/orca/README
   trunk/orca/TODO
   trunk/orca/config/PerlHead1.in
   trunk/orca/config/PerlHead2.in
   trunk/orca/configure
   trunk/orca/configure.in
   trunk/orca/docs/Makefile.in
   trunk/orca/docs/REQUIREMENTS
   trunk/orca/docs/manual.html
   trunk/orca/lib/Makefile.in
   trunk/orca/lib/Orca/Config.pm
   trunk/orca/lib/Orca/Constants.pm
   trunk/orca/lib/Orca/DataFile.pm
   trunk/orca/lib/Orca/HTMLFile.pm
   trunk/orca/lib/Orca/ImageFile.pm
   trunk/orca/lib/Orca/NewState.pm
   trunk/orca/lib/Orca/OldState.pm
   trunk/orca/lib/Orca/OpenFileHash.pm
   trunk/orca/lib/Orca/RRDFile.pm
   trunk/orca/lib/Orca/SourceFile.pm
   trunk/orca/lib/Orca/SourceFileIDs.pm
   trunk/orca/lib/Orca/Utils.pm
   trunk/orca/lib/download.cfg
   trunk/orca/lib/homesteaders.cfg
   trunk/orca/lib/time_gets.cfg
   trunk/orca/orcallator/Makefile.in
   trunk/orca/orcallator/orcallator.cfg.in
   trunk/orca/orcallator/orcallator.se
   trunk/orca/orcallator/orcallator_column.pl
   trunk/orca/orcallator/orcallator_running.pl.in
   trunk/orca/orcallator/start_orcallator.sh.in
   trunk/orca/packages/Digest-MD5-2.13/Changes
   trunk/orca/packages/Digest-MD5-2.13/MANIFEST
   trunk/orca/packages/Digest-MD5-2.13/MD5.pm
   trunk/orca/packages/Digest-MD5-2.13/MD5.xs
   trunk/orca/packages/Digest-MD5-2.13/README
   trunk/orca/packages/Digest-MD5-2.13/t/files.t
   trunk/orca/packages/Makefile.in
   trunk/orca/packages/Storable-1.0.11/ChangeLog
   trunk/orca/packages/Storable-1.0.11/MANIFEST
   trunk/orca/packages/Storable-1.0.11/Makefile.PL
   trunk/orca/packages/Storable-1.0.11/README
   trunk/orca/packages/Storable-1.0.11/Storable.pm
   trunk/orca/packages/Storable-1.0.11/Storable.xs
   trunk/orca/packages/Storable-1.0.11/t/canonical.t
   trunk/orca/packages/Storable-1.0.11/t/dclone.t
   trunk/orca/packages/Storable-1.0.11/t/dump.pl
   trunk/orca/packages/Storable-1.0.11/t/forgive.t
   trunk/orca/packages/Storable-1.0.11/t/freeze.t
   trunk/orca/packages/Storable-1.0.11/t/retrieve.t
   trunk/orca/packages/Storable-1.0.11/t/store.t
   trunk/orca/packages/Storable-1.0.11/t/tied.t
   trunk/orca/packages/rrdtool-1.0.33/CHANGES
   trunk/orca/packages/rrdtool-1.0.33/CONTRIBUTORS
   trunk/orca/packages/rrdtool-1.0.33/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/README
   trunk/orca/packages/rrdtool-1.0.33/TODO
   trunk/orca/packages/rrdtool-1.0.33/cgilib-0.4/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/cgilib-0.4/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/config/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/config/acconfig.h
   trunk/orca/packages/rrdtool-1.0.33/config/aclocal.m4
   trunk/orca/packages/rrdtool-1.0.33/config/config.h.in
   trunk/orca/packages/rrdtool-1.0.33/config/ltconfig
   trunk/orca/packages/rrdtool-1.0.33/configure
   trunk/orca/packages/rrdtool-1.0.33/configure.in
   trunk/orca/packages/rrdtool-1.0.33/contrib/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/contrib/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/contrib/killspike/killspike.pl.in
   trunk/orca/packages/rrdtool-1.0.33/contrib/trytime/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/doc/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/doc/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/doc/RRDp.html
   trunk/orca/packages/rrdtool-1.0.33/doc/RRDp.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/RRDs.html
   trunk/orca/packages/rrdtool-1.0.33/doc/RRDs.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/bin_dec_hex.html
   trunk/orca/packages/rrdtool-1.0.33/doc/bin_dec_hex.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/bin_dec_hex.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/cdeftutorial.html
   trunk/orca/packages/rrdtool-1.0.33/doc/cdeftutorial.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/cdeftutorial.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/rpntutorial.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rpntutorial.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rpntutorial.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdcgi.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdcgi.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdcgi.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdcreate.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdcreate.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdcreate.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/rrddump.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rrddump.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rrddump.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdfetch.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdfetch.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdfetch.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdgraph.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdgraph.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdgraph.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdlast.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdlast.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdlast.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdresize.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdresize.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdresize.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdrestore.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdrestore.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdrestore.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdtool.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdtool.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdtool.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdtune.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdtune.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdtune.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.txt
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdupdate.html
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdupdate.pod
   trunk/orca/packages/rrdtool-1.0.33/doc/rrdupdate.txt
   trunk/orca/packages/rrdtool-1.0.33/examples/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/examples/piped-demo.pl.in
   trunk/orca/packages/rrdtool-1.0.33/examples/shared-demo.pl.in
   trunk/orca/packages/rrdtool-1.0.33/gd1.3/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/gd1.3/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/gd1.3/gd.c
   trunk/orca/packages/rrdtool-1.0.33/gd1.3/gd.h
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/ANNOUNCE
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/CHANGES
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/INSTALL
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/KNOWNBUG
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/README
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/README.rrdtool
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/TODO
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/Y2KINFO
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/example.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/libpng.3
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/libpng.txt
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/libpngpf.3
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/png.5
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/png.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/png.h
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngconf.h
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngerror.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngget.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngmem.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngpread.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngread.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngrio.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngrtran.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngrutil.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngset.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngtrans.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwio.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwrite.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwtran.c
   trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwutil.c
   trunk/orca/packages/rrdtool-1.0.33/perl-piped/RRDp.pm
   trunk/orca/packages/rrdtool-1.0.33/perl-shared/Makefile.PL
   trunk/orca/packages/rrdtool-1.0.33/perl-shared/RRDs.pm
   trunk/orca/packages/rrdtool-1.0.33/perl-shared/RRDs.xs
   trunk/orca/packages/rrdtool-1.0.33/perl-shared/t/base.t
   trunk/orca/packages/rrdtool-1.0.33/src/Makefile.am
   trunk/orca/packages/rrdtool-1.0.33/src/Makefile.in
   trunk/orca/packages/rrdtool-1.0.33/src/gdpng.c
   trunk/orca/packages/rrdtool-1.0.33/src/gifsize.c
   trunk/orca/packages/rrdtool-1.0.33/src/parsetime.c
   trunk/orca/packages/rrdtool-1.0.33/src/parsetime.h
   trunk/orca/packages/rrdtool-1.0.33/src/pngsize.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_cgi.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_create.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_diff.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_dump.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_error.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_fetch.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_format.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_format.h
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_graph.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_last.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_open.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_resize.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_restore.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_tool.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_tool.h
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_tune.c
   trunk/orca/packages/rrdtool-1.0.33/src/rrd_update.c
   trunk/orca/packages/rrdtool-1.0.33/zlib-1.1.3/Makefile.in
   trunk/orca/src/Makefile.in
   trunk/orca/src/orca.pl.in
Log:
Load orca-0.27b1 into trunk/orca.


Modified: trunk/orca/configure
==============================================================================
--- trunk/orca/configure	(original)
+++ trunk/orca/configure	Sat Jul 13 21:25:40 2002
@@ -643,19 +643,46 @@
 
 
 # Remember the command line arguments to configure for use when
-# configure is run again.
-CONFIGURE_COMMAND_LINE=${1+"$@"}
+# configure is run again.  Also create the command line options for
+# RRD configure.
+ORCA_CONFIGURE_COMMAND_LINE=${1+"$@"}
+RRD_CONFIGURE_COMMAND_LINE="$ORCA_CONFIGURE_COMMAND_LINE --cache-file=../../config.cache"
 
 
+
+# Set this to yes to have configure always build all of the required
+# Perl Orca modules.  This is used to test the build more than
+# anything else.
+ALWAYS_BUILD_PERL_MODULES=yes
+ALWAYS_BUILD_PERL_MODULES=
+
 # Define the directories containing packages that Orca makes use of here.
 # The directory name packages where these packages are distributed with
 # Orca gets added where necessary.
 COMPRESS_ZLIB_DIR=Compress-Zlib-1.05
+COMPRESS_ZLIB_VER=1.05
 DATA_DUMPER_DIR=Data-Dumper-2.101
-DIGEST_MD5_DIR=Digest-MD5-2.09
+DATA_DUMPER_VER=2.101
+DATE_PARSE_DIR=TimeDate-1.10
+DATE_PARSE_VER=2.20
+DIGEST_MD5_DIR=Digest-MD5-2.13
+DIGEST_MD5_VER=2.13
 MATH_INTERPOLATE_DIR=Math-Interpolate-1.05
-RRDTOOL_DIR=rrdtool-1.0.13
-STORABLE_DIR=Storable-0.6.9
+MATH_INTERPOLATE_VER=1.05
+RRDTOOL_DIR=rrdtool-1.0.33
+RRDTOOL_VER=1.000331
+STORABLE_DIR=Storable-1.0.11
+STORABLE_VER=1.011
+TIME_HIRES_DIR=Time-HiRes-01.20
+TIME_HIRES_VER=1.20
+
+
+
+
+
+
+
+
 
 
 
@@ -663,6 +690,16 @@
 
 
 
+
+
+
+# Get the current working directory and the config directory.
+cwd=`pwd`
+config_dir="$cwd/config"
+if test ! -d $config_dir; then
+  { echo "configure: error: *** Cannot find config directory." 1>&2; exit 1; }
+fi
+
 # Minimum Autoconf version required.
 
 
@@ -807,7 +844,7 @@
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:811: checking for $ac_word" >&5
+echo "configure:848: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -837,7 +874,7 @@
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:841: checking for $ac_word" >&5
+echo "configure:878: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -888,7 +925,7 @@
       # Extract the first word of "cl", so it can be a program name with args.
 set dummy cl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:892: checking for $ac_word" >&5
+echo "configure:929: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -920,7 +957,7 @@
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:924: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:961: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -931,12 +968,12 @@
 
 cat > conftest.$ac_ext << EOF
 
-#line 935 "configure"
+#line 972 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:940: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:977: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -962,12 +999,12 @@
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:966: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1003: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:971: checking whether we are using GNU C" >&5
+echo "configure:1008: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -976,7 +1013,7 @@
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:980: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1017: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -995,7 +1032,7 @@
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:999: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:1036: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1028,7 +1065,7 @@
 
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:1032: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:1069: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1076,7 +1113,7 @@
 # Extract the first word of "bzip2", so it can be a program name with args.
 set dummy bzip2; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1080: checking for $ac_word" >&5
+echo "configure:1117: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_BZIP2'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1111,7 +1148,7 @@
 # Extract the first word of "bunzip2", so it can be a program name with args.
 set dummy bunzip2; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1115: checking for $ac_word" >&5
+echo "configure:1152: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_BUNZIP2'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1146,7 +1183,7 @@
 # Extract the first word of "compress", so it can be a program name with args.
 set dummy compress; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1150: checking for $ac_word" >&5
+echo "configure:1187: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_COMPRESS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1181,7 +1218,7 @@
 # Extract the first word of "cut", so it can be a program name with args.
 set dummy cut; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1185: checking for $ac_word" >&5
+echo "configure:1222: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_CUT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1217,7 +1254,7 @@
 # Extract the first word of "expr", so it can be a program name with args.
 set dummy expr; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1221: checking for $ac_word" >&5
+echo "configure:1258: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_EXPR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1250,10 +1287,50 @@
   echo "$ac_t""no" 1>&6
 fi
 
+for ac_prog in gtar gnutar tar
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1296: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_TAR'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$TAR" in
+  /*)
+  ac_cv_path_TAR="$TAR" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_TAR="$TAR" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_TAR="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+TAR="$ac_cv_path_TAR"
+if test -n "$TAR"; then
+  echo "$ac_t""$TAR" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$TAR" && break
+done
+
 # Extract the first word of "gzip", so it can be a program name with args.
 set dummy gzip; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1257: checking for $ac_word" >&5
+echo "configure:1334: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GZIP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1288,7 +1365,7 @@
 # Extract the first word of "gunzip", so it can be a program name with args.
 set dummy gunzip; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1292: checking for $ac_word" >&5
+echo "configure:1369: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GUNZIP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1325,7 +1402,7 @@
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1329: checking for $ac_word" >&5
+echo "configure:1406: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_AWK'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1365,7 +1442,7 @@
 # Extract the first word of "perl", so it can be a program name with args.
 set dummy perl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1369: checking for $ac_word" >&5
+echo "configure:1446: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1403,7 +1480,7 @@
 else
   
   echo $ac_n "checking if '$PERL' will run Perl scripts""... $ac_c" 1>&6
-echo "configure:1407: checking if '$PERL' will run Perl scripts" >&5
+echo "configure:1484: checking if '$PERL' will run Perl scripts" >&5
   rm -f conftest.BZ
   cat > conftest.BZ <<EOF
 #!$PERL
@@ -1421,7 +1498,7 @@
   rm -f conftest.BZ
 
 fi
-PERL_HEAD="../config/$PERL_HEAD"
+PERL_HEAD="$cwd/config/$PERL_HEAD"
 
 
 # Determine the correct ps command to use to find out about process
@@ -1429,7 +1506,7 @@
 # Extract the first word of "ps", so it can be a program name with args.
 set dummy ps; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1433: checking for $ac_word" >&5
+echo "configure:1510: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_PS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1466,7 +1543,7 @@
     PS_SELF="$PS -p PID -o \'rss vsz pmem time user pid comm\'"
     ;;
   *-linux-*)
-    PS_SELF="$PS auxp PID"
+    PS_SELF="$PS up PID"
     ;;
   *)
     PS_SELF="$PS aux | grep PID"
@@ -1475,19 +1552,19 @@
     echo "configure: warning: *** to get process information for your host," 1>&2
     echo "configure: warning: *** please email the command the the output from" 1>&2
     echo "configure: warning: *** ./config/config.guess to" 1>&2
-    echo "configure: warning: *** orca-developers at onelist.com" 1>&2
+    echo "configure: warning: *** orca-developers at yahoogroups.com" 1>&2
     ;;
 esac
 if test "$PS_SELF"; then
   echo $ac_n "checking for ps command""... $ac_c" 1>&6
-echo "configure:1484: checking for ps command" >&5
+echo "configure:1561: checking for ps command" >&5
   echo "$ac_t""$PS_SELF" 1>&6
   
 fi
 # Extract the first word of "se", so it can be a program name with args.
 set dummy se; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1491: checking for $ac_word" >&5
+echo "configure:1568: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_SE'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1522,7 +1599,7 @@
 # Extract the first word of "uname", so it can be a program name with args.
 set dummy uname; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1526: checking for $ac_word" >&5
+echo "configure:1603: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_UNAME'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1558,7 +1635,7 @@
 # Extract the first word of "uncompress", so it can be a program name with args.
 set dummy uncompress; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1562: checking for $ac_word" >&5
+echo "configure:1639: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_UNCOMPRESS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1631,7 +1708,7 @@
 
 # This command can be used to add --enable-shared to the configure
 # options for RRDtool if it is not already declared.
-# expr "$CONFIGURE_COMMAND_LINE" : "--enable-shared" >/dev/null 2>&1 || CONFIGURE_COMMAND_LINE="$CONFIGURE_COMMAND_LINE --enable-shared"
+# expr "$ORCA_CONFIGURE_COMMAND_LINE" : "--enable-shared" >/dev/null 2>&1 || ORCA_CONFIGURE_COMMAND_LINE="$ORCA_CONFIGURE_COMMAND_LINE --enable-shared"
 
 
 
@@ -1640,9 +1717,9 @@
 
 
 
-  echo $ac_n "checking if Perl module Data::Dumper version 2.101 is installed""... $ac_c" 1>&6
-echo "configure:1645: checking if Perl module Data::Dumper version 2.101 is installed" >&5
-  if $PERL ./config/check_for_perl_mod Data::Dumper 2.101; then
+  echo $ac_n "checking if Perl module Data::Dumper version $DATA_DUMPER_VER is installed""... $ac_c" 1>&6
+echo "configure:1722: checking if Perl module Data::Dumper version $DATA_DUMPER_VER is installed" >&5
+  if $PERL ./config/check_for_perl_mod Data::Dumper $DATA_DUMPER_VER; then
     borp_cv_perl_data_dumper=yes
     
   else
@@ -1651,6 +1728,7 @@
   fi
   echo "$ac_t""$borp_cv_perl_data_dumper" 1>&6
 
+test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_data_dumper=no
 if test "$borp_cv_perl_data_dumper" = no; then
   MAKE_DATA_DUMPER=make_data_dumper
   TEST_DATA_DUMPER=test_data_dumper
@@ -1665,9 +1743,35 @@
 
 
 
-  echo $ac_n "checking if Perl module Digest::MD5 version 2.09 is installed""... $ac_c" 1>&6
-echo "configure:1670: checking if Perl module Digest::MD5 version 2.09 is installed" >&5
-  if $PERL ./config/check_for_perl_mod Digest::MD5 2.09; then
+  echo $ac_n "checking if Perl module Date::Parse version $DATE_PARSE_VER is installed""... $ac_c" 1>&6
+echo "configure:1748: checking if Perl module Date::Parse version $DATE_PARSE_VER is installed" >&5
+  if $PERL ./config/check_for_perl_mod Date::Parse $DATE_PARSE_VER; then
+    borp_cv_perl_date_parse=yes
+    
+  else
+    borp_cv_perl_date_parse=no
+    
+  fi
+  echo "$ac_t""$borp_cv_perl_date_parse" 1>&6
+
+test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_date_parse=no
+if test "$borp_cv_perl_date_parse" = no; then
+  MAKE_DATE_PARSE=make_date_parse
+  TEST_DATE_PARSE=test_date_parse
+  INSTALL_PERL_DATE_PARSE=install_perl_date_parse
+  CLEAN_DATE_PARSE=clean_date_parse
+  DISTCLEAN_DATE_PARSE=distclean_date_parse
+fi
+
+
+
+
+
+
+
+  echo $ac_n "checking if Perl module Digest::MD5 version $DIGEST_MD5_VER is installed""... $ac_c" 1>&6
+echo "configure:1774: checking if Perl module Digest::MD5 version $DIGEST_MD5_VER is installed" >&5
+  if $PERL ./config/check_for_perl_mod Digest::MD5 $DIGEST_MD5_VER; then
     borp_cv_perl_digest_md5=yes
     
   else
@@ -1676,6 +1780,7 @@
   fi
   echo "$ac_t""$borp_cv_perl_digest_md5" 1>&6
 
+test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_digest_md5=no
 if test "$borp_cv_perl_digest_md5" = no; then
   MAKE_DIGEST_MD5=make_digest_md5
   TEST_DIGEST_MD5=test_digest_md5
@@ -1690,9 +1795,9 @@
 
 
 
-  echo $ac_n "checking if Perl module Math::Interpolate version 1.05 is installed""... $ac_c" 1>&6
-echo "configure:1695: checking if Perl module Math::Interpolate version 1.05 is installed" >&5
-  if $PERL ./config/check_for_perl_mod Math::Interpolate 1.05; then
+  echo $ac_n "checking if Perl module Math::Interpolate version $MATH_INTERPOLATE_VER is installed""... $ac_c" 1>&6
+echo "configure:1800: checking if Perl module Math::Interpolate version $MATH_INTERPOLATE_VER is installed" >&5
+  if $PERL ./config/check_for_perl_mod Math::Interpolate $MATH_INTERPOLATE_VER; then
     borp_cv_perl_math_interpolate=yes
     
   else
@@ -1701,6 +1806,7 @@
   fi
   echo "$ac_t""$borp_cv_perl_math_interpolate" 1>&6
 
+test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_math_interpolate=no
 if test "$borp_cv_perl_math_interpolate" = no; then
   MAKE_MATH_INTERPOLATE=make_math_interpolate
   TEST_MATH_INTERPOLATE=test_math_interpolate
@@ -1715,18 +1821,19 @@
 
 
 
-  echo $ac_n "checking if Perl module RRDs version 1.000131 is installed""... $ac_c" 1>&6
-echo "configure:1720: checking if Perl module RRDs version 1.000131 is installed" >&5
-  if $PERL ./config/check_for_perl_mod RRDs 1.000131; then
-    borp_cv_perl_rdds=yes
+  echo $ac_n "checking if Perl module RRDs version $RRDTOOL_VER is installed""... $ac_c" 1>&6
+echo "configure:1826: checking if Perl module RRDs version $RRDTOOL_VER is installed" >&5
+  if $PERL ./config/check_for_perl_mod RRDs $RRDTOOL_VER; then
+    borp_cv_perl_rrds=yes
     
   else
-    borp_cv_perl_rdds=no
+    borp_cv_perl_rrds=no
     
   fi
-  echo "$ac_t""$borp_cv_perl_rdds" 1>&6
+  echo "$ac_t""$borp_cv_perl_rrds" 1>&6
 
-if test "$borp_cv_perl_rdds" = no; then
+test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_rrds=no
+if test "$borp_cv_perl_rrds" = no; then
   MAKE_RRDTOOL=make_rrdtool
   TEST_RRDTOOL=test_rrdtool
   INSTALL_PERL_RRDTOOL=install_perl_rrdtool
@@ -1740,9 +1847,9 @@
 
 
 
-  echo $ac_n "checking if Perl module Storable version 0.609 is installed""... $ac_c" 1>&6
-echo "configure:1745: checking if Perl module Storable version 0.609 is installed" >&5
-  if $PERL ./config/check_for_perl_mod Storable 0.609; then
+  echo $ac_n "checking if Perl module Storable version $STORABLE_VER is installed""... $ac_c" 1>&6
+echo "configure:1852: checking if Perl module Storable version $STORABLE_VER is installed" >&5
+  if $PERL ./config/check_for_perl_mod Storable $STORABLE_VER; then
     borp_cv_perl_storable=yes
     
   else
@@ -1751,6 +1858,7 @@
   fi
   echo "$ac_t""$borp_cv_perl_storable" 1>&6
 
+test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_storable=no
 if test "$borp_cv_perl_storable" = no; then
   MAKE_STORABLE=make_storable
   TEST_STORABLE=test_storable
@@ -1764,10 +1872,40 @@
 
 
 
+
+  echo $ac_n "checking if Perl module Time::HiRes version $TIME_HIRES_VER is installed""... $ac_c" 1>&6
+echo "configure:1878: checking if Perl module Time::HiRes version $TIME_HIRES_VER is installed" >&5
+  if $PERL ./config/check_for_perl_mod Time::HiRes $TIME_HIRES_VER; then
+    borp_cv_perl_time_hires=yes
+    
+  else
+    borp_cv_perl_time_hires=no
+    
+  fi
+  echo "$ac_t""$borp_cv_perl_time_hires" 1>&6
+
+test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_time_hires=no
+if test "$borp_cv_perl_time_hires" = no; then
+  MAKE_TIME_HIRES=make_time_hires
+  TEST_TIME_HIRES=test_time_hires
+  INSTALL_PERL_TIME_HIRES=install_perl_time_hires
+  CLEAN_TIME_HIRES=clean_time_hires
+  DISTCLEAN_TIME_HIRES=distclean_time_hires
+  PERL_USE_TIME_HIRES=
+else
+  PERL_USE_TIME_HIRES="use Time::HiRes qw(time);"
+fi
+
+
+
+
+
+
+
 # Define the INSTALL and MKDIR variables to point to the scripts in
 # the config directory.
-INSTALL="../config/install-sh -c"
-MKDIR="../config/mkinstalldirs"
+INSTALL="$config_dir/install-sh -c"
+MKDIR="$config_dir/mkinstalldirs"
 
 
 
@@ -1897,15 +2035,26 @@
 
 ac_given_srcdir=$srcdir
 
-trap 'rm -fr `echo "config/PerlHead1
+trap 'rm -fr `echo "Makefile
+	  config/PerlHead1
 	  config/PerlHead2
 	  lib/Makefile
 	  packages/Makefile
-	  src/orca.pl
 	  src/Makefile
+	  src/orca.pl
 	  $ORCALLATOR_OUTPUT
 	  docs/Makefile
-	  Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+	  contrib/Makefile
+	  contrib/rotate_orca_graphs/Makefile
+	  contrib/rotate_orca_graphs/rotate_orca_graphs.sh
+	  contrib/orcaservices/Makefile
+	  contrib/orcaservices/orcaservices.cfg
+	  contrib/orcaservices/orcaservices.pl
+	  contrib/orcaservices/orcaservices_running.pl
+	  contrib/orcaservices/restart_orcaservices.sh
+	  contrib/orcaservices/start_orcaservices.sh
+	  contrib/orcaservices/stop_orcaservices.sh
+	  contrib/orcaservices/S99orcaservices.sh" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
 EOF
 cat >> $CONFIG_STATUS <<EOF
 
@@ -1952,13 +2101,24 @@
 s%@build_cpu@%$build_cpu%g
 s%@build_vendor@%$build_vendor%g
 s%@build_os@%$build_os%g
-s%@CONFIGURE_COMMAND_LINE@%$CONFIGURE_COMMAND_LINE%g
+s%@ORCA_CONFIGURE_COMMAND_LINE@%$ORCA_CONFIGURE_COMMAND_LINE%g
+s%@RRD_CONFIGURE_COMMAND_LINE@%$RRD_CONFIGURE_COMMAND_LINE%g
 s%@COMPRESS_ZLIB_DIR@%$COMPRESS_ZLIB_DIR%g
 s%@DATA_DUMPER_DIR@%$DATA_DUMPER_DIR%g
+s%@DATE_PARSE_DIR@%$DATE_PARSE_DIR%g
 s%@DIGEST_MD5_DIR@%$DIGEST_MD5_DIR%g
 s%@MATH_INTERPOLATE_DIR@%$MATH_INTERPOLATE_DIR%g
 s%@RRDTOOL_DIR@%$RRDTOOL_DIR%g
 s%@STORABLE_DIR@%$STORABLE_DIR%g
+s%@TIME_HIRES_DIR@%$TIME_HIRES_DIR%g
+s%@COMPRESS_ZLIB_VER@%$COMPRESS_ZLIB_VER%g
+s%@DATA_DUMPER_VER@%$DATA_DUMPER_VER%g
+s%@DATE_PARSE_VER@%$DATE_PARSE_VER%g
+s%@DIGEST_MD5_VER@%$DIGEST_MD5_VER%g
+s%@MATH_INTERPOLATE_VER@%$MATH_INTERPOLATE_VER%g
+s%@RRDTOOL_VER@%$RRDTOOL_VER%g
+s%@STORABLE_VER@%$STORABLE_VER%g
+s%@TIME_HIRES_VER@%$TIME_HIRES_VER%g
 s%@RRD_DIR@%$RRD_DIR%g
 s%@HTML_DIR@%$HTML_DIR%g
 s%@ORCALLATOR_DIR@%$ORCALLATOR_DIR%g
@@ -1971,6 +2131,7 @@
 s%@COMPRESS@%$COMPRESS%g
 s%@CUT@%$CUT%g
 s%@EXPR@%$EXPR%g
+s%@TAR@%$TAR%g
 s%@GZIP@%$GZIP%g
 s%@GUNZIP@%$GUNZIP%g
 s%@AWK@%$AWK%g
@@ -1995,6 +2156,11 @@
 s%@INSTALL_PERL_DATA_DUMPER@%$INSTALL_PERL_DATA_DUMPER%g
 s%@CLEAN_DATA_DUMPER@%$CLEAN_DATA_DUMPER%g
 s%@DISTCLEAN_DATA_DUMPER@%$DISTCLEAN_DATA_DUMPER%g
+s%@MAKE_DATE_PARSE@%$MAKE_DATE_PARSE%g
+s%@TEST_DATE_PARSE@%$TEST_DATE_PARSE%g
+s%@INSTALL_PERL_DATE_PARSE@%$INSTALL_PERL_DATE_PARSE%g
+s%@CLEAN_DATE_PARSE@%$CLEAN_DATE_PARSE%g
+s%@DISTCLEAN_DATE_PARSE@%$DISTCLEAN_DATE_PARSE%g
 s%@MAKE_DIGEST_MD5@%$MAKE_DIGEST_MD5%g
 s%@TEST_DIGEST_MD5@%$TEST_DIGEST_MD5%g
 s%@INSTALL_PERL_DIGEST_MD5@%$INSTALL_PERL_DIGEST_MD5%g
@@ -2015,6 +2181,12 @@
 s%@INSTALL_PERL_STORABLE@%$INSTALL_PERL_STORABLE%g
 s%@CLEAN_STORABLE@%$CLEAN_STORABLE%g
 s%@DISTCLEAN_STORABLE@%$DISTCLEAN_STORABLE%g
+s%@MAKE_TIME_HIRES@%$MAKE_TIME_HIRES%g
+s%@TEST_TIME_HIRES@%$TEST_TIME_HIRES%g
+s%@INSTALL_PERL_TIME_HIRES@%$INSTALL_PERL_TIME_HIRES%g
+s%@CLEAN_TIME_HIRES@%$CLEAN_TIME_HIRES%g
+s%@DISTCLEAN_TIME_HIRES@%$DISTCLEAN_TIME_HIRES%g
+s%@PERL_USE_TIME_HIRES@%$PERL_USE_TIME_HIRES%g
 s%@INSTALL@%$INSTALL%g
 s%@MKDIR@%$MKDIR%g
 
@@ -2058,15 +2230,26 @@
 
 cat >> $CONFIG_STATUS <<EOF
 
-CONFIG_FILES=\${CONFIG_FILES-"config/PerlHead1
+CONFIG_FILES=\${CONFIG_FILES-"Makefile
+	  config/PerlHead1
 	  config/PerlHead2
 	  lib/Makefile
 	  packages/Makefile
-	  src/orca.pl
 	  src/Makefile
+	  src/orca.pl
 	  $ORCALLATOR_OUTPUT
 	  docs/Makefile
-	  Makefile"}
+	  contrib/Makefile
+	  contrib/rotate_orca_graphs/Makefile
+	  contrib/rotate_orca_graphs/rotate_orca_graphs.sh
+	  contrib/orcaservices/Makefile
+	  contrib/orcaservices/orcaservices.cfg
+	  contrib/orcaservices/orcaservices.pl
+	  contrib/orcaservices/orcaservices_running.pl
+	  contrib/orcaservices/restart_orcaservices.sh
+	  contrib/orcaservices/start_orcaservices.sh
+	  contrib/orcaservices/stop_orcaservices.sh
+	  contrib/orcaservices/S99orcaservices.sh"}
 EOF
 cat >> $CONFIG_STATUS <<\EOF
 for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
@@ -2135,13 +2318,14 @@
 
 # Build the RRDtool library if it is needed.
 if test "$borp_cv_perl_rdds" = no; then
-  command="(cd packages/$RRDTOOL_DIR; ./configure $CONFIGURE_COMMAND_LINE --cache-file=../../config.cache)"
+  command="(cd packages/$RRDTOOL_DIR; ./configure $RRD_CONFIGURE_COMMAND_LINE)"
   echo ""
   echo "Running configure in packages/$RRDTOOL_DIR to create RRDtool and RRDs.pm."
   echo ""
   echo $command
   echo ""
   eval $command
+  sleep 1
 fi
 
 if test -z "$WEB_LOG"; then

Modified: trunk/orca/Makefile.in
==============================================================================
--- trunk/orca/Makefile.in	(original)
+++ trunk/orca/Makefile.in	Sat Jul 13 21:25:41 2002
@@ -1,7 +1,8 @@
 @SET_MAKE@
 
-SUBDIRS 	= packages lib src @ORCALLATOR_SUBDIR@ docs
-PREFIX		= @prefix@
+SUBDIRS 	= packages lib src @ORCALLATOR_SUBDIR@ docs contrib
+prefix		= @prefix@
+MKDIR		= @MKDIR@
 MAKE_RRDTOOL	= @MAKE_RRDTOOL@
 ORCALLATOR_DIR	= @ORCALLATOR_DIR@
 RRD_DIR		= @RRD_DIR@
@@ -19,13 +20,16 @@
 	cd src && $(MAKE) upgrade_installation
 
 install: $(INSTALL_RRDTOOL)
-	./config/mkinstalldirs $(ORCALLATOR_DIR)
-	./config/mkinstalldirs $(RRD_DIR)/orcallator
+	$(MKDIR) $(ORCALLATOR_DIR)
+	$(MKDIR) $(RRD_DIR)/orcallator
 	@for dir in $(SUBDIRS); do			\
 		echo "cd $$dir && $(MAKE) install";	\
 		(cd $$dir && $(MAKE) install);		\
 	done
 
+install_contrib:
+	cd contrib && $(MAKE) install_contrib
+
 orcallator_run_at_boot:
 	cd orcallator && $(MAKE) orcallator_run_at_boot
 

Modified: trunk/orca/configure.in
==============================================================================
--- trunk/orca/configure.in	(original)
+++ trunk/orca/configure.in	Sat Jul 13 21:25:41 2002
@@ -6,25 +6,62 @@
 AC_CANONICAL_SYSTEM
 
 # Remember the command line arguments to configure for use when
-# configure is run again.
-CONFIGURE_COMMAND_LINE=${1+"$@"}
-AC_SUBST(CONFIGURE_COMMAND_LINE)
+# configure is run again.  Also create the command line options for
+# RRD configure.
+ORCA_CONFIGURE_COMMAND_LINE=${1+"$@"}
+RRD_CONFIGURE_COMMAND_LINE="$ORCA_CONFIGURE_COMMAND_LINE --cache-file=../../config.cache"
+AC_SUBST(ORCA_CONFIGURE_COMMAND_LINE)
+AC_SUBST(RRD_CONFIGURE_COMMAND_LINE)
+
+# Set this to yes to have configure always build all of the required
+# Perl Orca modules.  This is used to test the build more than
+# anything else.
+ALWAYS_BUILD_PERL_MODULES=yes
+ALWAYS_BUILD_PERL_MODULES=
 
 # Define the directories containing packages that Orca makes use of here.
 # The directory name packages where these packages are distributed with
 # Orca gets added where necessary.
 COMPRESS_ZLIB_DIR=Compress-Zlib-1.05
+COMPRESS_ZLIB_VER=1.05
 DATA_DUMPER_DIR=Data-Dumper-2.101
-DIGEST_MD5_DIR=Digest-MD5-2.09
+DATA_DUMPER_VER=2.101
+DATE_PARSE_DIR=TimeDate-1.10
+DATE_PARSE_VER=2.20
+DIGEST_MD5_DIR=Digest-MD5-2.13
+DIGEST_MD5_VER=2.13
 MATH_INTERPOLATE_DIR=Math-Interpolate-1.05
-RRDTOOL_DIR=rrdtool-1.0.13
-STORABLE_DIR=Storable-0.6.9
+MATH_INTERPOLATE_VER=1.05
+RRDTOOL_DIR=rrdtool-1.0.33
+RRDTOOL_VER=1.000331
+STORABLE_DIR=Storable-1.0.11
+STORABLE_VER=1.011
+TIME_HIRES_DIR=Time-HiRes-01.20
+TIME_HIRES_VER=1.20
+
 AC_SUBST(COMPRESS_ZLIB_DIR)
 AC_SUBST(DATA_DUMPER_DIR)
+AC_SUBST(DATE_PARSE_DIR)
 AC_SUBST(DIGEST_MD5_DIR)
 AC_SUBST(MATH_INTERPOLATE_DIR)
 AC_SUBST(RRDTOOL_DIR)
 AC_SUBST(STORABLE_DIR)
+AC_SUBST(TIME_HIRES_DIR)
+AC_SUBST(COMPRESS_ZLIB_VER)
+AC_SUBST(DATA_DUMPER_VER)
+AC_SUBST(DATE_PARSE_VER)
+AC_SUBST(DIGEST_MD5_VER)
+AC_SUBST(MATH_INTERPOLATE_VER)
+AC_SUBST(RRDTOOL_VER)
+AC_SUBST(STORABLE_VER)
+AC_SUBST(TIME_HIRES_VER)
+
+# Get the current working directory and the config directory.
+cwd=`pwd`
+config_dir="$cwd/config"
+if test ! -d $config_dir; then
+  AC_MSG_ERROR([*** Cannot find config directory.])
+fi
 
 # Minimum Autoconf version required.
 AC_PREREQ(2.13)
@@ -155,6 +192,7 @@
 AC_PATH_PROG(COMPRESS, compress)
 AC_PATH_PROG(CUT, cut, cut)
 AC_PATH_PROG(EXPR, expr, expr)
+AC_PATH_PROGS(TAR,gtar gnutar tar)
 AC_PATH_PROG(GZIP, gzip)
 AC_PATH_PROG(GUNZIP, gunzip)
 AC_PATH_PROGS(AWK, mawk gawk nawk awk)
@@ -166,7 +204,7 @@
 else
   BORP_PERL_RUN($PERL, PERL_HEAD=PerlHead1, PERL_HEAD=PerlHead2)
 fi
-PERL_HEAD="../config/$PERL_HEAD"
+PERL_HEAD="$cwd/config/$PERL_HEAD"
 AC_SUBST(PERL_HEAD)
 
 # Determine the correct ps command to use to find out about process
@@ -177,7 +215,7 @@
     PS_SELF="$PS -p PID -o \'rss vsz pmem time user pid comm\'"
     ;;
   *-linux-*)
-    PS_SELF="$PS auxp PID"
+    PS_SELF="$PS up PID"
     ;;
   *)
     PS_SELF="$PS aux | grep PID"
@@ -186,7 +224,7 @@
     AC_MSG_WARN([*** to get process information for your host,])
     AC_MSG_WARN([*** please email the command the the output from])
     AC_MSG_WARN([*** ./config/config.guess to])
-    AC_MSG_WARN([*** orca-developers at onelist.com])
+    AC_MSG_WARN([*** orca-developers at yahoogroups.com])
     ;;
 esac
 if test "$PS_SELF"; then
@@ -238,9 +276,10 @@
 
 # This command can be used to add --enable-shared to the configure
 # options for RRDtool if it is not already declared.
-# expr "$CONFIGURE_COMMAND_LINE" : "--enable-shared" >/dev/null 2>&1 || CONFIGURE_COMMAND_LINE="$CONFIGURE_COMMAND_LINE --enable-shared"
+# expr "$ORCA_CONFIGURE_COMMAND_LINE" : "--enable-shared" >/dev/null 2>&1 || ORCA_CONFIGURE_COMMAND_LINE="$ORCA_CONFIGURE_COMMAND_LINE --enable-shared"
 
-dnl BORP_PERL_MODULE(borp_cv_perl_compress_zlib, $PERL, Compress::Zlib, 1.05)
+dnl BORP_PERL_MODULE(borp_cv_perl_compress_zlib, $PERL, Compress::Zlib, $COMPRESS_ZLIB_VER)
+dnl test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_compress_zlib=no
 dnl if test "$borp_cv_perl_compress_zlib" = no; then
 dnl   MAKE_COMPRESS_ZLIB=make_compress_zlib
 dnl   TEST_COMPRESS_ZLIB=test_compress_zlib
@@ -254,7 +293,8 @@
 AC_SUBST(CLEAN_COMPRESS_ZLIB)
 AC_SUBST(DISTCLEAN_COMPRESS_ZLIB)
 
-BORP_PERL_MODULE(borp_cv_perl_data_dumper, $PERL, Data::Dumper, 2.101)
+BORP_PERL_MODULE(borp_cv_perl_data_dumper, $PERL, Data::Dumper, $DATA_DUMPER_VER)
+test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_data_dumper=no
 if test "$borp_cv_perl_data_dumper" = no; then
   MAKE_DATA_DUMPER=make_data_dumper
   TEST_DATA_DUMPER=test_data_dumper
@@ -268,7 +308,23 @@
 AC_SUBST(CLEAN_DATA_DUMPER)
 AC_SUBST(DISTCLEAN_DATA_DUMPER)
 
-BORP_PERL_MODULE(borp_cv_perl_digest_md5, $PERL, Digest::MD5, 2.09)
+BORP_PERL_MODULE(borp_cv_perl_date_parse, $PERL, Date::Parse, $DATE_PARSE_VER)
+test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_date_parse=no
+if test "$borp_cv_perl_date_parse" = no; then
+  MAKE_DATE_PARSE=make_date_parse
+  TEST_DATE_PARSE=test_date_parse
+  INSTALL_PERL_DATE_PARSE=install_perl_date_parse
+  CLEAN_DATE_PARSE=clean_date_parse
+  DISTCLEAN_DATE_PARSE=distclean_date_parse
+fi
+AC_SUBST(MAKE_DATE_PARSE)
+AC_SUBST(TEST_DATE_PARSE)
+AC_SUBST(INSTALL_PERL_DATE_PARSE)
+AC_SUBST(CLEAN_DATE_PARSE)
+AC_SUBST(DISTCLEAN_DATE_PARSE)
+
+BORP_PERL_MODULE(borp_cv_perl_digest_md5, $PERL, Digest::MD5, $DIGEST_MD5_VER)
+test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_digest_md5=no
 if test "$borp_cv_perl_digest_md5" = no; then
   MAKE_DIGEST_MD5=make_digest_md5
   TEST_DIGEST_MD5=test_digest_md5
@@ -282,7 +338,8 @@
 AC_SUBST(CLEAN_DIGEST_MD5)
 AC_SUBST(DISTCLEAN_DIGEST_MD5)
 
-BORP_PERL_MODULE(borp_cv_perl_math_interpolate, $PERL, Math::Interpolate, 1.05)
+BORP_PERL_MODULE(borp_cv_perl_math_interpolate, $PERL, Math::Interpolate, $MATH_INTERPOLATE_VER)
+test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_math_interpolate=no
 if test "$borp_cv_perl_math_interpolate" = no; then
   MAKE_MATH_INTERPOLATE=make_math_interpolate
   TEST_MATH_INTERPOLATE=test_math_interpolate
@@ -296,8 +353,9 @@
 AC_SUBST(CLEAN_MATH_INTERPOLATE)
 AC_SUBST(DISTCLEAN_MATH_INTERPOLATE)
 
-BORP_PERL_MODULE(borp_cv_perl_rdds, $PERL, RRDs, 1.000131)
-if test "$borp_cv_perl_rdds" = no; then
+BORP_PERL_MODULE(borp_cv_perl_rrds, $PERL, RRDs, $RRDTOOL_VER)
+test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_rrds=no
+if test "$borp_cv_perl_rrds" = no; then
   MAKE_RRDTOOL=make_rrdtool
   TEST_RRDTOOL=test_rrdtool
   INSTALL_PERL_RRDTOOL=install_perl_rrdtool
@@ -310,7 +368,8 @@
 AC_SUBST(CLEAN_RRDTOOL)
 AC_SUBST(DISTCLEAN_RRDTOOL)
 
-BORP_PERL_MODULE(borp_cv_perl_storable, $PERL, Storable, 0.609)
+BORP_PERL_MODULE(borp_cv_perl_storable, $PERL, Storable, $STORABLE_VER)
+test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_storable=no
 if test "$borp_cv_perl_storable" = no; then
   MAKE_STORABLE=make_storable
   TEST_STORABLE=test_storable
@@ -324,10 +383,29 @@
 AC_SUBST(CLEAN_STORABLE)
 AC_SUBST(DISTCLEAN_STORABLE)
 
+BORP_PERL_MODULE(borp_cv_perl_time_hires, $PERL, Time::HiRes, $TIME_HIRES_VER)
+test "$ALWAYS_BUILD_PERL_MODULES" && borp_cv_perl_time_hires=no
+if test "$borp_cv_perl_time_hires" = no; then
+  MAKE_TIME_HIRES=make_time_hires
+  TEST_TIME_HIRES=test_time_hires
+  INSTALL_PERL_TIME_HIRES=install_perl_time_hires
+  CLEAN_TIME_HIRES=clean_time_hires
+  DISTCLEAN_TIME_HIRES=distclean_time_hires
+  PERL_USE_TIME_HIRES=
+else
+  PERL_USE_TIME_HIRES="use Time::HiRes qw(time);"
+fi
+AC_SUBST(MAKE_TIME_HIRES)
+AC_SUBST(TEST_TIME_HIRES)
+AC_SUBST(INSTALL_PERL_TIME_HIRES)
+AC_SUBST(CLEAN_TIME_HIRES)
+AC_SUBST(DISTCLEAN_TIME_HIRES)
+AC_SUBST(PERL_USE_TIME_HIRES)
+
 # Define the INSTALL and MKDIR variables to point to the scripts in
 # the config directory.
-INSTALL="../config/install-sh -c"
-MKDIR="../config/mkinstalldirs"
+INSTALL="$config_dir/install-sh -c"
+MKDIR="$config_dir/mkinstalldirs"
 AC_SUBST(INSTALL)
 AC_SUBST(MKDIR)
 
@@ -345,25 +423,37 @@
                      orcallator/Makefile"
 fi
 
-AC_OUTPUT(config/PerlHead1
+AC_OUTPUT(Makefile
+	  config/PerlHead1
 	  config/PerlHead2
 	  lib/Makefile
 	  packages/Makefile
-	  src/orca.pl
 	  src/Makefile
+	  src/orca.pl
 	  $ORCALLATOR_OUTPUT
 	  docs/Makefile
-	  Makefile)
+	  contrib/Makefile
+	  contrib/rotate_orca_graphs/Makefile
+	  contrib/rotate_orca_graphs/rotate_orca_graphs.sh
+	  contrib/orcaservices/Makefile
+	  contrib/orcaservices/orcaservices.cfg
+	  contrib/orcaservices/orcaservices.pl
+	  contrib/orcaservices/orcaservices_running.pl
+	  contrib/orcaservices/restart_orcaservices.sh
+	  contrib/orcaservices/start_orcaservices.sh
+	  contrib/orcaservices/stop_orcaservices.sh
+	  contrib/orcaservices/S99orcaservices.sh)
 
 # Build the RRDtool library if it is needed.
 if test "$borp_cv_perl_rdds" = no; then
-  command="(cd packages/$RRDTOOL_DIR; ./configure $CONFIGURE_COMMAND_LINE --cache-file=../../config.cache)"
+  command="(cd packages/$RRDTOOL_DIR; ./configure $RRD_CONFIGURE_COMMAND_LINE)"
   echo ""
   echo "Running configure in packages/$RRDTOOL_DIR to create RRDtool and RRDs.pm."
   echo ""
   echo $command
   echo ""
   eval $command
+  sleep 1
 fi
 
 if test -z "$WEB_LOG"; then

Modified: trunk/orca/src/Makefile.in
==============================================================================
--- trunk/orca/src/Makefile.in	(original)
+++ trunk/orca/src/Makefile.in	Sat Jul 13 21:25:41 2002
@@ -3,8 +3,8 @@
 prefix		= @prefix@
 exec_prefix	= @exec_prefix@
 bindir		= @bindir@
-MKDIR		= @MKDIR@
 INSTALL		= @INSTALL@
+MKDIR		= @MKDIR@
 PERL_HEAD	= @PERL_HEAD@
 ORCALLATOR_DIR	= @ORCALLATOR_DIR@
 RRD_DIR		= @RRD_DIR@
@@ -42,7 +42,6 @@
 
 Makefile:	Makefile.in
 		cd .. && CONFIG_FILES=src/Makefile ./config.status
-		$(MAKE)
 
 orca.pl:	orca.pl.in
 		cd .. && CONFIG_FILES=src/orca.pl ./config.status

Modified: trunk/orca/src/orca.pl.in
==============================================================================
--- trunk/orca/src/orca.pl.in	(original)
+++ trunk/orca/src/orca.pl.in	Sat Jul 13 21:25:41 2002
@@ -1,6 +1,6 @@
 # Orca: display arbitrary data from files onto web pages using RRDtool.
 #
-# Copyright (C) 1998, 1999 Blair Zajac and Yahoo!, Inc.
+# Copyright (C) 1998-2001 Blair Zajac and Yahoo!, Inc.
 
 use strict;
 require 5.004_01;
@@ -16,15 +16,17 @@
 }
 
 use Carp;
+use Getopt::Long;
+use Cwd;
 
 # Load any modules that have required version numbers here in
 # addition to the loading of the modules in the other Orca
 # modules to keep all the requiste numbers here.
-use Data::Dumper         2.101;
-use Digest::MD5          2.09 qw(md5_base64);
-use Math::IntervalSearch 1.05 qw(interval_search);
-use Storable             0.609;
-use RRDs                 1.000131;
+use Data::Dumper         @DATA_DUMPER_VER@;
+use Digest::MD5          @DIGEST_MD5_VER@;
+use Math::IntervalSearch @MATH_INTERPOLATE_VER@ qw(interval_search);
+use Storable             @STORABLE_VER@;
+use RRDs                 @RRDTOOL_VER@;
 
 # Set behavior of the Data::Dumper module.
 $Data::Dumper::Indent   = 1;
@@ -33,20 +35,28 @@
 
 # Load the required Orca modules.
 use Orca::Constants     qw($ORCA_VERSION
-                           @IMAGE_PLOT_TYPES
+                           IS_WIN32
+                           die_when_called
+                           $INCORRECT_NUMBER_OF_ARGS
+                           $opt_daemon
                            $opt_generate_gifs
+                           $opt_log_filename
+                           $opt_no_html
+                           $opt_no_images
                            $opt_once_only
-                           $opt_rrd_update_only
                            $opt_verbose
-                           $IMAGE_SUFFIX);
+                           @IMAGE_PLOT_TYPES
+                           $IMAGE_SUFFIX
+                           $MAX_PLOT_TYPE_LENGTH);
 use Orca::Config        qw(load_config
-                           %config_options
-                           %config_groups
+                           %config_global
+                           @config_groups
+                           @config_groups_names
                            @config_plots);
-use Orca::OldState      qw($orca_old_state 
-                           load_old_state 
+use Orca::OldState      qw($orca_old_state
+                           load_old_state
                            save_old_state);
-use Orca::Utils         qw(perl_glob unique);
+use Orca::Utils         qw(name_to_fsname perl_glob unique);
 use Orca::SourceFile;
 use Orca::SourceFileIDs qw(@sfile_fids);
 use Orca::HTMLFile;
@@ -54,6 +64,10 @@
 # Note the starting time of the script.
 my $start_time = time;
 
+# Remember the original working directory because it will be needed to
+# remove the locking directory.
+my $start_cwd = cwd;
+
 # Set up a signal handler to force looking for new files.
 my $force_find_files = 0;
 sub handle_hup {
@@ -62,112 +76,193 @@
 $SIG{HUP} = \&handle_hup;
 
 sub Usage {
-  die "usage: $0 [-o] [-r] [-v] config_file\n";
+  print STDERR "$0: @_\n" if @_;
+die << "END";
+usage: $0 [options] configuration_file
+Options:
+  -daemon           Run Orca in daemon mode
+  -gifs             Output GIFs instead of PNGs
+  -logfile filename Output all messages
+  -no-html          Update RRD files and images but not HTML files
+  -no-images        Update RRD files but not image and HTML files
+  -once             Run only once and do not continue to monitor input files
+  -verbose          Verbose; list multiple times for increased verbosity
+Orca understands the first unique command line option, i.e. -d for -daemon.
+END
 }
 
-while (@ARGV and $ARGV[0] =~ /^-\w/) {
-  my $arg = shift;
-  if ($arg eq '-gifs') {
-    $opt_generate_gifs = 1;
-    $IMAGE_SUFFIX      = 'gif';
-  } elsif ($arg eq '-o') {
-    $opt_once_only = 1;
-  } elsif ($arg eq '-r') {
-    $opt_rrd_update_only = 1;
-  } elsif ($arg eq '-v') {
-    ++$opt_verbose;
-  } else {
-    Usage;
-  }
+GetOptions('daemon'     => \$opt_daemon,
+           'gifs'       => \$opt_generate_gifs,
+           'logfile=s'  => \$opt_log_filename,
+           'no-html'    => \$opt_no_html,
+           'no-images'  => \$opt_no_images,
+           'once'       => \$opt_once_only,
+           'verbose+'   => \$opt_verbose) or
+  Usage;
+
+# Currently, Orca can only daemonize itself on Unix platforms.
+if ($opt_daemon and IS_WIN32) {
+  die "$0: cannot daemonize on a Windows platform.\n";
 }
 
-Usage unless @ARGV;
+if ($opt_generate_gifs) {
+  $IMAGE_SUFFIX = 'gif';
+}
 
-# Install signal handlers to clean up.
+# Load the configuration file.
+Usage("no configuration file specified") unless @ARGV == 1;
+my $config_filename = shift;
+unless (-r $config_filename) {
+  die "$0: no configuration file `$config_filename' to read.\n";
+}
+load_config($config_filename);
+
+# Set two variables that are used by the code that ensures that only
+# one Orca process is using a particular configuration file at a
+# particular time.  This is done by using the fact that mkdir() is
+# atomic.  The first variable is the name of the directory to create
+# and the second is a flag used by the Orca clean up code to see if
+# the locking directory should be removed.
+my $locking_directory       = "$config_filename.lock";
+my $rmdir_locking_directory = '';
+
+# Install signal handlers to clean Orca up, including the locking
+# directory.
 $SIG{INT}     = \&catch_signal;
+$SIG{PIPE}    = \&catch_signal;
 $SIG{TERM}    = \&catch_signal;
-$SIG{__DIE__} = \&catch_signal;
+$SIG{__DIE__} = \&catch_die;
+
+# Now try to create the locking directory.
+unless (mkdir($locking_directory, 0755)) {
+  die "$0: cannot create locking directory `$locking_directory': $!\n";
+}
+$rmdir_locking_directory = 1;
+
+# If a log file was specified or if Orca should daemonize itself, then
+# redirect STDOUT to the appropriate file.  If Orca should daemonize
+# itself and no log file was specified, then write to /dev/null.
+# STDERR is dup'ed from STDOUT after any daemonizing since it does a
+# chdir() and the log filename may be relative to the current
+# directory.  This will still keep any failures to the real STDERR
+# until the last possible time.
+if ($opt_daemon and !$opt_log_filename) {
+  $opt_log_filename = '/dev/null';
+}
+if ($opt_log_filename) {
+  open(STDOUT, ">>$opt_log_filename") or
+    die "$0: cannot open `$opt_log_filename' for writing: $!\n";
+}
+
+# If Orca should daemonize itself, then do so now.  Find POSIX::setsid
+# but do not always use it unless it is needed since some systems do
+# not supply POSIX::setsid and Orca should not quit on those systems.
+if ($opt_daemon) {
+  my $expr = 'use POSIX qw(setsid)';
+  local $SIG{__DIE__}  = 'DEFAULT';
+  local $SIG{__WARN__} = \&die_when_called;
+  eval $expr;
+  if ($@) {
+    die "$0: cannot get setsid since eval '$expr' failed: $@\n";
+  }
+  chdir('/')               or die "$0: cannot chdir `/': $!\n";
+  open(STDIN, '/dev/null') or die "$0: cannot read `/dev/null': $!\n";
+  defined(my $pid = fork)  or die "$0: cannot fork: $!\n";
+  exit if $pid;
+  POSIX::setsid()          or die "$0: cannot start a new session: $!\n";
+}
+
+if ($opt_log_filename) {
+  open(STDERR, '>&STDOUT') or
+    die "$0: cannot dup stdout: $!\n";
+}
 
 if ($opt_verbose) {
-  print "Orca version $ORCA_VERSION using RRDs version $RRDs::VERSION.\n";
+  print "Orca version $ORCA_VERSION using RRDs version $RRDs::VERSION at ",
+        scalar localtime, ".\n";
 }
 
-&main(@ARGV);
+# Load the file state information from disk.
+load_old_state($config_global{state_file});
 
-exit 0;
+# Create orca.gif, rrdtool.gif and any other static images for the
+# HTML pages.
+&create_static_images;
 
-# This is the locking directory.
-my $locking_directory;
+# Load in any new data and update necessary plots.
+&watch_data_sources($config_filename);
 
-# This is set to 1 if the locking directory should be removed.
-my $rmdir_locking_directory;
+&clean_up_and_quit(1, "Orca has completed.\n");
 
-sub clean_up_and_quit {
-  # Print some statistics about running.
-  &running_stats;
+exit 0;
 
-  if ($rmdir_locking_directory and
-      $locking_directory and
-      -d $locking_directory) {
-    rmdir($locking_directory) or
-      warn "$0: cannot rmdir `$locking_directory': $!\n";
-  }
-  exit 0;
-}
+# This cleans up any leftover temporary files.  In certain
+# circumstances, such as when Orca receives a SIGPIPE, then assume
+# that STDOUT and STDERR are closed and do not print any messages so
+# that Orca can properly clean up.  If Orca prints when STDOUT and/or
+# STDERR or closed, then it will hang.
+sub clean_up_and_quit {
+  my $can_print = shift;
+  my $message   = shift;
 
-sub catch_signal {
-  my $signal = shift;
-  chomp($signal);
-  $signal =~ s/\.+$//;
-  if ($signal =~ /$0/o) {
-    print STDERR "$signal.\n";
-  } else {
-    print STDERR "$0: caught signal $signal.\n";
-  }
-  clean_up_and_quit;
-}
+  $can_print = 1 unless defined $can_print;
 
-sub main {
-  my $config_filename = shift;
+  if ($rmdir_locking_directory and $locking_directory) {
+    my $ok = 1;
+    if ($opt_daemon) {
+      unless (chdir($start_cwd)) {
+        $ok = 0;
+        if ($can_print) {
+          warn "$0: cannot chdir `$start_cwd': $!\n";
+        }
+      }
+    }
 
-  unless (-r $config_filename) {
-    die "$0: no configuration file `$config_filename' to read.\n";
+    if ($ok and -d $locking_directory) {
+      unless (rmdir($locking_directory)) {
+        if ($can_print) {
+          warn "$0: cannot rmdir `$locking_directory': $!\n";
+        }
+      }
+    }
   }
 
-  # Create a locking directory using the configuration filename.
-  $locking_directory = "$config_filename.lock";
-  unless (mkdir($locking_directory, 0755)) {
-    die "$0: cannot create locking directory `$locking_directory': $!\n";
+  # Print the given message and any running statistics.
+  if ($can_print) {
+    &running_stats;
+    print $message if $message;
   }
-  $rmdir_locking_directory = 1;
-
-  # Load the configuration file.
-  load_config($config_filename) or
-    die "$0: cannot load configuration file.\n";
-
-  # Load the file state information from disk.
-  load_old_state($config_options{state_file});
 
-  # Create orca.gif, rrdtool.gif and any other static images for
-  # the HTML pages.
-  &create_static_images;
+  exit 0;
+}
 
-  # Load in any new data and update necessary plots.
-  &watch_data_sources($config_filename);
+# Catch any die messages.
+sub catch_die {
+  my $message = shift;
+  clean_up_and_quit(1, $message);
+}
 
-  &clean_up_and_quit;
+# Catch any signals.  Treat SIGPIPE specially to instruct Orca to not
+# print any more messages to STDOUT or STDERR, since these file
+# descriptors may have closed if they were attached to a process that
+# exited, unless a log filename is specified, in which case it is ok
+# to print since STDOUT and STDERR were opened to a file.
+sub catch_signal {
+  my $signal    = shift;
+  my $can_print = $signal !~ /PIPE/ || $opt_log_filename;
+  my $message   = "$0: caught signal $signal.\n";
+  clean_up_and_quit($can_print, $message);
 }
 
+# Create the necessary static images files in the HTML directory using
+# the data stored in Orca's DATA section.  The generated files should
+# include orca.gif and rrdtool.gif.  Convert the hexadecimal forms
+# stored in the DATA section to the raw image form on disk.
 sub create_static_images {
-  # Create the necessary images files in the HTML directory unless
-  # Orca was passed the -r flag, which instructs it to only update
-  # the RRD files.  The generated files should include orca.gif and
-  # rrdtool.gif.  Convert the hexadecimal forms stored in the DATA
-  # section to the raw image form on disk.
-  return if $opt_rrd_update_only;
   my $image_filename = '';
   while (<main::DATA>) {
     chomp;
+    next unless $_;
     if ($image_filename) {
       if (/CLOSE/) {
         close(ORCA_WRITE) or
@@ -178,7 +273,7 @@
         print ORCA_WRITE pack('h*', $_);
       }
     } elsif (/OPEN (.*)/) {
-      $image_filename = "$config_options{html_dir}/$1";
+      $image_filename = "$config_global{html_dir}/$1";
       print "Creating $1.\n" if $opt_verbose;
       unless (open(ORCA_WRITE, ">$image_filename")) {
         warn "$0: cannot open `$image_filename' for writing: $!\n";
@@ -203,7 +298,7 @@
 
 sub watch_data_sources {
   unless (@_ == 1) {
-    confess "$0: watch_data_sources: passed wrong number of arguments.\n";
+    confess "$0: watch_data_sources $INCORRECT_NUMBER_OF_ARGS";
   }
   my $config_filename = shift;
 
@@ -217,11 +312,11 @@
   # time interval that the current time is in, where the intervals are
   # defined as the times to have Orca find new source data files.
   my $find_new_files = 1;
-  my $time_interval  = get_time_interval($config_options{find_times});
+  my $time_interval  = get_time_interval($config_global{find_times});
 
   # This hash holds the next time to load the data from all the files
   # in a particular subgroup.
-  my %subgroup_load_time;
+  my @subgroup_load_time;
 
   for (;;) {
     # If Orca is being forced to find new files, then set up the
@@ -229,7 +324,7 @@
     if ($force_find_files) {
       $force_find_files = 0;
       $find_new_files   = 1;
-      $time_interval    = get_time_interval($config_options{find_times});
+      $time_interval    = get_time_interval($config_global{find_times});
     }
 
     my $found_new_files = 0;
@@ -253,15 +348,19 @@
       # Go through all of the subgroups and for each subgroup and all
       # of the files in the subgroup find the next load time in the
       # future.
-      undef %subgroup_load_time;
-      foreach my $group_name (keys %$subgroup_fids_ref) {
-        foreach my $subgroup_name (keys %{$subgroup_fids_ref->{$group_name}}) {
+      undef @subgroup_load_time;
+      for (my $group_index=0;
+           $group_index<@$subgroup_fids_ref;
+           ++$group_index) {
+        my $indexed_subgroup_fids_ref = $subgroup_fids_ref->[$group_index] or
+          next;
+        foreach my $subgroup_name (keys %$indexed_subgroup_fids_ref) {
           my $subgroup_load_time = 1e20;
-          foreach my $fid (@{$subgroup_fids_ref->{$group_name}{$subgroup_name}}) {
+          foreach my $fid (@{$indexed_subgroup_fids_ref->{$subgroup_name}}) {
             my $load_time       = $new_found_files_ref->{$fid}->next_load_time;
             $subgroup_load_time = $load_time if $load_time < $subgroup_load_time;
           }
-          $subgroup_load_time{$group_name}{$subgroup_name} = $subgroup_load_time;
+          $subgroup_load_time[$group_index]{$subgroup_name} = $subgroup_load_time;
         }
       }
     }
@@ -278,11 +377,13 @@
     # is in the future.
     my $sleep_till_time;
     my $need_to_save_state = $found_new_files;
-    foreach my $group_name (sort keys %subgroup_load_time) {
-      foreach my $subgroup_name (sort keys %{$subgroup_load_time{$group_name}}) {
+    for (my $group_index=0; $group_index<@subgroup_load_time; ++$group_index) {
+      my $subgroup_load_time_ref = $subgroup_load_time[$group_index] or
+        next;
+      foreach my $subgroup_name (sort keys %{$subgroup_load_time_ref}) {
         # Skip this subgroup if the load time has not been reached and
         # if no new files were found.
-        my $subgroup_load_time = $subgroup_load_time{$group_name}{$subgroup_name};
+        my $subgroup_load_time = $subgroup_load_time_ref->{$subgroup_name};
         if ($subgroup_load_time > time) {
           $sleep_till_time = $subgroup_load_time unless $sleep_till_time;
           if ($subgroup_load_time < $sleep_till_time) {
@@ -291,9 +392,10 @@
           next unless $found_new_files;
         }
 
+        my $group_name = $config_groups_names[$group_index];
         if ($opt_verbose) {
-          print "Loading new data",
-                $subgroup_name ? " from $subgroup_name" : "", ".\n";
+          print "Loading new data from group $group_name",
+                $subgroup_name ? " for $subgroup_name.\n" : ".\n";
         }
 
         my %this_subgroup_rrds;
@@ -301,21 +403,21 @@
         my $number_new_data_points_since_flush = 0;
         $subgroup_load_time                    = 1e20;
         my $previous_fid;
-        foreach my $fid (@{$subgroup_fids_ref->{$group_name}{$subgroup_name}}) {
+        foreach my $fid (@{$subgroup_fids_ref->[$group_index]{$subgroup_name}}) {
           # Determine if the currently loaded data should be flushed.
           if (defined $previous_fid) {
             local $Orca::Config::a = $fid;
             local $Orca::Config::b = $previous_fid;
-            if (&{$config_groups{$group_name}{filename_compare}} > 1 and
+            if (&{$config_groups[$group_index]{filename_compare}} > 1 and
                 $number_new_data_points_since_flush) {
               if ($opt_verbose) {
-                print "Flushing new data",
-                       $subgroup_name ? " from $subgroup_name" : "", ".\n";
+                print "Flushing new data from group $group_name",
+                       $subgroup_name ? " for $subgroup_name" : "", ".\n";
               }
               foreach my $rrd (sort values %this_subgroup_rrds) {
                 $rrd->flush_data;
               }
-              save_old_state($config_options{state_file},
+              save_old_state($config_global{state_file},
                              $new_found_files_ref);
               $number_new_data_points_since_flush = 0;
               $need_to_save_state                 = 0;
@@ -340,7 +442,7 @@
         }
 
         # Update the load time for this subgroup.
-        $subgroup_load_time{$group_name}{$subgroup_name} = $subgroup_load_time;
+        $subgroup_load_time_ref->{$subgroup_name} = $subgroup_load_time;
 
         # Now that the source data files have been read, recalculate
         # the time to sleep to if the load time for this subgroup is
@@ -364,40 +466,40 @@
           print "Flushing new data and updating ", uc($IMAGE_SUFFIX),
                 $subgroup_name ? "s from $subgroup_name" : "s", ".\n";
         }
-        foreach my $rrd (sort {$a->name cmp $b->name}
+        foreach my $rrd (sort {$a->data_expression cmp $b->data_expression}
                               values %this_subgroup_rrds) {
           $rrd->flush_data;
-          next if $opt_rrd_update_only;
+          next if $opt_no_images;
           foreach my $image ($rrd->created_images) {
             next if $image->rrds > 1;
             $image->plot;
           }
         }
-        save_old_state($config_options{state_file}, $new_found_files_ref);
+        save_old_state($config_global{state_file}, $new_found_files_ref);
         $need_to_save_state = 0;
       }
     }
 
     # Save the state if any new data was loaded or new files were found.
     if ($need_to_save_state) {
-      save_old_state($config_options{state_file}, $new_found_files_ref);
+      save_old_state($config_global{state_file}, $new_found_files_ref);
     }
 
-    # Create the HTML and image files now.
-    unless ($opt_rrd_update_only) {
+    # Create the image files now.
+    unless ($opt_no_images) {
       # Plot the data in each image.
       print "Updating ", uc($IMAGE_SUFFIX), "s.\n" if $opt_verbose;
       foreach my $image (@{$image_files_ref->{list}}) {
         $image->plot;
       }
+    }
 
-      # Make the HTML files.
-      if ($found_new_files) {
-        &create_html_files($new_found_files_ref,
-                           $subgroup_fids_ref,
-                           $image_files_ref);
-        $found_new_files = 0;
-      }
+    # Create the HTML files now.
+    if ($found_new_files and !$opt_no_html) {
+      &create_html_files($new_found_files_ref,
+                         $subgroup_fids_ref,
+                         $image_files_ref);
+      $found_new_files = 0;
     }
 
     # Return now if this loop is being run only once.
@@ -407,7 +509,7 @@
     # does change, then find new files only if the new time interval
     # is not -1, which signifies that the time is before the first
     # find_times.
-    my $new_time_interval = get_time_interval($config_options{find_times});
+    my $new_time_interval = get_time_interval($config_global{find_times});
     if ($time_interval != $new_time_interval) {
       $find_new_files = 1 if $new_time_interval != -1;
       $time_interval  = $new_time_interval;
@@ -434,7 +536,7 @@
 
 # Take a string and capatialize only the first character of the
 # string.
-sub Capatialize {
+sub capatialize {
   my $string = shift;
   substr($string, 0, 1) = uc(substr($string, 0, 1));
   $string;
@@ -474,16 +576,35 @@
       $subgroup_fids_ref,
       $image_files_ref) = @_;
 
-  my $html_dir         = $config_options{html_dir};
+  my $html_dir         = $config_global{html_dir};
   my $index_filename   = "$html_dir/index.html";
 
+  # This variable sets the number of groups to place into a single row.
+  my $table_number_columns = 9;
+  my @table_columns;
+
+  # Depending on the number of different timespan plots to make,
+  # create a set of HTML pages labeled 'All' that contains all of the
+  # different timespan plots.  Only make the 'All' pages if there is
+  # more than one timespan plot, otherwise there is no point in making
+  # it.  This array holds the names of the different HTML pages to
+  # create containing different plots.
+  my @html_page_plot_types = @IMAGE_PLOT_TYPES;
+  my $make_html_all_page;
+  if (@html_page_plot_types > 1) {
+    $make_html_all_page = 1;
+    push(@html_page_plot_types, 'all');
+  } else {
+    $make_html_all_page = 0;
+  }
+
   print "Creating HTML files in `$html_dir/'.\n" if $opt_verbose;
 
   # Create the main HTML index.html file.
   my $index_html = Orca::HTMLFile->new($index_filename,
-                                       $config_options{html_top_title},
-                                       $config_options{html_page_header},
-                                       $config_options{html_page_footer});
+                                       $config_global{html_top_title},
+                                       $config_global{html_page_header},
+                                       $config_global{html_page_footer});
   unless ($index_html) {
     warn "$0: warning: cannot create Orca::HTMLFile object: $@.\n";
     return;
@@ -498,51 +619,64 @@
   # images for that subgroup.  Also create an HTML file for different time
   # span images (i.e., daily, monthly, etc).
 
-  # This variable sets the number of groups to place into a single row.
-  my $table_number_columns = 9;
-  my @table_columns;
-
-  # Go through each subgroup.  If there is only one subgroup and that
-  # subgroup does not have a name, then give the subgroup the name Everything.
-  # However, only refer to the name Everything in naming HTML files
-  # and in HTML content.  Use the original subgroup name as a hash key.
-  my $number_subgroups = 0;
-  foreach my $group_name (keys %$subgroup_fids_ref) {
-    $number_subgroups += keys %{$subgroup_fids_ref->{$group_name}};
-  }
-  $index_html->print("<h2>Available Targets</h2>\n\n<table>\n");
-  foreach my $group_name (sort keys %$subgroup_fids_ref) {
-    foreach my $subgroup_name (sort sort_subgroup_names keys
-                               %{$subgroup_fids_ref->{$group_name}}) {
-      my $html_subgroup_name = ($number_subgroups == 1 and !$subgroup_name) ? 'Everything' : $subgroup_name;
+  $index_html->print("<h2>Available Targets</h2>\n\n");
+  for (my $group_index=0; $group_index<@$subgroup_fids_ref; ++$group_index) {
+    my $subgroups_ref = $subgroup_fids_ref->[$group_index] or
+      next;
+    my $group_name = $config_groups_names[$group_index];
+    my @subgroups  = sort sort_subgroup_names keys %$subgroups_ref;
+    next unless @subgroups;
+    if (@config_groups > 1) {
+      $index_html->print("<h3>Group $group_name</h3>\n");
+    }
+    $index_html->print("<table>\n");
+
+    foreach my $subgroup_name (@subgroups) {
+      my $html_subgroup_name;
+      my $html_title_name = @config_groups > 1 ? "Group $group_name" : '';
+      if (@subgroups != 1 or $subgroup_name) {
+        $html_subgroup_name  = $subgroup_name;
+        $html_title_name    .= " $subgroup_name";
+      } else {
+        $html_subgroup_name  = '';
+      }
 
       # Create the HTML code for the main index.html file.
-      my $subgroup_basename = escape_name($html_subgroup_name);
-      my $element = "<table border=2><tr><td><b>$html_subgroup_name</b></td></tr>\n<tr><td>\n";
+      my $subgroup_basename = name_to_fsname("${group_name}_$html_subgroup_name",
+                                             $MAX_PLOT_TYPE_LENGTH+6);
+      my $element = "<table border=2>";
+      if ($html_subgroup_name) {
+        $element .= "<tr><td><b>$html_subgroup_name</b></td></tr>\n";
+      }
+      $element .= "<tr><td>\n";
       foreach my $plot_type (@IMAGE_PLOT_TYPES) {
         $element      .= "<a href=\"$subgroup_basename-$plot_type.html\">";
-        my $Plot_Type  = Capatialize($plot_type);
+        my $Plot_Type  = capatialize($plot_type);
         $element      .= "$Plot_Type</a><br>\n";
       }
-      $element .= "<a href=\"$subgroup_basename-all.html\">All</a></td></tr>\n";
+      if ($make_html_all_page) {
+        $element .= "<a href=\"$subgroup_basename-all.html\">All</a></td></tr>\n";
+      }
       $element .= "</table>\n\n";
 
       push(@table_columns, "<td>$element</td>");
       if (@table_columns == $table_number_columns) {
-        $index_html->print("<tr valign=top>" . join('', @table_columns) . "</tr>\n");
+        $index_html->print("<tr valign=top>" .
+                           join('', @table_columns) .
+                           "</tr>\n");
         @table_columns = ();
       }
 
       # Create the various time span HTML files for this subgroup.
       my @html_files;
-      foreach my $plot_type (@IMAGE_PLOT_TYPES, 'all') {
+      foreach my $plot_type (@html_page_plot_types) {
         my $href      = "$subgroup_basename-$plot_type.html";
         my $filename  = "$html_dir/$href";
-        my $Plot_Type = Capatialize($plot_type);
+        my $Plot_Type = capatialize($plot_type);
         my $fd = Orca::HTMLFile->new($filename,
-                                     "$Plot_Type $html_subgroup_name",
-                                     $config_options{html_page_header},
-                                     $config_options{html_page_footer});
+                                     "$Plot_Type $html_title_name",
+                                     $config_global{html_page_header},
+                                     $config_global{html_page_footer});
         unless ($fd) {
           warn "$0: warning: cannot create Orca::HTMLFile object: $@.\n";
           next;
@@ -568,13 +702,14 @@
       # the HTML files that are being created.  Make sure the images
       # appear in the files in the order listed in the configuration
       # file.
-      my @images = sort {$a->plot_ref->{_index} <=> $b->plot_ref->{_index}}
+      my @images = sort {$a->plot_ref->{index} <=> $b->plot_ref->{index}}
                    grep {$subgroup_name eq $_->subgroup_name} @{$image_files_ref->{list}};
       if (@images > 1) {
         my $href_html = "<hr>";
         for (my $i=0; $i<@images; ++$i) {
           $href_html .= "<a href=\"#$i\">[" .
-                        replace_subgroup_name($images[$i]->plot_ref->{title},'') .
+                        replace_subgroup_name($images[$i]->plot_ref->{title},
+                                              '') .
                         "]</a><spacer size=10>\n";
         }
         foreach my $html_file (@html_files) {
@@ -588,8 +723,7 @@
         my $name       = $image->name;
         my $title      = replace_subgroup_name($image->plot_ref->{title},
                                                $image->subgroup_name);
-        my $href       = "href=\"" . escape_name($name) . ".html\"";
-        my $sub_dir    = $config_groups{$image->group_name}{sub_dir};
+        my $href       = "href=\"" . name_to_fsname($name, 5) . ".html\"";
         my $image_size = $image->image_src_size;
 
         foreach my $html_file (@html_files) {
@@ -599,29 +733,37 @@
 
         # Put the proper images into each HTML file.  The all HTML file is
         # listed last and requires special handling.
-        for (my $j=0; $j<@html_files-1; ++$j) {
-          my $image_filename = "$name-$html_files[$j]{plot_type}.$IMAGE_SUFFIX";
-          $image_filename    = "$subgroup_name/$image_filename" if $sub_dir;
+        for (my $j=0; $j<@html_files-$make_html_all_page; ++$j) {
+          my $image_filename = length($subgroup_name) ?
+                               "$subgroup_name/" :
+                               "";
+          $image_filename .= "$name-$html_files[$j]{plot_type}.$IMAGE_SUFFIX";
           my $html = "<a $href><img src=\"$image_filename\" $image_size " .
                      "alt=\"$html_files[$j]{Plot_Type} $title\"></a>\n";
           $html_files[$j]{fd}->print($html);
-          $html_files[-1]{fd}->print($html);
+          if ($make_html_all_page) {
+            $html_files[-1]{fd}->print($html);
           }
         }
+      }
 
-        foreach my $html_file (@html_files) {
-          $html_file->{fd}->print("<hr>\n");
-        }
+      foreach my $html_file (@html_files) {
+        $html_file->{fd}->print("<hr>\n");
+      }
     }
-  }
 
-  # If there are any remaining subgroups to display, do it now.
-  if (@table_columns) {
-    $index_html->print("<tr valign=top>" .
-                       join('', @table_columns) .
-                       "</tr>\n");
+    # If there are any remaining subgroups to display, do it now.
+    if (@table_columns) {
+      $index_html->print("<tr valign=top>" .
+                         join('', @table_columns) .
+                         "</tr>\n");
+      @table_columns = ();
+    }
+
+    $index_html->print("</table>\n\n");
   }
-  $index_html->print("</table>\n\n\n<br>\n<hr>\n" .
+
+  $index_html->print("<br>\n<hr>\n" .
                      "<h2>Available Data Sets</h2>\n\n");
 
   # Here the different available plots are listed and the HTML files
@@ -640,9 +782,14 @@
   @table_columns        = ();
 
   # Go through all of the configured plots.
-  for (my $i=0; $i<@config_plots; ++$i) {
+  foreach my $config_plot (@config_plots) {
+    my $plot_creates = $config_plot->{creates};
+    next unless @$plot_creates;
+
+    my $group_index = $config_plot->{source_index};
+    my $group_name  = $config_groups_names[$group_index];
 
-    next unless @{$config_plots[$i]{creates}};
+    my $html_title_name = @config_groups > 1 ? " Group $group_name" : '';
 
     # Create an ordered list of images sorted on the legend name for
     # each image.  Remember, each image represented here actually
@@ -654,9 +801,10 @@
     # have the same legend name.
     my %image_legend_no_subgroup;
     my %same_legends_image_list;
-    foreach my $image (@{$config_plots[$i]{creates}}) {
-      my $legend_no_subgroup = replace_subgroup_name($image->plot_ref->{title}, '');
-      $image_legend_no_subgroup{$image} = $legend_no_subgroup; 
+    foreach my $image (@$plot_creates) {
+      my $legend_no_subgroup = replace_subgroup_name($image->plot_ref->{title},
+                                                     '');
+      $image_legend_no_subgroup{$image} = $legend_no_subgroup;
       unless (defined $same_legends_image_list{$legend_no_subgroup}) {
         $same_legends_image_list{$legend_no_subgroup} = [];
       }
@@ -681,7 +829,8 @@
     # through and create the correct HTML files.
     foreach my $image (@images) {
 
-      my $no_subgroup_name   = escape_name($image->no_subgroup_name);
+      my $no_subgroup_name   = name_to_fsname($image->no_subgroup_name,
+                                              $MAX_PLOT_TYPE_LENGTH+6);
       my $legend_no_subgroup = $image_legend_no_subgroup{$image};
 
       # If this is the first time that this legend has been seen in
@@ -692,14 +841,14 @@
         # Now create the HTML files for the time span plots.  Use the
         # legend name to create this list.
         $legend_html_files{$legend_no_subgroup} = [];
-        foreach my $plot_type (@IMAGE_PLOT_TYPES, 'all') {
+        foreach my $plot_type (@html_page_plot_types) {
           my $href      = "$no_subgroup_name-$plot_type.html";
           my $filename  = "$html_dir/$href";
-          my $Plot_Type = Capatialize($plot_type);
+          my $Plot_Type = capatialize($plot_type);
           my $fd = Orca::HTMLFile->new($filename,
-                                       "$Plot_Type $legend_no_subgroup",
-                                       $config_options{html_page_header},
-                                       "<hr>\n$config_options{html_page_footer}");
+                                       "${Plot_Type}${html_title_name} $legend_no_subgroup",
+                                       $config_global{html_page_header},
+                                       "<hr>\n$config_global{html_page_footer}");
           unless ($fd) {
             warn "$0: warning: cannot create Orca::HTMLFile object: $@.\n";
             next;
@@ -740,13 +889,13 @@
         # to these other HTML files.  If the configuration file contains
         # an href for information on this plot, then include the href here.
         my $element = "<td><b>$legend_no_subgroup";
-        if (my $legend_href = $config_plots[$i]{href}) {
+        if (my $legend_href = $config_plot->{href}) {
           $element .= " [<a href=\"$legend_href\">Info</a>]";
         }
         $element .= "</b></td>\n";
-        foreach my $plot_type (@IMAGE_PLOT_TYPES, 'all') {
+        foreach my $plot_type (@html_page_plot_types) {
           $element .= "<td><a href=\"$no_subgroup_name-$plot_type.html\">";
-          $element .= Capatialize($plot_type) . "</a></td>\n";
+          $element .= capatialize($plot_type) . "</a></td>\n";
         }
         push(@table_columns, $element);
         if (@table_columns == $table_number_columns) {
@@ -758,24 +907,26 @@
       # At this point the HTML files for this set of of images have been
       # opened.  Now create the summary HTML file that contains only the
       # images for a particular plot for a particular subgroup.
-      my $with_subgroup_name   = escape_name($image->name);
+      my $with_subgroup_name   = name_to_fsname($image->name, 5);
       my $legend_with_subgroup = replace_subgroup_name($image->plot_ref->{title},
                                                        $image->subgroup_name);
       my $summarize_name       = "$html_dir/$with_subgroup_name.html";
       my $summarize_html       = Orca::HTMLFile->new($summarize_name,
-                                                     $legend_with_subgroup,
-                                                     $config_options{html_page_header},
-                                                     $config_options{html_page_footer});
+                                                     "$html_title_name ZZZ $legend_with_subgroup",
+                                                     $config_global{html_page_header},
+                                                     $config_global{html_page_footer});
       unless ($summarize_html) {
         warn "$0: warning: cannot create Orca::HTMLFile object: $@.\n";
         next;
       }
-      my $sub_dir        = $config_groups{$image->group_name}{sub_dir};
-      my $image_filename = $with_subgroup_name;
-      $image_filename    = $image->subgroup_name . "/$image_filename" if $sub_dir;
-      my $image_size     = $image->image_src_size;
+      my $image_subgroup_name = $image->subgroup_name;
+      my $image_filename      = length($image_subgroup_name) ?
+                                "$image_subgroup_name/" :
+                                "";
+      $image_filename        .= $with_subgroup_name;
+      my $image_size          = $image->image_src_size;
       foreach my $plot_type (@IMAGE_PLOT_TYPES) {
-        my $Plot_Type    = Capatialize($plot_type);
+        my $Plot_Type    = capatialize($plot_type);
         $summarize_html->print("<hr>\n<h2>$Plot_Type $legend_with_subgroup</h2>\n",
                                "<img src=\"$image_filename-$plot_type.$IMAGE_SUFFIX\"",
                                $image_size,
@@ -783,21 +934,25 @@
       }
 
       # Now add the images into each HTML file.
-      my $name     = $image->name;
-      my $subgroup = $image->subgroup_name;
-      my $href     = "href=\"$with_subgroup_name.html\"";
+      my $name          = $image->name;
+      my $subgroup_name = $image->subgroup_name;
+      my $href          = "href=\"$with_subgroup_name.html\"";
 
       my @legend_html_files = @{$legend_html_files{$legend_no_subgroup}};
-      $legend_html_files[-1]{fd}->print("<hr>\n<h2><a ${href} name=\"$subgroup\">$subgroup $legend_no_subgroup</a></h2>\n");
-      for (my $i=0; $i<@legend_html_files-1; ++$i) {
+      if ($make_html_all_page) {
+        $legend_html_files[-1]{fd}->print("<hr>\n<h2><a ${href} name=\"$subgroup_name\">$subgroup_name $legend_no_subgroup</a></h2>\n");
+      }
+      for (my $i=0; $i<@legend_html_files-$make_html_all_page; ++$i) {
         my $Plot_Type      = $legend_html_files[$i]{Plot_Type};
-        my $image_filename = "$name-$legend_html_files[$i]{plot_type}.$IMAGE_SUFFIX";
-        $image_filename    = "$subgroup/$image_filename" if $sub_dir;
+        my $image_filename = length($subgroup_name) ? "$subgroup_name/" : "";
+        $image_filename   .= "$name-$legend_html_files[$i]{plot_type}.$IMAGE_SUFFIX";
         my $html = "<a $href><img src=\"$image_filename\" $image_size " .
-                   "alt=\"$Plot_Type $subgroup $legend_no_subgroup\"></a>\n";
-        $legend_html_files[$i]{fd}->print("<hr>\n<h2><a ${href} name=\"$subgroup\">$Plot_Type $subgroup $legend_no_subgroup</a></h2>\n");
+                   "alt=\"$Plot_Type $subgroup_name $legend_no_subgroup\"></a>\n";
+        $legend_html_files[$i]{fd}->print("<hr>\n<h2><a ${href} name=\"$subgroup_name\">$Plot_Type $subgroup_name $legend_no_subgroup</a></h2>\n");
         $legend_html_files[$i]{fd}->print($html);
-        $legend_html_files[-1]{fd}->print($html);
+        if ($make_html_all_page) {
+          $legend_html_files[-1]{fd}->print($html);
+        }
       }
     }
   }
@@ -808,26 +963,6 @@
   $index_html->print("\n</table>\n\n</font>\n<hr>\n");
 }
 
-# Email the list of people a message.
-sub email_message {
-  my ($people, $subject) = @_;
-
-  return unless $people;
-
-  if (open(SENDMAIL, "|/usr/lib/sendmail -oi -t")) {
-    print SENDMAIL <<"EOF";
-To: $people
-Subject: Orca: $subject
-
-Orca: $subject
-EOF
-  close(SENDMAIL) or
-    warn "$0: warning: sendmail did not close: $!\n";
-  } else {
-    warn "$0: warning: cannot fork for sendmail: $!\n";
-  }
-}
-
 # Replace any %g with the subgroup and any %G's with a capitalized
 # version of the subgroup in the title string with the subgroup name.
 sub replace_subgroup_name {
@@ -843,72 +978,9 @@
   $title;
 }
 
-# Replace special characters from key names, remove redundant characters,
-# and shorten the names so the maximum path name is not exceeded.  If
-# the name is still too long such that the maximum filename path length
-# may be exceeded by appending -daily.html or other names to the name,
-# which is choosen to be 235 characters, then compute a MD5 hash of the
-# name, trim the name the name to 210 characters, which leaves enough space
-# for a 22 byte base64 MD5 digest, plus a separating '-' and plus the prefix,
-# and append the MD5 name.
-sub escape_name {
-  my $name = shift;
-
-  $name =~ s/:/_/g;
-  $name =~ s:/:_per_:g;
-  $name =~ s:\s+:_:g;
-  $name =~ s:%:_pct_:g;
-  $name =~ s:#:_num_:g;
-  $name =~ s:\*:_X_:g;
-
-  # Trim anything containing orcallator, orca.
-  $name =~ s:orcallator:o:g;
-  $name =~ s:orca:o:g;
-
-  # Remove trailing _'s.
-  $name =~ s:_+$::;
-  $name =~ s:_+,:,:g;
-
-  # Replace multiple _'s with one _, except when they follow a , which
-  # happens when the same group and subgroup appear for a new data
-  # source.
-  $name =~ s:,_{2,}:\200:g;
-  $name =~ s:_{2,}:_:g;
-  $name =~ s:\200:,__:g;
-
-  if (length($name) > 235) {
-    my $md5 = md5_base64($name);
-    $name   = substr($name, 0, 210) . "-$md5";
-
-    # Be careful to convert any / characters _, since / is a valid base64
-    # character and should not be used.
-    $name =~ s:/:_:g;
-  }
-
-  $name;
-}
-
-# Replace special characters from key names, remove redundant characters,
-# and shorten the names so the maximum path name is not exceeded.
-sub old_escape_name {
-  my $name = shift;
-  $name =~ s/:/_/g;
-  $name =~ s:/:_per_:g;
-  $name =~ s:\s+:_:g;
-  $name =~ s:%:_percent_:g;
-  $name =~ s:#:_number_:g;
-  $name =~ s:\*:_X_:g;
-  $name =~ s:([_,]){2,}:$1:g;
-
-  # Remove trailing _'s.
-  $name =~ s:_+$::;
-  $name =~ s:_+,:,:g;
-  $name;
-}
-
 sub find_files {
   unless (@_ == 4) {
-    confess "$0: find_files passed wrong number of arguments.\n";
+    confess "$0: find_files $INCORRECT_NUMBER_OF_ARGS";
   }
 
   my ($config_filename,
@@ -917,17 +989,21 @@
       $image_files_ref) = @_;
 
   my %new_found_files;
-  my %subgroup_fids;
+  my @subgroup_fids;
   my $found_new_files = 0;
 
-  foreach my $group_name (sort keys %config_groups) {
+  for (my $group_index=0; $group_index<@config_groups; ++$group_index) {
+    my $group_ref  = $config_groups[$group_index];
+    my $group_name = $config_groups_names[$group_index];
+
     # Find all the readable files matching the regular expression.
     my @fids;
-    foreach my $regexp (@{$config_groups{$group_name}{find_files}}) {
+    foreach my $regexp (@{$group_ref->{find_files}}) {
       push(@fids, perl_glob($regexp));
     }
     unless (@fids) {
-      warn "$0: warning: no files found for `find_files' for `group $group_name' in `$config_filename'.\n";
+      warn "$0: warning: no files found for `find_files' for `group ",
+           "$group_name' in `$config_filename'.\n";
       next;
     }
 
@@ -940,7 +1016,7 @@
       # Find the subgroup that the files belong in.
       my $filename = $sfile_fids[$fid];
       my $subgroup = undef;
-      foreach my $regexp (@{$config_groups{$group_name}{find_files}}) {
+      foreach my $regexp (@{$group_ref->{find_files}}) {
         my @result = ($filename =~ $regexp);
         if (@result) {
           # There there are no ()'s in the regexp, then change (1) to
@@ -965,17 +1041,26 @@
 
     # Create a new list of filenames sorted by subgroup name and
     # inside each subgroup sorted using the filename_compare
-    # configuration option function or by the Perl cmp function.  This
-    # will cause the created plots to appear in subgroup order.  The
-    # compare subroutine expects the input in the $a and $b package
-    # variables.  Since the subroutine was eval'ed in the Orca::Config
-    # package, the sort subroutine needs be in that package.
+    # configuration file function or by the default compare function
+    # that uses cmp to compare filenames.  This will cause the created
+    # plots to appear in subgroup order.  Note that the FIDs are not
+    # being sorted, but the filename the FID references.
+    #
+    # The compare subroutine expects the input in the $a and $b
+    # package variables and since the compare subroutine was eval'ed
+    # in the Orca::Config package it will look for these variables in
+    # Orca::Config.  Also, since sort cannot be passed a reference to
+    # a sorting subroutine stored in a hash (i.e. sort $a{b} @c), use
+    # a temporary variable.  Some versions of Perl will complain that
+    # fc is used only once, so declare the variable and set it in two
+    # separate statements.
     @fids = ();
     {
-      local *Orca::Config::fc = $config_groups{$group_name}{filename_compare};
+      package Orca::Config;
+      local *fc;
+      *fc = $group_ref->{filename_compare};
       foreach my $subgroup (sort keys %tmp_fids_by_subgroup) {
-        push(@fids,
-             sort Orca::Config::fc @{$tmp_fids_by_subgroup{$subgroup}});
+        push(@fids, sort fc @{$tmp_fids_by_subgroup{$subgroup}});
       }
     }
 
@@ -983,8 +1068,8 @@
     # manages that file and the images that are generated from the
     # file.  Delete from the list of filenames those files that have
     # not successfully created Orca::SourceDataFile objects.
-    for (my $i=0; $i<@fids;) {
-      my $fid = $fids[$i];
+    for (my $j=0; $j<@fids;) {
+      my $fid = $fids[$j];
       # Create the object that contains this file.  Take care if the
       # same file is being used in another group.
       unless (defined $new_found_files{$fid}) {
@@ -992,73 +1077,67 @@
           $new_found_files{$fid} = $old_found_files_ref->{$fid};
         } else {
           print "  $sfile_fids[$fid]\n" if $opt_verbose > 2;
-          my $data_file =
-            Orca::SourceFile->new($fid,
-                                  $config_groups{$group_name}{interval},
-                                  $config_options{late_interval},
-                                  $config_groups{$group_name}{reopen},
-                                  $config_groups{$group_name}{column_description},
-                                  $config_groups{$group_name}{date_source},
-                                  $config_groups{$group_name}{date_format},
-                                  $config_options{warn_email});
+          my $data_file = Orca::SourceFile->new($group_index, $fid);
           unless ($data_file) {
             warn "$0: warning: cannot process `$sfile_fids[$fid]'.\n";
-            splice(@fids, $i, 1);
+            splice(@fids, $j, 1);
             next;
           }
           $new_found_files{$fid} = $data_file;
           $found_new_files = 1;
         }
       }
-      ++$i;
+      ++$j;
     }
 
     # Register with each source data file the groups that use it.
     foreach my $fid (@fids) {
-      $new_found_files{$fid}->add_groups($group_name);
+      $new_found_files{$fid}->add_groups($group_index);
     }
 
     # Go through each source data file and register the new plots to
     # create.
     foreach my $fid (@fids) {
       my $subgroup_name = $tmp_subgroup_by_fid{$fid};
-      $new_found_files{$fid}->add_plots($group_name,
+      $new_found_files{$fid}->add_plots($group_index,
                                         $subgroup_name,
                                         $rrd_data_files_ref,
                                         $image_files_ref);
-      unless (defined $subgroup_fids{$group_name}{$subgroup_name}) {
-        $subgroup_fids{$group_name}{$subgroup_name} = [];
+      unless (defined $subgroup_fids[$group_index]{$subgroup_name}) {
+        $subgroup_fids[$group_index]{$subgroup_name} = [];
       }
-      push(@{$subgroup_fids{$group_name}{$subgroup_name}}, $fid);
+      push(@{$subgroup_fids[$group_index]{$subgroup_name}}, $fid);
     }
   }
   my @found_files = keys %new_found_files;
 
-  die "$0: no data source files found.\n" unless @found_files;
+  unless (@found_files) {
+    die "$0: no data files found.  Make sure `find_files' parameter is set ",
+        "properly.\n";
+  }
 
   # Now that all the source data files have been loaded, empty the state
   # object loaded from disk.
   undef %$orca_old_state;
 
-  return ($found_new_files,
-          \%new_found_files,
-          \%subgroup_fids);
+  return ($found_new_files, \%new_found_files, \@subgroup_fids);
 }
 
 # Print a message on the statistics of this running process.
 sub running_stats {
+  return unless $opt_verbose;
+
   my $ps_self = '@PS_SELF@';
   if ($ps_self) {
     $ps_self =~ s/PID/$$/g;
     system($ps_self);
   }
-  if ($opt_verbose) {
-    my $time_span = time - $start_time;
-    my $minutes   = int($time_span/60);
-    my $seconds   = $time_span - 60*$minutes;
 
-    printf "Current running time is %d:%02d minutes.\n", $minutes, $seconds;
-  }
+  my $time_span = time - $start_time;
+  my $minutes   = int($time_span/60);
+  my $seconds   = $time_span - 60*$minutes;
+
+  printf "Current running time is %d:%02d minutes.\n", $minutes, $seconds;
 }
 
 __END__
@@ -1071,7 +1150,7 @@
 
 =head1 SYNOPSIS
 
-  orca [-gifs] [-o] [-r] [-v [-v [-v]]] configuration_file
+  orca [-gifs] [-no-html] [-o] [-r] [-v [-v [-v]]] configuration_file
 
 =head1 DESCRIPTION
 
@@ -1082,8 +1161,8 @@
   * Reads white space separated data files.
   * Watches data files for updates and sleeps between reads.
   * Finds new files at specified times.
-  * Remembers the last modification times for files so they do not have to
-    be reread continuously.
+  * Remembers the last modification times for files so they do not
+    have to be reread continuously.
   * Can plot the same type of data from different files into different
     or the same PNGs.
   * Different plots can be created based on the filename.
@@ -1091,16 +1170,16 @@
   * Create arbitrary plots of data from different columns.
   * Ignore columns or use the same column in many plots.
   * Add or remove columns from plots without having to deleting RRDs.
-  * Plot the results of arbitrary Perl expressions, including mathematical
-    ones, using one or more columns.
-  * Group multiple columns into a single plot using regular expressions on
-    the column titles.
+  * Plot the results of arbitrary Perl expressions, including
+    mathematical ones, using one or more columns.
+  * Group multiple columns into a single plot using regular
+    expressions on the column titles.
   * Creates an HTML tree of HTML files and PNG plots.
   * Creates an index of URL links listing all available targets.
   * Creates an index of URL links listing all different plot types.
   * No separate CGI set up required.
-  * Can be run under cron or it can sleep itself waiting for file updates
-    based on when the file was last updated.
+  * Can be run under cron or it can sleep itself waiting for file
+    updates based on when the file was last updated.
 
 Orca is similar to but substantially different from other tools that
 record and display hourly, daily, monthly, and yearly data, such as
@@ -1112,6 +1191,34 @@
 
   http://www.munitions.com/~jra/cricket/
 
+=head1 INDEX
+
+This is an index of this manual:
+
+  Name
+  Synopsis
+  Description
+  Index
+  Examples
+  Command Line Options
+  Mailing Lists
+  Plot Prefixes
+  Author, Comments and Bugs
+  Recognized Signals
+  Architecture Issues
+  Installation and Configuration
+    Required Global Parameters
+    Optional Global Parameters
+    Group Parameters
+      Required Group Parameters
+      Optional Group Parameters
+    Plot Parameters
+      Required Plot Parameters
+      Data Source Optional Plot Parameters
+    Plotting Parameters
+    Multiple Plot Plotting Parameters
+  Implementation Notes
+
 =head1 EXAMPLES
 
 A static example of Orca is at
@@ -1123,11 +1230,16 @@
 
 =head1 COMMAND LINE OPTIONS
 
-Orca has only four command line options.  They are:
+Orca has only five command line options.  They are:
 
 B<-gifs>: Generate GIFs instead of PNGs.  Tell Orca to generate GIFs
 instead of PNGs.  You may not want to generate GIFs since PNGs are 1/3
-the size of GIFs and take less time to generate.
+the size of GIFs and take less time to generate.  The only reason to
+do this is if you are using a browser that does not support PNGs and
+only supports GIFs.
+
+B<-no-html>: Do not generate any HTML files and only update the
+images.
 
 B<-o>: Once.  This tells Orca to go through the steps of finding
 files, updating the RRDs, updating the PNGs, and creating the HTML
@@ -1149,6 +1261,89 @@
 configuration files can be found in the sample_configs directory with
 the distribution of this tool.
 
+=head1 MAILING LISTS
+
+Four mailing lists exist for Orca.  To subscribe to any of the mailing
+lists, please visit the URL below.  You have the parameter of choosing
+a digest form of the mailing list if you wish it when you subscribe to
+the mailing list or anytime thereafter.  To send email to any of these
+lists you must subscribe to the list.
+
+B<orca-announce at yahoogroups.com>
+
+  Home         http://groups.yahoo.com/group/orca-announce/
+  Subscribe    http://groups.yahoo.com/group/orca-announce/join
+  Archive      http://groups.yahoo.com/group/orca-announce/archive
+
+The orca-announce at yahoogroups.com mailing list is a LOW volume
+moderated mailing list for announcing stable releases of Orca.
+
+B<orca-users at yahoogroups.com>
+
+  Home         http://groups.yahoo.com/group/orca-users/
+  Subscribe    http://groups.yahoo.com/group/orca-users/join
+  Archive      http://groups.yahoo.com/group/orca-users/archive
+
+The orca-users at yahoogroups.com is a first stop mailing list for
+getting help in setting up and getting Orca running.  Problems
+relating to downloading, configuring, compiling the necessary Perl
+modules, and installing Orca belong here.  People interested anything
+more than this, such as developing data gathering modules or active
+Perl development, should be on one or both of the
+orca-discuss at yahoogroups.com or orca-developers at yahoogroups.com
+mailing lists.  Once you get Orca running to your satisfaction, you
+may want to remove yourself from this list.
+
+B<orca-discuss at yahoogroups.com>
+
+  Home         http://groups.yahoo.com/group/orca-discuss/
+  Subscribe    http://groups.yahoo.com/group/orca-discuss/join
+  Archive      http://groups.yahoo.com/group/orca-discuss/archive
+
+The orca-discuss at yahoogroups.com mailing list is for active users of
+Orca who are doing new interesting things with Orca and want to
+discuss Orca but are not interested in actively developing Orca source
+code.  These people are also not interested in helping people get Orca
+running on their systems.
+
+B<orca-developers at yahoogroups.com>
+
+  Home         http://groups.yahoo.com/group/orca-developers/
+  Subscribe    http://groups.yahoo.com/group/orca-developers/join
+  Archive      http://groups.yahoo.com/group/orca-developers/archive
+
+The orca-developers at yahoogroups.com mailing list is for hackers of
+Orca who actually hack and improve Orca.
+
+=head1 PLOT PREFIXES
+
+RRDtool generates the actual GIF or PNG plots and sometimes will need
+to scale the Y axis of the plot to have normal looking like numbers,
+such as 1 M instead of 1,000,000.  If you see a letter following the
+numbers in the bottom of the plot, then use that letter to scale the Y
+axis appropriately:
+
+  a  10e-18 Ato
+  f  10e-15 Femto
+  p  10e-12 Pico
+  n  10e-9  Nano
+  u  10e-6  Micro
+  m  10e-3  Milli
+  k  10e3   Kilo
+  M  10e6   Mega
+  G  10e9   Giga
+  T  10e12  Terra
+  P  10e15  Peta
+  E  10e18  Exa
+
+=head1 AUTHOR, COMMENTS, AND BUGS
+
+Please direct all Orca comments and bugs to one of the above mailing
+lists.
+
+If you wish to contact the author of Orca, Blair Zajac, directly,
+please email me at blair at gps.caltech.edu.
+
 =head1 RECOGNIZED SIGNALS
 
 Orca, when it received the HUP signal, will look for new source data
@@ -1164,8 +1359,8 @@
 good amount of IO.  The machine running Orca should always have the
 B<rrd_dir> directory locally mounted.  It is more important this
 B<rrd_dir> be locally stored than B<html_dir> for performance
-concerns.  The two options B<html_dir> and B<rrd_dir> are described in
-more detail below.
+concerns.  The two parameters B<html_dir> and B<rrd_dir> are described
+in more detail below.
 
 =head1 INSTALLATION AND CONFIGURATION
 
@@ -1175,16 +1370,16 @@
 a line.  Lines that begin with whitespace are concatenated onto the
 last key's value.
 
-There are three main groups of options in a Orca confg: general
-options, file specific options, and plot specific options.  General
-options may be used by the file and plot specific options.  If an
-option is required, then it is only placed one time into the
-configuration file.
+There are three main groups of parameters in a Orca configuration
+file: global parameters, file specific parameters, and plot specific
+parameters.  Global parameters may be used by the group and plot
+specific parameters.  If an parameter is required, then it is only
+placed one time into the configuration file.
 
-General options break down into two main groups, required and options.
-These are the required options:
+Global parameters break down into two main groups, required and
+optional.  These are the required parameters:
 
-=head2 Required General Options
+=head2 Required Global Parameters
 
 =over 4
 
@@ -1194,8 +1389,8 @@
 all input data files and the Unix epoch time when they were last read
 by Orca into a state file.  The value for B<state_file> must be a
 valid, writable filename.  If I<filename> does not begin with a / and
-the B<base_dir> option was set, then the B<base_dir> directory will be
-prepended to the I<filename>.
+the B<base_dir> parameter was set, then the B<base_dir> directory will
+be prepended to the I<filename>.
 
 Each entry for a data input file is roughly 100 bytes, so for small
 sites, this file will not be large.
@@ -1208,8 +1403,9 @@
 directory should be on a disk locally attached to the host running
 Orca, but is not necessary.
 
-If I<directory> does not begin with a / and the B<base_dir> option was
-set, then the B<base_dir> directory will be prepended to I<directory>.
+If I<directory> does not begin with a / and the B<base_dir> parameter
+was set, then the B<base_dir> directory will be prepended to
+I<directory>.
 
 =item B<rrd_dir> I<directory>
 
@@ -1220,8 +1416,9 @@
 slowed down.  It is more important this B<rrd_dir> be locally stored
 than B<html_dir> for performance concerns.
 
-If I<directory> does not begin with a / and the B<base_dir> option was
-set, then the B<base_dir> directory will be prepended to I<directory>.
+If I<directory> does not begin with a / and the B<base_dir> parameter
+was set, then the B<base_dir> directory will be prepended to
+I<directory>.
 
 If B<rrd_dir> is not defined, then B<base_dir> will be used as
 B<rrd_dir>.  Orca will quit with an error if both B<rrd_dir> and
@@ -1231,15 +1428,26 @@
 
 If B<base_dir> is set, then it is used to prepend to any file or
 directory based names that do not begin with /.  These are currently
-B<state_file>, B<html_dir>, B<rrd_dir>, and the B<find_files> option
-in the B<group> options.
+B<state_file>, B<html_dir>, B<rrd_dir>, and the B<find_files>
+parameter in the B<group> section.
 
 =back
 
-=head2 Optional General Options
+=head2 Optional Global Parameters
 
 =over 4
 
+=item B<require> I<package name> I<version number>
+
+B<require> allows the configuration file to specify the minimum
+required version of a package to run as in the same way that B<use>
+and B<require> are used in Perl programs.  Here, both I<package name>
+and I<version number> are required and I<version number> must be a
+number, not a general Perl expression.
+
+Currently, only the version of Orca can be specified and I<package
+name> must be set to Orca.
+
 =item B<late_interval> I<Perl expression>
 
 B<late_interval> is used to calculate the time interval between a
@@ -1271,7 +1479,14 @@
   1) When a file did exist and now is gone.
   2) When a file was being updated regularly and then no longer is updated.
 
-By default, nobody is emailed.
+The only way to disable these email messages is by commenting out
+warn_email or by not giving it an argument:
+
+  #warn_email  root at localhost
+
+or
+
+  warn_email
 
 =item B<expire_images> 1
 
@@ -1280,7 +1495,7 @@
 being used, then the following modifications must added to srm.conf or
 httpd.conf.
 
-  < 
+  <
   < #MetaDir .web
   ---
   >
@@ -1295,20 +1510,28 @@
 
 =item B<find_times> I<hours:minutes> [I<hours:minutes> ...]
 
-The B<find_times> option is used to tell Orca when to go and find new
-files.  This particularly useful when new input data files are created
-at midnight.  In this case, something like
-
-  find_times 0:10
-
-would work.
+The B<find_times> parameter is used to tell Orca when to go and find
+new files.  This particularly useful when new input data files are
+created at midnight.  In this case, something like this may work:
+
+  # Find files at the following times:
+  #    0:10 to pick up new orcallator files for the new day.
+  #    1:00 to pick up late comer orcallator files for the new day.
+  #    6:00 to pick up new files before the working day.
+  #   12:00 to pick up new files during the working day.
+  #   19:00 to pick up new files after the working day.
+  find_times 0:10 1:00 6:00 12:00 19:00
+
+If you add too many different times to find_times, then Orca may spend
+a large amount of time finding files, so it's best just to have it
+find files when you know that they will appear.
 
 By default, files are only searched for when Orca starts up.
 
 =item B<html_top_title> I<text> ...
 
 The I<text> is placed at the top of the main index.html that Orca
-creates.  By default, no addition text is placed at the top of the
+creates.  By default, no additional text is placed at the top of the
 main index.html.
 
 =item B<html_page_header> I<text> ...
@@ -1322,24 +1545,67 @@
 creates.  By default, no additional text is placed at the bottom of
 each HTML file.
 
-=item B<sub_dir> I<directory>
+=item B<generate_hourly_plot> I<value>
+
+This tells Orca if it should or should not create a hourly plot of the
+data.  By default, the daily plot is always created, unless I<value>
+is set to 0.  This may be useful if it does not make any sense
+plotting the data on this timescale.
+
+=item B<generate_daily_plot> I<value>
+
+This tells Orca if it should or should not create a daily plot of the
+data.  By default, the daily plot is always created, unless I<value>
+is set to 0.  This may be useful if it does not make any sense
+plotting the data on this timescale.
+
+=item B<generate_weekly_plot> I<value>
+
+This tells Orca if it should or should not create a weekly plot of the
+data.  By default, the weekly plot is always created, unless I<value>
+is set to 0.  This may be useful if it does not make any sense
+plotting the data on this timescale.
+
+=item B<generate_monthly_plot> I<value>
+
+This tells Orca if it should or should not create a monthly plot of
+the data.  By default, the monthly plot is always created, unless
+I<value> is set to 0.  This may be useful if it does not make any
+sense plotting the data on this timescale.
 
-In certain cases Orca will not create sub directories for the
-different groups of files that it processes.  If you wish to force
-Orca to create sub directories, then do this
+=item B<generate_quarterly_plot> I<value>
 
-  sub_dir 1
+This tells Orca if it should or should not create a quarterly plot of
+the data.  By default, the quarterly plot is always created, unless
+I<value> is set to 0.  This may be useful if it does not make any
+sense plotting the data on this timescale.
+
+=item B<generate_yearly_plot> I<value>
+
+This tells Orca if it should or should not create a yearly plot of the
+data.  By default, the yearly plot is always created, unless I<value>
+is set to 0.  This may be useful if it does not make any sense
+plotting the data on this timescale.
+
+=item B<max_filename_length> I<value>
+
+When creating plots and HTML files Orca can create filenames that have
+an individual path element up to 250 bytes long.  Some web servers
+and/or web browsers cannot handle filenames this long and this
+configuration file parameter allows the user to reduce the length of
+the filenames that Orca creates.  The default I<value> is 250 and
+I<value> must be greater than 63.
 
 =back
 
-=head2 Group Options
+=head2 Group Parameters
 
 The next step in configuring Orca is telling where to find the files
 to use as input, a description of the columns of data comprising the
 file, the interval at which the file is updated, and where the
 measurement time is stored in the file.  This is stored into a group.
 
-A generic example of a group and its options are:
+A generic example of a group and its parameters are:
 
   group GROUP_NAME1 {
   find_files		filename1 filename2 ...
@@ -1358,18 +1624,18 @@
 
 The key for a group, in this example GROUP_NAME1 and GROUP_NAME2, is a
 descriptive name that is unique for all files and is used later when
-the plots to create are defined.  Files that share the same general
-format of column data may be grouped together.  The options for a
+the plots to create are defined.  Files that share the same global
+format of column data may be grouped together.  The parameters for a
 particular group must be enclosed in the curly brackets {}'s.  An
 unlimited number of groups may be listed.
 
-=head2 Required Group Options
+=head2 Required Group Parameters
 
 =over 4
 
 =item B<find_files> I<path|regexp> [I<path|regexp> ...]
 
-The B<find_files> option tells Orca what data files to use as its
+The B<find_files> parameter tells Orca what data files to use as its
 input.  The arguments to B<find_files> may be a simple filename, a
 complete path to a filename, or a regular expression to find files.
 The regular expression match is not the normal shell globing that the
@@ -1378,8 +1644,8 @@
 
   find_files /data/source1 /data/source2
 
-will have Orca use /data/source1 and /data/source2 as the inputs to Orca.
-This could have also been written as
+will have Orca use /data/source1 and /data/source2 as the inputs to
+Orca.  This could have also been written as
 
   find_files /data/source\d
 
@@ -1422,13 +1688,13 @@
 hence all the (?:...) for matching anything else.
 
 If any of the paths or regular expressions given to B<find_files> do
-not begin with a / and the B<base_dir> option was set, then the
+not begin with a / and the B<base_dir> parameter was set, then the
 B<base_dir> directory will be prepended to the path or regular
 expression.
 
 =item B<interval> I<seconds>
 
-The B<interval> options takes the number of seconds between updates
+The B<interval> parameters takes the number of seconds between updates
 for the input data files listed in this group.
 
 =item B<column_description> I<column_name> [I<column_name> ...]
@@ -1459,35 +1725,45 @@
 
 =item B<date_source> file_mtime
 
-The B<date_source> option tells Orca where time and date of the
-measurement is located.  The first form of the B<date_source> options
-lists the column name as given to B<column_description> that contains
-the Unix epoch time.  The second form with the file_mtime argument
-tells Orca that the date and time for any new data in the file is the
-last modification time of the file.
-
-=item B<date_format> I<string>
-
-The B<date_format> option is only required if the column_name argument
-to B<date_source> is used.  Current, this argument is not used by
-Orca.
+The B<date_source> parameter tells Orca where time and date of the
+measurement is located.  The first form of the B<date_source>
+parameters lists the column name as given to B<column_description>
+that contains the Unix epoch time.  The second form with the
+file_mtime argument tells Orca that the date and time for any new data
+in the file is the last modification time of the file.
+
+=item B<date_parse> I<Perl subroutine>
+
+To support converting arbitrary strings in the input source data files
+that somehow represent time into an Unix epoch time usable by Orca,
+the B<date_source> parameter can be used.  The value for B<date_parse>
+is a Perl subroutine that accepts two arguments, the first being the
+name of the file where the data is loaded and the second the string
+from the `date_source' column that contains some time information.
+The subroutine should return the Unix epoch time.  If this parameter
+is not specified, then Orca assumes that the string holds the Unix
+epoch time.
+
+This Perl subroutine is only used if the file's date source is not
+specified to be the file's last modified time as indicated to Orca by
+use of the B<date_source> file_mtime configuration file parameter.
 
 =back
 
-=head2 Optional Group Options
+=head2 Optional Group Parameters
 
 =over 4
 
 =item B<filename_compare> I<Perl subroutine>
 
-The B<filename_compare> option is used to sort the found filenames in
-a particular group.  This function must be written as though it were
-being passed to the Perl sort() function, which takes the two items to
-compare in the package global $a and $b variables instead of the @_
-array.
+The B<filename_compare> parameter is used to sort the found filenames
+in a particular group.  This function must be written as though it
+were being passed to the Perl sort() function, which takes the two
+items to compare in the package global $a and $b variables instead of
+the @_ array.
 
-Use of this option has an additional effect on letting Orca know when
-it can flush data to the RRD files.  It determines this when it
+Use of this parameter has an additional effect on letting Orca know
+when it can flush data to the RRD files.  It determines this when it
 compares the previously loaded filename to the filename about to be
 loaded using the B<filename_compare> function.  If the result of the
 comparison is greater than 1, then the data is flushed.  If the
@@ -1517,20 +1793,26 @@
 not cause a flush but when orcallator-2000-02-16 is about to be
 loaded, previously loaded data will be flushed.
 
-If the B<filename_compare> option is not used, then the filenames are
-sorted using the Perl <=> operator and data is not flushed until all
-of it is loaded.
+If the B<filename_compare> parameter is not used, then the filenames
+are sorted using the Perl <=> operator and data is not flushed until
+all of it is loaded.
+
+=item B<late_interval> I<Perl expression>
+
+Each group can have its own B<late_interval> that overrides the
+late_interval global parameter.  If the group's late_interval is not
+specified, then the global one is used.
 
 =item B<reopen> 1
 
-Using the B<reopen> option for a group instructs Orca to close and
+Using the B<reopen> parameter for a group instructs Orca to close and
 reopen any input data files when there is new data to be read.  This
 is of most use when an input data file is erased and rewritten by some
 other process.
 
 =back
 
-=head2 Plot Options
+=head2 Plot Parameters
 
 The final step is to tell Orca what plots to create and how to create
 them.  The general format for creating a plot is:
@@ -1552,19 +1834,19 @@
 Unlike the group, there is no key for generating a plot.  An unlimited
 number of plots can be created.
 
-Some of the plot options if they have the two characters %g or %G will
-perform a substitution of this substring with the group name from the
-find_files ()'s matching.  %g gets replaced with the exact match from
-() and %G gets replaced with the first character capitalized.  For
-example, if
+Some of the plot parameters if they have the two characters %g or %G
+will perform a substitution of this substring with the group name from
+the find_files ()'s matching.  %g gets replaced with the exact match
+from () and %G gets replaced with the first character capitalized.
+For example, if
 
   find_files /(olympia)/data
 
 was used to locate a file, then %g will be replaced with olympia and
 %G replaced with Olympia.  This substitution is performed on the
-B<title> and B<legend> plot options.
+B<title> and B<legend> plot parameters.
 
-=head2 Required Plot Options
+=head2 Required Plot Parameters
 
 =over 4
 
@@ -1578,19 +1860,19 @@
 
 =item B<data> I<regular expression>
 
-The B<data> plot option tells Orca the data sources to use to place in
-a single PNG plot.  At least one B<data> option is required for a
-particular plot and as many as needed may be placed into a single
+The B<data> plot parameter tells Orca the data sources to use to place
+in a single PNG plot.  At least one B<data> parameter is required for
+a particular plot and as many as needed may be placed into a single
 plot.
 
 Two forms of arguments to B<data> are allowed.  The first form allows
 arbitrary Perl expressions, including mathematical expressions, that
 result in a number as a data source to plot.  The expression may
 contain the names of the columns as found in the group given to the
-B<source> option.  The column names must be separated with white space
-from any other characters in the expression.  For example, if you have
-number of bytes per second input and output and you want to plot the
-total number of bits per second, you could do this:
+B<source> parameter.  The column names must be separated with white
+space from any other characters in the expression.  For example, if
+you have number of bytes per second input and output and you want to
+plot the total number of bits per second, you could do this:
 
   plot {
   source	bytes_per_second
@@ -1616,7 +1898,7 @@
                      hme0IErr/s hme0OErr/s
                      hme1IErr/s hme1OErr/s
   .
-  .  
+  .
   }
 
   plot {
@@ -1670,7 +1952,7 @@
   hme1 Input & Output Errors per Second
 
 If you wanted to have the links listed in order of hme0 and hme1, then
-you would add the B<flush_regexps> option to tell Orca to find all
+you would add the B<flush_regexps> parameter to tell Orca to find all
 regular expression matches for a particular plot set and all plot sets
 before the plot set containing B<flush_regexps> before continuing on
 to the next plot set.  For example, if
@@ -1700,23 +1982,25 @@
 
 =back
 
-=head2 Data Source Optional Plot Options
+=head2 Data Source Optional Plot Parameters
 
-The following options are plot optional.  Like the B<data> option,
-multiple copies of these may be specified.  The first option of a
-particular type sets the option for the first B<data> option, the
-second option refers to the second B<data> option, etc.
+The following parameters are optional.  Like the B<data> parameter,
+multiple copies of these may be specified.  The first parameter of a
+particular type sets the parameter for the first B<data> parameter,
+the second parameter refers to the second B<data> parameter, etc.
 
 =over 4
 
 =item B<data_type> I<type>
 
 When defining data types, Orca uses the same data types as provided by
-RRD.  These are (a direct quote from the RRDcreate manual page):
+RRD.
+
+These are (a direct quote from the RRDcreate manual page):
 
 =over 4
 
-=item B<GAUGE> 
+=item B<GAUGE>
 
 is for things like temperatures or number of people in a room or value
 of a RedHat share.
@@ -1740,7 +2024,7 @@
 overflow checks. So if your counter does not reset at 32 or 64 bit you
 might want to use DERIVE and combine it with a MIN value of 0.
 
-=item B<ABSOLUTE> 
+=item B<ABSOLUTE>
 
 is for counters which get reset upon reading. This is used for fast
 counters which tend to overflow. So instead of reading them normally
@@ -1749,17 +2033,50 @@
 
 =back
 
-If the B<data_type> is not specified for a B<data> option, it defaults
-to GAUGE.
+If there are no B<data_type>'s specified for a plot, then all of the
+data_types for the data's default to GAUGE.  If at least one data_type
+is specified and there are more data's than data_types's, then the
+last specified data_type will be used for all of the data's were not
+given a data_type.  In the following example, there are three data's
+and only two data_types's.  The data_type of COUNTER will be applied
+to column3 and column4.
+
+  plot {
+  data		column1
+  data		column2
+  data		column3
+  data		column4
+  data_type	DERIVE
+  data_type	COUNTER
+  }
+
+
+The B<data_type> is only used once when the RRD files are created as a
+parameter to rrdcreate.  If you want to change B<data_type> after the
+RRD files have been created and you want to change these values, then
+you have to modify Orca's configuration file, remove the RRD files and
+let Orca rebuild them.
+
+If there are multiple plots that refer to the same RRD and if the
+different plots have different data_types, then the first plot that
+creates the RRD file will set the data_type.
 
 =item B<data_min> I<number>
 
 =item B<data_max> I<number>
 
 B<data_min> and B<data_max> are optional entries defining the expected
-range of the supplied data.  If B<data_min> and/or B<data_max> are
-defined, any value outside the defined range will be regarded as
-I<*UNKNOWN*>.
+range of the supplied data and used by RRDtool and not by Orca to
+limit the range of data stored in the RRD files.  If the input value
+that Orca passes to RRDtool is less than B<data_min> or greater than
+B<data_max> then RRD will store I<*UNKNOWN*> in its place instead.
+
+These values are only used once when the RRD files are created as a
+parameter to rrdcreate.  If you want to change either B<data_min> or
+B<data_max> after the RRD files have been created and you want to
+change these values, then you have to modify Orca's configuration file
+and either remove the RRD files and let Orca rebuild them or find a
+separate RRD program that will modify the minimum and maximum values.
 
 If you want to specify the second data sources minimum and maximum but
 do not want to limit the first data source, then set the I<number>'s
@@ -1768,25 +2085,40 @@
   plot {
   data		column1
   data		column2
+  data		column3
   data_min	U
   data_max	U
   data_min	0
   data_max	100
   }
 
+If there are no minimum or maximum values specified for a particular
+plot, then there will no limit applied to any input data given to the
+RRD file since the value 'U' is passed to rrdcreate.  If at least one
+data_min or data_max is specified and there are more data's than
+data_*'s, then the last specified data_* will be used for all of the
+data's were not given a data_*'.  In the example above, there are
+three data's and only two data_*'s.  The minimum of 0 and maximum of
+100 will be applied to column3.
+
+If there are multiple plots that refer to the same RRD and if the
+different plots have different data_min's and data_max's, then the
+first plot that creates the RRD file will set the data_min's and
+data_max's.
+
 =item B<color> I<rrggbb>
 
-The optional B<color> option specifies the color to use for a
+The optional B<color> parameter specifies the color to use for a
 particular plot.  The color should be of the form I<rrggbb> in
 hexadecimal.
 
 =item B<flush_regexps> 1
 
-Using the B<flush_regexps> option tells Orca to make sure that the
-plot set including this option and all previous plot sets have matched
-all of the columns with their regular expressions.  See the above
-description of using regular expressions in the B<data> option for an
-example.
+Using the B<flush_regexps> parameter tells Orca to make sure that the
+plot set including this parameter and all previous plot sets have
+matched all of the columns with their regular expressions.  See the
+above description of using regular expressions in the B<data>
+parameter for an example.
 
 =item B<required> 1
 
@@ -1799,12 +2131,12 @@
 
   required 1
 
-in the options for a particular plot.  In this case, Orca will record
-a I<*UNKNOWN*> value for all invalid data.
+in the parameters for a particular plot.  In this case, Orca will
+record a I<*UNKNOWN*> value for all invalid data.
 
 =back
 
-=head2 Plotting Options
+=head2 Plotting Parameters
 
 =over 4
 
@@ -1816,44 +2148,44 @@
 
 =item B<plot_width> I<number>
 
-Using the B<plot_width> option specifies how many pixels wide the
+Using the B<plot_width> parameter specifies how many pixels wide the
 drawing area inside the PNG is.
 
 =item B<plot_height> I<number>
 
-Using the B<plot_height> option specifies how many pixels high the
+Using the B<plot_height> parameter specifies how many pixels high the
 drawing area inside the PNG is.
 
 =item B<plot_min> I<number>
 
-By setting the B<plot_min> option, the minimum value to be graphed is
-set.  By default this will be auto-configured from the data you select
-with the graphing functions.
+By setting the B<plot_min> parameter, the minimum value to be graphed
+is set.  By default this will be auto-configured from the data you
+select with the graphing functions.
 
 =item B<plot_max> I<number>
 
-By setting the B<plot_max> option, the minimum value to be graphed is
-set.  By default this will be auto-configured from the data you select
-with the graphing functions.
+By setting the B<plot_max> parameter, the minimum value to be graphed
+is set.  By default this will be auto-configured from the data you
+select with the graphing functions.
 
 =item B<rigid_min_max>
 
 Normally Orca will automatically expand the lower and upper limit if
 the graph contains a value outside the valid range.  By setting the
-B<rigid_min_max> option, this is disabled.
+B<rigid_min_max> parameter, this is disabled.
 
 =item B<logarithmic>
 
 Normally Orca will use a linear scale for the Y axis.  If a plot
-contains this option, then a logarithmic scale will be used.
+contains this parameter, then a logarithmic scale will be used.
 
 =item B<title> <text>
 
-Setting the B<title> option sets the title of the plot.  If you place
-%g or %G in the title, it is replaced with the text matched by any
-()'s in the group B<find_files> option.  %g gets replaced with the
-exact text matched by the ()'s and %G is replaced with the same text,
-except the first character is capitalized.
+Setting the B<title> parameter sets the title of the plot.  If you
+place %g or %G in the title, it is replaced with the text matched by
+any ()'s in the group B<find_files> parameter.  %g gets replaced with
+the exact text matched by the ()'s and %G is replaced with the same
+text, except the first character is capitalized.
 
 =item B<y_legend> <text>
 
@@ -1862,17 +2194,17 @@
 
 =back
 
-=head2 Multiple Plot Plotting Options
+=head2 Multiple Plot Plotting Parameters
 
 =over 4
 
-The following options should be specified multiple times for each data
-source in the plot.
+The following parameters should be specified multiple times for each
+data source in the plot.
 
 =item B<line_type> I<type>
 
-The B<line_type> option specifies the type of line to plot a
-particular data set with.  The available options are: LINE1, LINE2,
+The B<line_type> parameter specifies the type of line to plot a
+particular data set with.  The available parameters are: LINE1, LINE2,
 and LINE3 which generate increasingly wide lines, AREA, which does the
 same as LINE? but fills the area between 0 and the graph with the
 specified color, and STACK, which does the same as LINE?, but the
@@ -1882,9 +2214,56 @@
 
 =item B<legend> I<text>
 
-The B<legend> option specifies for a single data source the comment
+The B<legend> parameter specifies for a single data source the comment
 that is placed below the PNG plot.
 
+=item B<summary_format> I<format>
+
+The B<summary_format> option specifies the format for the summary
+values, as passed to the RRDtool GPRINT function.  In the format
+string there should be a '%lf' or '%le' marker in the place where the
+number should be printed.
+
+If an additional '%s' is found AFTER the marker, the value will be
+scaled and an appropriate SI magnitude unit will be printed in place
+of the '%s' marker.  The scaling will take the base of the plot into
+consideration.
+
+If a '%S' is used instead of a '%s', then instead of calculating the
+appropriate SI magnitude unit for this value, the previously
+calculated SI magnitude unit will be used.  This is useful if you want
+all the values in a PRINT statement to have the same SI magnitude
+unit.  If there was no previous SI magnitude calculation made, then
+'%S' behaves like a '%s', unless the value is 0, in which case it does
+not remember a SI magnitude unit and a SI magnitude unit will only be
+calculated when the next '%s' is seen or the next '%S' for a non-zero
+value.
+
+The same format is used for each number within a single summary line,
+but you can specify multiple summary_format options if there are
+multiple plots on the graph:
+
+  plot {
+  source		things
+  data			some
+  data			other
+  data			things
+  data			something_else
+  summary_format	%.0lf
+  summary_format	%4.1f %s
+  color			0000ff
+  color			ff0000
+  }
+
+If there are no summary format specifiers, then the default format of
+'%9.3lf %S' will be used for all of the data summary lines.  If at
+least one summary_format is specified and there are more data's than
+summary_format's, then the last specified summary_format will be used
+for all of the data summary lines that were not given a
+summary_format.  In the example above, there are four data's and only
+two summary_format's.  The format '%4.1f %s' will be used for the
+`things' and `something_else' data summary lines.
+
 =back
 
 =head1 IMPLEMENTATION NOTES
@@ -1901,64 +2280,6 @@
 the value being the anonymous subroutine array.  This saves in memory
 and in processing time.
 
-=head1 MAILING LISTS
-
-Four mailing lists exist for Orca.  To subscribe to any of the mailing
-lists, please visit the URL below.  You have the option of choosing a
-digest form of the mailing list if you wish it when you subscribe to
-the mailing list or anytime thereafter.  To send email to any of these
-lists you must subscribe to the list.
-
-B<orca-announce>
-
-  Subscribe http://www.onelist.com/subscribe/orca-announce
-  Archive   http://www.onelist.com/archive/orca-announce
-
-The orca-announce at onelist.com mailing list is a LOW volume moderated
-mailing list for announcing stable releases of Orca.
-
-B<orca-users at onelist.com>
-
-  Subscribe http://www.onelist.com/subscribe/orca-users
-  Archive   http://www.onelist.com/archive/orca-users
-
-The orca-users at onelist.com is a first stop mailing list for getting
-help in setting up and getting Orca running.  Problems relating to
-downloading, configuring, compiling the necessary Perl modules, and
-installing Orca belong here.  People interested anything more than
-this, such as developing data gathering modules or active Perl
-development, should be on one or both of the orca-discuss at onelist.com
-or orca-developers at onelist.com mailing lists.  Once you get Orca
-running to your satisfaction, you may want to remove yourself from
-this list.
-
-B<orca-discuss at onelist.com>
-
-  Subscribe http://www.onelist.com/subscribe/orca-discuss
-  Archive   http://www.onelist.com/archive/orca-discuss
-
-The orca-discuss at onelist.com mailing list is for active users of Orca
-who are doing new interesting things with Orca and want to discuss
-Orca but are not interested in actively developing Orca source code.
-These people are also not interested in helping people get Orca
-running on their systems.
-
-B<orca-developers at onelist.com>
-
-  Subscribe http://www.onelist.com/subscribe/orca-developers
-  Archive   http://www.onelist.com/archive/orca-developers
-
-The orca-developers at onelist.com mailing list is for hackers of Orca
-who actually hack and improve Orca.
-
-=head1 AUTHOR, COMMENTS, AND BUGS
-
-Please direct all Orca comments and bugs to one of the above mailing
-lists.
-
-If you wish to contact the author or Orca, Blair Zajac, directly,
-please email me to blair at akamai.com.
-
 =cut
 
 These are hexadecimal forms of GIFs used by Orca.

Modified: trunk/orca/docs/manual.html
==============================================================================
--- trunk/orca/docs/manual.html	(original)
+++ trunk/orca/docs/manual.html	Sat Jul 13 21:25:42 2002
@@ -77,9 +77,9 @@
 
 
 "Company, Paul" wrote:
-> 
+>
 > Observations on Solaris 2.x:
-> 
+>
 >         + Average # Processes in Run Queue
 >           and
 >           System Load
@@ -87,12 +87,12 @@
 >         + Bits Per Second does not work, although the Packets Per Second
 > does.
 >         + No definitions for Data Sets
-> 
+>
 > File this stuff away or not.
 > Just though you might want this data.
 > I'll send you the fixes if I find them.
-> 
+>
 > --pjc
-> 
+>
 >
 

Modified: trunk/orca/docs/Makefile.in
==============================================================================
--- trunk/orca/docs/Makefile.in	(original)
+++ trunk/orca/docs/Makefile.in	Sat Jul 13 21:25:42 2002
@@ -1,7 +1,9 @@
+ at SET_MAKE@
+
 prefix	= @prefix@
 mandir	= @mandir@/man1
-MKDIR	= @MKDIR@
 INSTALL	= @INSTALL@
+MKDIR	= @MKDIR@
 ORCA	= ../src/orca.pl
 
 TARGETS	= orca.man orca.html orca.txt
@@ -23,7 +25,6 @@
 
 Makefile: Makefile.in
 	cd .. && CONFIG_FILES=docs/Makefile ./config.status
-	$(MAKE)
 
 clean:
 	$(RM) $(TARGETS) pod2html-*

Modified: trunk/orca/docs/REQUIREMENTS
==============================================================================
--- trunk/orca/docs/REQUIREMENTS	(original)
+++ trunk/orca/docs/REQUIREMENTS	Sat Jul 13 21:25:42 2002
@@ -7,7 +7,7 @@
 		Can have brand new data fields at any point in time
 
 	Internal Storage
-		
+
 	Methods
 
 Orca::RRDFile

Modified: trunk/orca/README
==============================================================================
--- trunk/orca/README	(original)
+++ trunk/orca/README	Sat Jul 13 21:25:42 2002
@@ -40,7 +40,7 @@
 explain how the data files Orca uses are created, maintained, and used
 to create the images that Orca creates.  Read about RRDtool at
 
-    http://ee-staff.ethz.ch/~oetiker/webtools/rrdtool/
+    http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/
 
 DATA COLLECTION TOOLS
 =====================
@@ -87,16 +87,18 @@
 the mailing list or anytime thereafter.  To send email to any of these
 lists you must subscribe to the list.
 
-orca-announce at onelist.com
-    Subscribe    http://www.onelist.com/subscribe/orca-announce
-    Archive      http://www.onelist.com/archive/orca-announce
+orca-announce at yahoogroups.com
+    Home         http://groups.yahoo.com/group/orca-announce/
+    Subscribe    http://groups.yahoo.com/group/orca-announce/join
+    Archive      http://groups.yahoo.com/group/orca-announce/archive
 
     This is a LOW volume moderated mailing list for announcing stable
     releases of Orca.
 
-orca-users at onelist.com
-    Subscribe    http://www.onelist.com/subscribe/orca-users
-    Archive      http://www.onelist.com/archive/orca-users
+orca-users at yahoogroups.com
+    Home         http://groups.yahoo.com/group/orca-users/
+    Subscribe    http://groups.yahoo.com/group/orca-users/join
+    Archive      http://groups.yahoo.com/group/orca-users/archive
 
     This mailing list is a first stop mailing list for getting help
     in setting up and getting Orca running.  Problems relating to
@@ -107,9 +109,10 @@
     Once you get Orca running to your satisfaction, you may want to
     remove yourself from this list.
 
-orca-discuss at onelist.com
-    Subscribe    http://www.onelist.com/subscribe/orca-discuss
-    Archive      http://www.onelist.com/archive/orca-discuss
+orca-discuss at yahoogroups.com
+    Home         http://groups.yahoo.com/group/orca-discuss/
+    Subscribe    http://groups.yahoo.com/group/orca-discuss/join
+    Archive      http://groups.yahoo.com/group/orca-discuss/archive
 
     This mailing list is for active users of Orca who are doing new
     interesting things with Orca and want to discuss Orca but are not
@@ -117,9 +120,10 @@
     are also not interested in helping people get Orca running on their
     systems.
 
-orca-developers at onelist.com
-    Subscribe    http://www.onelist.com/subscribe/orca-developers
-    Archive      http://www.onelist.com/archive/orca-developers
+orca-developers at yahoogroups.com
+    Home         http://groups.yahoo.com/group/orca-developers/
+    Subscribe    http://groups.yahoo.com/group/orca-developers/join
+    Archive      http://groups.yahoo.com/group/orca-developers/archive
 
     This mailing list is for people who are interested in actively
     developing, fixing and improving Orca's source code and related data
@@ -133,17 +137,19 @@
 AUTHOR
 ======
 
-These two tools were written by Blair Zajac.  I welcome any patches for
-bugs or improvements, comments and suggestions.  Please send any Orca
-correspondence to orca-users at onelist.com or orca-developers at onelist.com,
-which I read and participate on.
+These two tools were written by Blair Zajac.  I welcome any patches
+for bugs or improvements, comments and suggestions.  Please send any
+Orca correspondence to orca-users at yahoogroups.com or
+orca-developers at yahoogroups.com, which I read and participate on.
 
-If you wish to contact me directly, my email address is bzajac at akamai.com.
+If you wish to contact me directly, my email address is
+blair at gps.caltech.edu.
 
 NAMING OF ORCA
 ==============
 
-I originally named Orca FMRTG, but after asking my wife
-http://www.rothschildimage.com for some suggestions, she came up with
-Orca.  It turns out that there are only one or two small programs on
-the Internet named Orca, so we both were happy to hear this.
+I originally named Orca FMRTG, but after asking my wife Ashley
+Rothschild (http://www.rothschildimage.com) for some suggestions, she
+came up with Orca.  It turns out that there are only one or two small
+programs on the Internet named Orca, so we both were happy to hear
+this.

Added: trunk/orca/contrib/Makefile.in
==============================================================================
--- trunk/orca/contrib/Makefile.in	(original)
+++ trunk/orca/contrib/Makefile.in	Sat Jul 13 21:25:42 2002
@@ -0,0 +1,34 @@
+ at SET_MAKE@
+
+SUBDIRS = orcaservices rotate_orca_graphs
+
+all:	Makefile $(TARGETS)
+	@for dir in $(SUBDIRS); do					\
+		echo "cd $$dir && $(MAKE) CFLAGS=$(CFLAGS)";		\
+		(cd $$dir && $(MAKE) CFLAGS="$(CFLAGS)");		\
+	done
+
+# Users will need to install the contributed programs by hand.
+install:
+
+install_contrib:
+	@for dir in $(SUBDIRS); do					\
+		echo "cd $$dir && $(MAKE) CFLAGS=$(CFLAGS) install";	\
+		(cd $$dir && $(MAKE) CFLAGS="$(CFLAGS)" install);	\
+	done
+
+clean:
+	@for dir in $(SUBDIRS); do					\
+		echo "cd $$dir && $(MAKE) CFLAGS=$(CFLAGS) clean";	\
+		(cd $$dir && $(MAKE) CFLAGS="$(CFLAGS)" clean);		\
+	done
+
+distclean: clean
+	@for dir in $(SUBDIRS); do					\
+		echo "cd $$dir && $(MAKE) CFLAGS=$(CFLAGS) distclean";	\
+		(cd $$dir && $(MAKE) CFLAGS="$(CFLAGS)" distclean);	\
+	done
+	$(RM) Makefile
+
+Makefile: Makefile.in
+	cd ../.. && CONFIG_FILES=contrib/Makefile ./config.status

Added: trunk/orca/contrib/rotate_orca_graphs/Makefile.in
==============================================================================
--- trunk/orca/contrib/rotate_orca_graphs/Makefile.in	(original)
+++ trunk/orca/contrib/rotate_orca_graphs/Makefile.in	Sat Jul 13 21:25:42 2002
@@ -0,0 +1,34 @@
+ at SET_MAKE@
+
+bindir	= @bindir@
+INSTALL	= @INSTALL
+MKDIR	= @MKDIR@
+
+TARGETS	= rotate_orca_graphs
+
+all:	Makefile $(TARGETS)
+
+Makefile: Makefile.in
+	cd ../.. && CONFIG_FILES=contrib/rotate_orca_graphs/Makefile ./config.status
+
+rotate_orca_graphs.sh: rotate_orca_graphs.sh.in
+	cd ../.. && CONFIG_FILES=contrib/rotate_orca_graphs/rotate_orca_graphs.sh ./config.status
+
+.SUFFIXES:	.sh
+
+.sh:
+	cp $< $@
+	chmod 0755 $@
+
+install:
+	$(MKDIR) $(bindir)
+	@for file in $(TARGETS); do			\
+		echo $(INSTALL) $$file $(bindir);	\
+		$(INSTALL) $$file $(bindir);		\
+	done
+
+clean:
+	$(RM) $(TARGETS)
+
+distclean: clean
+	$(RM) *.sh Makefile

Added: trunk/orca/contrib/rotate_orca_graphs/rotate_orca_graphs.sh.in
==============================================================================
--- trunk/orca/contrib/rotate_orca_graphs/rotate_orca_graphs.sh.in	(original)
+++ trunk/orca/contrib/rotate_orca_graphs/rotate_orca_graphs.sh.in	Sat Jul 13 21:25:42 2002
@@ -0,0 +1,39 @@
+#!/bin/sh
+#
+# This script can be used to generate daily copies of the Orca HTML
+# directory so that daily plots of your systems can be stored and
+# viewed later.
+#
+# To use this script:
+# 1) Set the ARCHIVE_DIR to the location of the archive directory.
+# 2) Set up a cron job that runs this script:
+#    59 23 * * * create_orca_daily_graphs.sh
+
+# Set this directory to archive the daily plots in.
+ARCHIVE_DIR=
+
+DATE=`date +%Y-%m-%d`
+HTML_DIR=@HTML_DIR@
+TAR=@TAR@
+
+if test -z "$ARCHIVE_DIR"; then
+  echo "$0: please edit $0 to set ARCHIVE_DIR" 1>&2
+  exit 1
+fi
+
+# Make sure that the Orca and archive HTML directories are not the
+# same.
+cd $ARCHIVE_DIR
+dir2=`pwd`
+cd $HTML_DIR
+dir1=`pwd`
+if test "$dir1" = "$dir2"; then
+  echo "$0: HTML_DIR $dir1 and ARCHIVE_DIR $dir2 are the same directory" 1>&2
+  exit 1
+fi
+
+if test ! -e $ARCHIVE_DIR/$DATE; then
+  mkdir $ARCHIVE_DIR/$DATE || exit 1
+fi
+
+$TAR cfl - . | (cd $ARCHIVE_DIR/$DATE; $TAR xf -)

Added: trunk/orca/contrib/orcaservices/Makefile.in
==============================================================================
--- trunk/orca/contrib/orcaservices/Makefile.in	(original)
+++ trunk/orca/contrib/orcaservices/Makefile.in	Sat Jul 13 21:25:42 2002
@@ -0,0 +1,85 @@
+ at SET_MAKE@
+
+prefix		= @prefix@
+exec_prefix	= @exec_prefix@
+bindir		= @bindir@
+libdir		= @libdir@
+INSTALL		= @INSTALL@
+MKDIR		= @MKDIR@
+PERL_HEAD	= @PERL_HEAD@
+ORCALLATOR_DIR	= @ORCALLATOR_DIR@/../orcaservices
+ORCASERVICES_DIR	= @ORCALLATOR_DIR@/../orcaservices
+RRD_DIR		= @RRD_DIR@
+RRDTOOL_DIR	= @RRDTOOL_DIR@
+PERL_SCRIPTS	= orcaservices_running orcaservices.pl
+SHELL_SCRIPTS	= restart_orcaservices stop_orcaservices start_orcaservices \
+		  S99orcaservices
+TARGETS		= $(PERL_SCRIPTS) $(SHELL_SCRIPTS)
+
+all:		Makefile $(TARGETS) orcaservices.cfg
+
+install: all
+		$(MKDIR) $(bindir)
+		$(MKDIR) $(libdir)
+		$(MKDIR) $(RRD_DIR)/orcaservices
+		@for file in $(TARGETS); do			\
+			echo $(INSTALL) $$file $(bindir);	\
+			$(INSTALL) $$file $(bindir);		\
+		done
+		if test -r $(libdir)/orcaservices.cfg; then	\
+			cp -p $(libdir)/orcaservices.cfg $(libdir)/orcaservices.cfg.`date +%Y-%m-%d-%H:%M:%S`; \
+		fi
+		$(INSTALL) -m 0644 orcaservices.cfg $(libdir)
+		$(INSTALL) -m 0755 orcaservices.pl $(libdir)
+
+orcaservices_run_at_boot: all
+		-$(RM) /etc/init.d/orcaservices /etc/rc0.d/K01orcaservices
+		-$(RM) /etc/rc1.d/K01orcaservices /etc/rc3.d/S99orcaservices
+		$(INSTALL) -m 0744 S99orcaservices /etc/init.d/orcaservices
+		ln /etc/init.d/orcaservices /etc/rc0.d/K01orcaservices
+		ln /etc/init.d/orcaservices /etc/rc1.d/K01orcaservices
+		ln /etc/init.d/orcaservices /etc/rc3.d/S99orcaservices
+
+clean:
+		$(RM) $(TARGETS)
+
+distclean:	clean
+		$(RM) *.sh orcaservices.cfg orcaservices_running.pl Makefile
+
+.SUFFIXES:	.pl .sh
+
+.pl:		$(PERL_HEAD)
+		cat $(PERL_HEAD) $< > $@
+		chmod 0755 $@
+
+.sh:
+		cp $< $@
+		chmod 0755 $@
+
+Makefile:	Makefile.in
+		cd ../.. && CONFIG_FILES=contrib/orcaservices/Makefile ./config.status
+		$(MAKE)
+
+orcaservices.cfg:			orcaservices.cfg.in
+		cd ../.. && CONFIG_FILES=contrib/orcaservices/orcaservices.cfg ./config.status
+
+orcaservices.pl:		orcaservices.pl.in	$(PERL_HEAD)
+		cd ../.. && CONFIG_FILES=contrib/orcaservices/orcaservices.pl ./config.status
+		cat $(PERL_HEAD) orcaservices.pl > orcaservices.perl
+		mv orcaservices.perl orcaservices.pl
+		chmod 0755 orcaservices.pl
+
+orcaservices_running.pl:		orcaservices_running.pl.in
+		cd ../.. && CONFIG_FILES=contrib/contrib/orcaservices/orcaservices_running.pl ./config.status
+
+restart_orcaservices.sh:		restart_orcaservices.sh.in
+		cd ../.. && CONFIG_FILES=contrib/contrib/orcaservices/restart_orcaservices.sh ./config.status
+
+start_orcaservices.sh:		start_orcaservices.sh.in
+		cd ../.. && CONFIG_FILES=contrib/contrib/orcaservices/start_orcaservices.sh ./config.status
+
+stop_orcaservices.sh:		stop_orcaservices.sh.in
+		cd ../.. && CONFIG_FILES=contrib/contrib/orcaservices/stop_orcaservices.sh ./config.status
+
+S99orcaservices.sh:		S99orcaservices.sh.in
+		cd ../.. && CONFIG_FILES=contrib/contrib/orcaservices/S99orcaservices.sh ./config.status

Added: trunk/orca/contrib/orcaservices/start_orcaservices.sh.in
==============================================================================
--- trunk/orca/contrib/orcaservices/start_orcaservices.sh.in	(original)
+++ trunk/orca/contrib/orcaservices/start_orcaservices.sh.in	Sat Jul 13 21:25:42 2002
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+# This script runs orcaservices.pl with the proper options for your site.
+
+# Define program locations that will be needed.
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+AWK=@AWK@
+CUT=@CUT@
+UNAME=@UNAME@
+ORCASERVICES_DIR=@ORCALLATOR_DIR@/../orcaservices
+
+# Get the hostname without the fully qualified part; that is, trim off
+# anything past the first `.'.
+uname=`$UNAME -n | $CUT -d. -f1`
+
+# The directory these files go into is $ORCASERVICES_DIR/HOSTNAME
+OUTDIR=$ORCASERVICES_DIR/$uname
+
+# Export the environmental variables.
+export OUTDIR
+
+# Check if orcaservices is already running.
+pids=`/usr/ucb/ps auxww | $AWK '/orcaservices.pl/ && !/awk/ {print $2}'`
+if test "$pids" != ""; then
+  echo "Orcaservices already running.  Exiting."
+  exit 1
+fi
+
+echo "Writing data into $OUTDIR/"
+
+# Cd to / so that any automounted filesystems can be unmounted.
+cd /
+
+# Create the output directory if it doesn't exist yet.
+if test ! -d $OUTDIR; then
+  echo "Creating $OUTDIR/"
+  mkdir -p $OUTDIR
+fi
+
+if test ! -d $OUTDIR; then
+  echo "Unable to create $OUTDIR/" 1>&2
+  exit 2
+fi
+
+# Now start the logging.
+echo "Starting logging"
+HOSTNAME=`hostname`
+if test -f "$libdir/orcaservices.$HOSTNAME"; then
+    $libdir/orcaservices.pl `cat $libdir/orcaservices.$HOSTNAME`
+else
+    $libdir/orcaservices.pl
+fi
+
+### # Write the PID of orcaservices to a file to make killing easier.
+### pid=$!
+### echo $pid > $OUTDIR/orcaservices.pid
+
+# Sleep for a couple of seconds to allow any orcaservices warnings to appear.
+sleep 5

Added: trunk/orca/contrib/orcaservices/orcaservices.pl.in
==============================================================================
--- trunk/orca/contrib/orcaservices/orcaservices.pl.in	(original)
+++ trunk/orca/contrib/orcaservices/orcaservices.pl.in	Sat Jul 13 21:25:42 2002
@@ -0,0 +1,2022 @@
+##
+##
+## OrcaServices.pl, a log generating services usage monitor
+##
+##
+
+##
+## This program logs many different services usage to a log file
+## for later processing.
+##
+
+##
+## Author: Carlos Canau <Carlos.Canau at KPNQwest.com>
+## With: Jose Carlos Pereira <Jose.Pereira at KPNQwest.com>
+##
+
+##
+## Portions adapted from Orcallator.se written by Blair Zajac
+## Portions ported to perl from Orcallator.se written by Blair Zajac
+## other portions adapted from several other open source scripts
+##
+##
+
+##
+## Version 1.5.5.dist: 06 Nov 2000	First distribution version
+##
+## Version 1.5.5: 31 Oct 2000	Bug with increasing "others" in named
+##
+## Version 1.5.4: 31 Oct 2000	DB radiator more secure method of getting DB user/pass
+##
+## Version 1.5.3: 31 Oct 2000	DB radiator accounting
+##
+## Version 1.5.2: 30 Oct 2000	Bugs---, bugs---, ...
+##
+## Version 1.5.1: 27 Oct 2000	Bugs--, bugs--, ...
+##
+## Version 1.5.0: 27 Oct 2000	Radiator/SQL accounting
+##
+## Version 1.4.1: 26 Oct 2000	on/off on services
+##
+## Version 1.4.0.3: 25 Oct 2000	some bugs crashed
+##
+## Version 1.4.0: 24 Oct 2000	DNS / named added
+##
+## Version 1.3.10: 17 Oct 2000	1 query/5min mechanism
+##
+## Version 1.3.9: 12 Oct 2000	New value: mailq
+##
+## Version 1.2.0: 11 Aug 2000	CAC.Washington.EDU ipop3d logfile added
+##
+## Version 1.1.0: 09 Aug 2000   Merit Radius logfile added
+##
+## Version 1.0.3: 09 Aug 2000   Re-open bug fixed (?)
+##
+## Version 1.0.2: 27 Jul 2000   Changes in SMTP regex
+##
+## Version 1.0.1: 25 Jul 2000   Lots of bugs smashed.
+##
+## Version 1.0.0: 23 Jul 2000	First release. Just SMTP.
+##
+##
+
+##
+## BUGS:
+##      several ?...
+##
+
+##
+## TODO:
+##      more services and diferent logfile reading synchronization
+##      code optimization and cleaning
+##      debugging
+##      can this code be GPLed ??
+##
+
+##
+## LICENSE:
+##         GPL.
+##         (c) 2000 Carlos Canau & Jose Carlos Pereira
+##
+
+##
+## DISCLAIMER:
+##            you use this program at your own and complete risk
+##            if you don't agree with that then delete it
+##
+
+$version = "1.5.5.dist";
+
+#
+# ATTENTION: you might need to edit this variables
+#
+$CAT="/usr/local/bin/cat";
+$ECHO="/usr/local/bin/echo";
+$TOUCH="/usr/local/bin/touch";
+
+$UNAME = "/usr/bin/uname";
+$nodename = `$UNAME -n`;
+chop($nodename);
+
+require 5.004;
+use Fcntl;
+use Getopt::Long;			# option handler
+use POSIX;				# useful functions
+use IO::Handle;
+use IO::File;
+use Sys::Syslog;
+ at PERL_USE_TIME_HIRES@			# import time from Time::HiRes
+					# for nanosecond precision
+
+$log_facility = "user";
+$log_priority = "info";
+
+($progname = $0) =~ s(.*/)();
+
+$SaveDay = 0;
+
+# put this in an option
+#
+# ATTENTION: you might need to edit this
+#
+$MAILQCMD = "/usr/bin/mailq | /usr/bin/tail -1";
+
+##
+## options
+##
+local %options;
+# my $def_poll = 5;
+# my $def_lines = 10;
+# my $def_count = (-1);
+my $def_interval = 300;                     # 5 minutes
+my $def_dns_logfile = "/var/log/named";
+my $def_smtp_logfile = "/var/log/syslog";
+my $def_merit_radius_logfile = "/usr/local/etc/raddb/logfile";
+my $def_pop_logfile = "/var/log/ipop3d.log";
+my $def_outputdir = "/var/orca/orcaservices";
+my $def_pid  = "$def_outputdir/${progname}.pid";
+my $def_compress = "/usr/local/bin/gzip -9";
+
+my $def_radius_auth = "/usr/local/lib/orcaservices.DB.$nodename";
+
+my $def_mailq = "on";
+
+GetOptions("pidfile=s"         => \$options{pidfile},
+           "debug:s"           => \$options{debug},
+           "interval=i"        => \$options{interval},
+           "dns_logfile=s"     => \$options{dns_logfile},
+           "smtp_logfile=s"    => \$options{smtp_logfile},
+           "merit_radius_logfile=s"  => \$options{merit_radius_logfile},
+           "radius_db=s"       => \$options{radius_db},
+           "pop_logfile=s"     => \$options{pop_logfile},
+           "outputdir=s"       => \$options{outputdir},
+	   "compress=s"        => \$options{compress},
+	   "mailq=s"           => \$options{mailq},
+           "help"              => \$options{help},
+           "version"           => \$options{help}
+           ) || usage();
+usage() if $options{help};
+
+if ($options{debug}) {
+    if ($options{debug} ne "on") {
+	$debug = 0;
+	exit if fork;
+    } else {
+	$debug = 1;
+    }
+} else {
+    $debug = 0;
+    exit if fork;
+}
+
+if ($options{interval}) {
+    $interval = $options{interval};
+} else {
+    $interval = $def_interval;
+}
+
+if ($options{compress}) {
+    $Compress = $options{compress};
+} else {
+    $Compress = $def_compress;
+}
+
+if ($options{outputdir}) {
+    $OutputDir = $options{outputdir};
+} else {
+    $OutputDir = $def_outputdir;
+}
+system ("mkdir $OutputDir 2>/dev/null");             # ignore return value
+system ("chmod 0755 $OutputDir 2>/dev/null");        # if you can change these
+                                                     # two systems bye the perl
+                                                     # syscall ... :-)
+system ("mkdir $OutputDir/$nodename 2>/dev/null");   # ignore return value
+system ("chmod 0755 $OutputDir/$nodename 2>/dev/null");
+if ($options{pidfile}) {
+    $PidFile = $options{pidfile};
+} else {
+    $PidFile = "$OutputDir/$nodename/${progname}.pid";;
+}
+
+if ($options{dns_logfile}) {
+    $DNSFile = $options{dns_logfile};
+} else {
+    $DNSFile = $def_dns_logfile;
+}
+
+if ($options{smtp_logfile}) {
+    $SMTPFile = $options{smtp_logfile};
+} else {
+    $SMTPFile = $def_smtp_logfile;
+}
+
+if ($options{mailq}) {
+    $MAILQ = $options{mailq};
+} else {
+    $MAILQ = $def_mailq;
+}
+
+if ($options{merit_radius_logfile}) {
+    $Merit_RADIUSFile = $options{merit_radius_logfile};
+} else {
+    $Merit_RADIUSFile = $def_merit_radius_logfile;
+}
+
+if ($options{pop_logfile}) {
+    $POPFile = $options{pop_logfile};
+} else {
+    $POPFile = $def_pop_logfile;
+}
+
+if ($options{radius_db}) {
+    $RADIUS_DB = $options{radius_db};
+###    print "\n\nWARNING: radius_db option not being used via cmd line. Using default\n\n";
+###    $RADIUS_DB = $def_radius_auth;
+} else {
+    $RADIUS_DB = $def_radius_auth;
+}
+
+##
+## options
+##
+
+
+
+
+&logit ("ready (pid $$)");
+if (open(P, "> $PidFile")) {
+    print P "$$\n";
+    close P;
+} else {
+    &logit("can't save pid (can't write to \`$PidFile')");
+    warn "$progname: can't save pid (can't write to \`$PidFile')\n";
+}
+
+
+
+##
+## init logfiles
+##
+my ($dns_ino, $dns_size, $dns_ok) = (0,0,0);
+if ($DNSFile !~ /^off$/i) {
+    $dns_ok = &init_dns ($DNSFile);                           # inits DNSFD
+}
+
+my ($smtp_ino, $smtp_size, $smtp_ok) = (0,0,0);
+if ($SMTPFile !~ /^off$/i) {
+    $smtp_ok = &init_smtp ($SMTPFile);                        # inits SMTPFD
+}
+
+my ($merit_radius_ino, $merit_radius_size, $merit_radius_ok) = (0,0,0);
+if ($Merit_RADIUSFile !~ /^off$/i) {
+    $merit_radius_ok = &init_merit_radius ($Merit_RADIUSFile);                  # inits RADIUSFD
+}
+
+my ($pop_ino, $pop_size, $pop_ok) = (0,0,0);
+if ($POPFile !~ /^off$/i) {
+    $pop_ok = &init_pop ($POPFile);                           # inits POPFD
+}
+
+if ($RADIUS_DB !~ /^off$/i) {
+
+    #check if database user/passwd is given!
+    if( ! -f $RADIUS_DB){
+        print "Database init error: No such file: $RADIUS_DB\n";
+        print "Aborting\n";
+        exit;
+    }
+
+    my($proto,$drv,$database,$user,$pass)= split(/:/,`$CAT $RADIUS_DB`);
+
+    if(!$proto || !$drv || !$database || !$user || !$pass){
+        print "Database init error: unable to parse $RADIUS_DB\n";
+        print "Syntax must be: protocol:driver:database:user:passwd ex: DBI:oracle:ORCA:user:pass\n";
+        print "Aborting\n";
+        exit;
+    }
+    chomp($pass);
+
+    if ( ($radius_ok = &init_radius("$proto:$drv:$database",$user,$pass)) ) {                      # inits $RADdbh
+        print "ERROR: Radius init failed! Aborting $radius_ok\n";
+        exit;
+    }
+}
+
+$print_header = 0;
+$current_column = 0;
+
+##
+## init outpufile
+##
+my $OutputFilename = "";
+#$outputfile_ok = &check_output ("$OutputDir/$nodename");  # inits OUTFD
+#                                                          # & $OutputFilename
+
+
+# incremental
+if (defined($DNSFD)) {
+    &init_dns_vars ();
+}
+
+while () {
+    my $outputfile_ok = 0;
+    my ($now, $sleep_till);
+
+    $now        = time;
+    $sleep_till = ($now/$interval) * $interval;
+    while ($sleep_till < $now + $interval*0.5) {
+	$sleep_till += $interval;
+    }
+
+    &measure_head ($now);
+
+    if (defined($SMTPFD)) {
+	&init_smtp_vars ();
+    }
+    if ($MAILQ eq "on") {
+	&init_mailq_vars ();
+    }
+    if (defined($Merit_RADIUSFD)) {
+	&init_merit_radius_vars ();
+    }
+    if (defined($POPFD)) {
+	&init_pop_vars ();
+    }
+
+    ### call the measure routines...
+    &measure ($sleep_till);
+
+    if (defined($RADdbh)) {
+	&put_radius ();
+    }
+
+    if (defined($DNSFD)) {
+	&put_dns ();
+    }
+    if (defined($SMTPFD)) {
+	&put_smtp ();
+    }
+    if ($MAILQ eq "on") {
+	&put_mailq ();
+    }
+    if (defined($Merit_RADIUSFD)) {
+	&put_merit_radius ();
+    }
+    if (defined($POPFD)) {
+	&put_pop ();
+    }
+
+    $outputfile_ok = &check_output ("$OutputDir/$nodename");
+
+    &flush_output ();
+
+}
+
+exit 0;
+
+
+
+# ----------------------------------------------------------------------------
+
+sub usage {
+    die "Usage: $progname [options]
+    ($progname uses the GNU extended POSIX option format)
+
+    --pidfile=FILE        write my PID here           (default: $def_pid)
+    --debug[=on|off]      show copious debugging info (default: off)
+    --interval=i          pooling interval in sec.    (default: $def_interval)
+    --dns_logfile=FILE    syslog from named           (default: $def_dns_logfile)
+    --smtp_logfile=FILE   syslog from sendmail        (default: $def_smtp_logfile)
+    --merit_radius_logfile=FILE syslog from merit_radius          (default: $def_merit_radius_logfile)
+    --radius_db=FILE      file for user/passwd for DB access (default: $def_radius_auth)
+    --pop_logfile=FILE    syslog from pop             (default: $def_pop_logfile)
+    --outputdir=DIR       write here output files     (default: $def_outputdir)
+    --compress=COMMAND    use this to compress files  (default: $def_compress)
+    --mailq=[on|off]      get mailq total requests    (default: $def_mailq)
+    --help, --version this option summary
+
+    Note: use filename 'off' to turn off the specific service
+
+    This is $progname version $version
+
+";
+}
+
+
+# -------------------------------------------------------------------
+#
+# logit -- send MSG(s) to the syslog.
+#
+# usage: &logit($msg_to_log);
+#
+
+sub logit {
+    local($Msg) = @_;
+
+    &Sys::Syslog::openlog("$progname", 'cons,pid', "$log_facility");
+    &Sys::Syslog::syslog("$log_priority", $Msg);
+    &Sys::Syslog::closelog();
+}
+
+
+# -------------------------------------------------------------------
+#
+# measure_head -- put first values
+#
+# usage: &measure_head($time)
+#
+
+sub measure_head() {
+    my ($time) = @_;
+
+    $now_string = strftime "%T", localtime;
+    put_output(" timestamp", sprintf("%10d", $time));
+    put_output("locltime", $now_string);
+}
+
+
+# ----------------------------------------------------------------------
+#
+# init_radius - set RADIATOR_RADIUS vars, connect to DB, calculate correct time stamp
+#
+# usage: &init_radius($db,$user,$pass);
+#
+
+sub init_radius {
+  my ($db,$user,$pass) = @_;
+
+    use DBI;
+
+    $RADdbh   = DBI->connect($db,$user,$pass);
+    if(!$RADdbh) {
+        print "Connect error $DBI::errstr\n";
+        return 1;
+    }
+
+    #get the lower time limit that our queries will start from
+    #get a "history" of 5minutes
+
+    $radius_base_ts= time - 5*60;
+
+    #get accumulated values for what we want to measure:
+
+#jcp correct this please!
+##    my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, undef) = localtime($radius_base_ts);
+##    $year += 1900;
+##    $mon++;
+
+
+##    $BASE_ACCUM_radius_DB="/var/orca/orcaservices/$nodename";
+##    $ACCUM_radius_DB= "$BASE_ACCUM_radius_DB/radiatorRadiusAccum.$year$mon.txt";
+##    `$TOUCH $ACCUM_radius_DB`;
+
+##    $radius_inc_time       ||= 0;
+##    $radius_inc_sessions   ||= 0;
+
+#END jcp correct this please!
+
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# init_dns - set DNS vars, open the logfile and seek into the end.
+#
+# usage: &init_dns($dns_logfile);
+#
+
+sub init_dns {
+    my ($filename) = @_;
+
+    if ($filename) {
+	$DNSFD = new IO::File "$filename", "r";
+	if (defined($DNSFD)) {
+	    my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+		$atime,$mtime,$ctime,$blksize,$blocks) = stat($DNSFD);
+	    if (!$dev) {
+		&logit ("can't stat $filename");
+		warn "$progname: can't stat $filename\n";
+		return 1;
+	    }
+	    $dns_ino = $ino;
+	    $dns_size = $size;
+	    $seek_ok = seek($DNSFD, 0, SEEK_END);
+	    if (!$seek_ok) {
+		&logit ("can't seek into EOF on $filename");
+		warn "$progname: can't seek into EOF on $filename\n";
+		return 2;
+	    }
+	} else {
+	    &logit ("can't open $filename");
+	    warn "$progname: can't open $filename\n";
+	    return 3;
+	}
+    }
+    &init_dns_vars ();
+    return 0;
+}
+
+# -------------------------------------------------------------------
+#
+# init_smtp - set SMTP vars, open the logfile and seek into the end.
+#
+# usage: &init_smtp($smtp_logfile);
+#
+
+sub init_smtp {
+    my ($filename) = @_;
+
+    if ($filename) {
+	$SMTPFD = new IO::File "$filename", "r";
+	if (defined($SMTPFD)) {
+	    my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+		$atime,$mtime,$ctime,$blksize,$blocks) = stat($SMTPFD);
+	    if (!$dev) {
+		&logit ("can't stat $filename");
+		warn "$progname: can't stat $filename\n";
+		return 1;
+	    }
+	    $smtp_ino = $ino;
+	    $smtp_size = $size;
+	    $seek_ok = seek($SMTPFD, 0, SEEK_END);
+	    if (!$seek_ok) {
+		&logit ("can't seek into EOF on $filename");
+		warn "$progname: can't seek into EOF on $filename\n";
+		return 2;
+	    }
+	} else {
+	    &logit ("can't open $filename");
+	    warn "$progname: can't open $filename\n";
+	    return 3;
+	}
+    }
+    &init_smtp_vars ();
+    return 0;
+}
+
+
+# ----------------------------------------------------------------------
+#
+# init_merit_radius - set Merit_RADIUS vars, open the logfile and seek into the end.
+#
+# usage: &init_merit_radius($radius_logfile);
+#
+
+sub init_merit_radius {
+    my ($filename) = @_;
+
+    if ($filename) {
+	$Merit_RADIUSFD = new IO::File "$filename", "r";
+	if (defined($Merit_RADIUSFD)) {
+	    my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+		$atime,$mtime,$ctime,$blksize,$blocks) = stat($Merit_RADIUSFD);
+	    if (!$dev) {
+		&logit ("can't stat $filename");
+		warn "$progname: can't stat $filename\n";
+		return 1;
+	    }
+	    $merit_radius_ino = $ino;
+	    $merit_radius_size = $size;
+	    $seek_ok = seek($Merit_RADIUSFD, 0, SEEK_END);
+	    if (!$seek_ok) {
+		&logit ("can't seek into EOF on $filename");
+		warn "$progname: can't seek into EOF on $filename\n";
+		return 2;
+	    }
+	} else {
+	    &logit ("can't open $filename");
+	    warn "$progname: can't open $filename\n";
+	    return 3;
+	}
+    }
+    &init_merit_radius_vars ();
+    return 0;
+}
+
+
+# ----------------------------------------------------------------------
+#
+# init_pop - set POP vars, open the logfile and seek into the end.
+#
+# usage: &init_pop($pop_logfile);
+#
+
+sub init_pop {
+    my ($filename) = @_;
+
+    if ($filename) {
+	$POPFD = new IO::File "$filename", "r";
+	if (defined($POPFD)) {
+	    my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+		$atime,$mtime,$ctime,$blksize,$blocks) = stat($POPFD);
+	    if (!$dev) {
+		&logit ("can't stat $filename");
+		warn "$progname: can't stat $filename\n";
+		return 1;
+	    }
+	    $pop_ino = $ino;
+	    $pop_size = $size;
+	    $seek_ok = seek($POPFD, 0, SEEK_END);
+	    if (!$seek_ok) {
+		&logit ("can't seek into EOF on $filename");
+		warn "$progname: can't seek into EOF on $filename\n";
+		return 2;
+	    }
+	} else {
+	    &logit ("can't open $filename");
+	    warn "$progname: can't open $filename\n";
+	    return 3;
+	}
+    }
+    &init_pop_vars ();
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# check_output - set outputfile vars, open the outputfile.
+#
+# usage: &check_output($outputdir);
+#
+
+sub check_output {
+    my ($outputdir) = @_;
+    $sec1=$min1=$hour1=$mday1=$mon1=$year1=$wday1=$yday1=$isdst1 = 0;
+
+    ($sec1,$min1,$hour1,$mday1,$mon1,$year1,$wday1,$yday1,$isdst1) = localtime();
+
+    if ($mday1 != $SaveDay) {
+	# First time or day has changed, start new logfile.
+	if (OUTFD->opened) {
+	    close(OUTFD);                            # ignore error
+	}
+	if (($Compress) && ($SaveDay)) {             # just on day change
+	    if ($OutputFilename) {
+		&logit ("compressing $OutputFilename");
+		system ("$Compress $OutputFilename");  # ignore error ??
+	    }
+	}
+
+	$now_string = strftime "%Y-%m-%d", localtime;
+
+	$OutputFilename = "$outputdir/percol-$now_string";
+
+        if (!open (OUTFD, ">>$OutputFilename")) {
+	    &logit ("can't open outputfile $OutputFilename");
+	    die "$progname: can't open outputfile $OutputFilename\n";
+	}
+
+	$SaveDay = $mday1;
+
+	$print_header = 1;
+    }
+
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# flush_output - dumps line into outputfile
+#
+# usage: &flush_output();
+#
+
+sub flush_output() {
+
+    if ($print_header) {
+	&print_columns(\@col_comment);
+	$print_header = 0;
+    }
+    &print_columns(\@col_data);
+    $current_column = 0;
+}
+
+# -------------------------------------------------------------------
+#
+# Send the stored columns of information to the output.
+#
+# usage: &print_columns( \@array );
+#
+
+sub print_columns() {
+    my ($ref) = @_;
+
+    @col = @$ref;
+
+    for ($i=0; $i < $current_column; $i++) {
+	printf OUTFD "%s", $col[$i];
+	if ($i != $current_column - 1) {
+	    printf OUTFD " ";
+	}
+    }
+    printf OUTFD "\n";
+
+    OUTFD->flush;
+}
+
+# -------------------------------------------------------------------
+#
+# Add one column of comments and data to the buffers.
+#
+# usage: &put_output( $comment, $data );
+#
+
+sub put_output() {
+    my ($comment, $data) = @_;
+
+    printf "OUT: --%s-- %s\n", $comment, $data if $debug;
+    $col_comment[$current_column] = $comment;
+    $col_data[$current_column]    = $data;
+    $current_column++;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Cycle several measurables
+#
+# usage: &measure( $sleep_till );
+#
+
+sub measure () {
+    my ($sleep_till) = @_;
+
+
+    $now = time;
+    while ($now < $sleep_till) {
+
+        printf "SMTP: sleeping for 5\n" if $debug;
+        sleep(5);
+        $now = time;
+
+	# measure...
+	if (defined($SMTPFD)) {
+	    &measure_smtp();
+	}
+	if (defined($Merit_RADIUSFD)) {
+	    &measure_merit_radius();
+	}
+	if (defined($POPFD)) {
+	    &measure_pop();
+	}
+	#
+	# stats only once an hour... but better not have logfile reading picks
+	#
+	if (defined($DNSFD)) {
+	    &measure_dns();
+	}
+
+	# measure...
+
+	$now = time;
+
+    } ## while ($now < $sleep_till)
+    # put in the end... calls external prog.
+    if ($MAILQ eq "on") {
+	&measure_mailq();
+    }
+
+    if (defined($RADdbh)) {
+        &measure_radius();
+    }
+
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Get values for smtp columns
+#
+# usage: &measure_smtp( );
+#
+
+sub measure_smtp () {
+
+
+    #################################### insert bail out for too much
+    #################################### time spent ??
+    $buf = <$SMTPFD>;
+    while ($buf) {
+	## process line read and check for eof
+	if ($buf) {
+	    &process_smtp_line ($buf);
+	}
+	if ($SMTPFD->eof) {
+	    printf "SMTP: eof on $SMTPFile\n" if $debug;
+	    last; # get out of while($buf)
+	}
+	$buf = <$SMTPFD>;
+    } ## while ($buf)
+
+
+    # test for file change via different inode or filesize decrease
+    $dev = $ino = $mode = $nlink = $uid = $gid = $rdev =
+	$size = $atime = $mtime = $ctime = $blksize = $blocks = '';
+    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+     $atime,$mtime,$ctime,$blksize,$blocks) = stat($SMTPFile);
+    if (!$dev) {
+	&logit ("can't stat $SMTPFile");
+	warn "$progname: can't stat $SMTPFile\n";
+	return 1;
+    }
+    printf "SMTPFD: smtp_ino=%s vs. ino=%s\tsmtp_size=%s vs. size=%s\n", $smtp_ino, $ino, $smtp_size, $size if $debug;
+    if (($smtp_ino != $ino) || ($smtp_size > $size)) {
+	undef $SMTPFD;
+	printf "SMTP: file change on $SMTPFile\n" if $debug;
+	$SMTPFD = new IO::File "$SMTPFile", "r";
+	if (!defined ($SMTPFD)) {
+	    &logit ("can't re-open $SMTPFile");
+	    warn "$progname: can't re-open $SMTPFile\n";
+	    $smtp_ino = $smtp_size = 0;
+	    return 2;
+	}
+	$smtp_ino = $ino;
+	$smtp_size = $size;
+    }
+
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# init smtp vars
+#
+# usage: &init_smtp_vars();
+#
+
+sub init_smtp_vars() {
+    $smtp_froms      = 0;
+    $smtp_MaxSize    = 0;
+    $smtp_sizes      = 0;
+
+    $smtp_MaxSeconds = 0;
+    $smtp_seconds    = 0;
+    $smtp_sent       = 0;
+
+    $smtp_fail       = 0;
+    $smtp_retries    = 0;
+    $smtp_queued     = 0;
+    $smtp_t_or_f     = 0;
+
+    $smtp_check_mail = 0;
+    $smtp_check_rcpt = 0;
+    $smtp_notifies   = 0;
+    $smtp_dsns       = 0;
+    $smtp_undefs     = 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Parse smtp log line
+#
+# usage: &process_smtp_line ($buf);
+#
+
+sub process_smtp_line () {
+    my ($line) = @_;
+
+
+    if ($line !~ / sendmail\[\d+\]: /) {
+	return 0;
+    }
+
+
+    # from
+# Jul 16 03:22:12 server123 sendmail[4977]: e6G2M7O04977: from=<jsmith at server321.domain.com>, size=981, class=0, nrcpts=1, msgid=<200007152000.VAA24441 at server321.domain.com>, proto=ESMTP, daemon=MTA, relay=server321.domain.com [10.0.0.65]
+#   0 Month, 1 Day, 2 hh:mm:ss, 3 nodename, 4 sendmail[NNNNN]:, 5 msg-id:, 6 from=FROM\,, 7 size=NNNNN\,, ...
+    if ($line =~ /: from=.*, size=(\d+)/i) {
+	$smtp_froms ++;
+	$size = $1;
+	$smtp_sizes += $size;
+	if ($size > $smtp_MaxSize) {
+	    $smtp_MaxSize = $size;
+	}
+	printf "SMTP_FROM: %s", $line if $debug;
+#	printf "smtp_froms=%s, size=%s, smtp_sizes=%s, smtp_MaxSize=%s\n", $smtp_froms, $size, $smtp_sizes, $smtp_MaxSize if $debug;
+	return 0;
+    }
+
+    # to
+#Jul 16 03:26:32 server123 sendmail[5060]: e6G2PqO05058: to=<info at domain1.pt>, delay=00:00:35, xdelay=00:00:35, mailer=esmtp, pri=120745, relay=server321.domain.com. [10.0.0.65], dsn=2.0.0, stat=Sent (DAA19487 Message accepted for delivery)
+#Jul 16 03:15:16 server123 sendmail[4828]: e6EBXrO12616: to=<sales at mail.domain2.pt>, delay=1+14:41:13, xdelay=00:00:55, mailer=esmtp, pri=3001977, relay=mail.domain2.pt. [11.0.0.130], dsn=4.0.0, stat=Deferred: Connection refused by mail.domain2.pt.
+#Jul 16 22:31:20 server123 sendmail[881]: e6GLUxP00881: to=<info at domain3.pt>, delay=00:00:11, xdelay=00:00:11, mailer=esmtp, pri=37973, relay=mail.domain4.pt. [12.0.0.15], dsn=5.0.0, stat=Service unavailable
+#Jul 24 18:33:05 server999 sendmail[15932]: SAA15929: to=<jsmith at domain4.pt>, ctladdr=<jjjj at domain9.pt> (16306/1984), delay=00:00:10, xdelay=00:00:09, mailer=esmtp, relay=mail.domain4.pt. [13.0.0.3], stat=Sent (Ok)
+    if ($line =~ /: to=/) {
+	if ($line =~ /, delay=(\d+)*\+*(\d+):(\d+):(\d+), .*, stat=Sent/i) {
+	    $seconds = 86400*$1 + 3600*$2 + 60*$3 + $4;
+
+	    $smtp_seconds += $seconds;
+	    if ($seconds > $smtp_MaxSeconds) {
+		$smtp_MaxSeconds = $seconds;
+	    }
+	    $smtp_sent ++;
+	    printf "SMTP_SENT: %s", $line if $debug;
+#	    printf "seconds=%s, smtp_seconds=%s, smtp_MaxSeconds=%s, smtp_sent=%s\n", $seconds, $smtp_seconds, $smtp_MaxSeconds, $smtp_sent if $debug;
+	    return 0;
+	}
+	if ($line =~ /, dsn=5/i) {
+	    $smtp_fail++;
+	    printf "SMTP_FAIL: %s", $line if $debug;
+#	    printf "smtp_fail=%s\n", $smtp_fail if $debug;
+	    return 0;
+	}
+	if (($line =~ /, dsn=4/i) || ($line =~ /, stat=Deferred:/i)) {
+	    $smtp_retries++;
+	    printf "SMTP_RETRY: %s", $line if $debug;
+#	    printf "smtp_retries=%s\n", $smtp_retries if $debug;
+	    return 0;
+	}
+	if ($line =~ /, stat=queued/i) {
+	    $smtp_queued++;
+	    printf "SMTP_QUEUE: %s", $line if $debug;
+#	    printf "smtp_queued=%s\n", $smtp_queued if $debug;
+	    return 0;
+	}
+	$smtp_t_or_f++;
+	printf "SMTP_T_OR_F: %s", $line if $debug;
+#	printf "smtp_t_or_f=%s\n", $smtp_t_or_f if $debug;
+	return 0;
+    }
+
+    # ruleset=check_mail
+#Jul 16 22:24:43 server123 sendmail[604]: e6GLNMO00604: ruleset=check_mail, arg1=<Mary.Wilson at domain10.pt>, relay=server321.domain.com [10.0.0.65], reject=451 4.1.8 <Mary.Wilson at domain10.pt>... Domain of sender address Mary.Wilson at domain10.pt does not resolve
+    if ($line =~ /: ruleset=check_mail, /i) {
+	$smtp_check_mail ++;
+	printf "SMTP_CHECK_MAIL: %s", $line if $debug;
+#	printf "smtp_check_mail=%s\n", $smtp_check_mail if $debug;
+	return 0;
+    }
+
+    # ruleset=check_rcpt
+#Jul 19 16:54:55 server123 sendmail[11437]: e6JFsoO11437: ruleset=check_rcpt, arg1=<xyz at domain777.net>, relay=a.b.c.net [6.1.6.7], reject=550 5.7.1 <xyz at domain777.net>... Relaying denied
+#Jul 19 17:34:54 server123 sendmail[12479]: e6JGYKO12479: ruleset=check_rcpt, arg1=<Edgar.Silva at mail.soso.domain8888.pt>, relay=individual [10.0.0.67], reject=450 4.7.1 <Edgar.Silva at mail.soso.domain8888.pt>... Can not check MX records for recipient host mail.soso.domain8888.pt
+    if ($line =~ /: ruleset=check_rcpt, /i) {
+	$smtp_check_rcpt ++;
+	printf "SMTP_CHECK_RCPT: %s", $line if $debug;
+#	printf "smtp_check_rcpt=%s\n", $smtp_check_rcpt if $debug;
+	return 0;
+    }
+
+    # postmaster notify:
+#Jul 17 05:30:04 server123 sendmail[10016]: e6EKWRO24933: e6H401o10016: postmaster notify: Cannot send message within 2 days
+    if ($line =~ /: postmaster notify: /i) {
+	$smtp_notifies ++;
+	printf "SMTP_NOTIFIES: %s", $line if $debug;
+#	printf "smtp_notifies=%s\n", $smtp_notifies if $debug;
+	return 0;
+    }
+
+    # DSN
+#Jul 18 22:28:58 server123 sendmail[7172]: e6ILQlO07170: e6ILSwO07172: DSN: Service unavailable
+#Jul 19 14:38:00 server123 sendmail[1846]: e6HBWSO21997: e6JDU0t01846: DSN: Cannot send message within 2 days
+#Jul 19 17:33:51 server123 sendmail[12272]: e6JGTlO12270: e6JGXpO12272: DSN: Return receipt
+    if ($line =~ /: DSN: /i) {
+	$smtp_dsns ++;
+	printf "SMTP_DSN: %s", $line if $debug;
+#	printf "smtp_dsns=%s\n", $smtp_dsns if $debug;
+	return 0;
+    }
+
+    $smtp_undefs ++;
+    printf "SMTP_UNDEF: %s", $line if $debug;
+#    printf "smtp_undefs=%s\n", $smtp_undefs if $debug;
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Put the smtp values for output
+#
+# usage: &put_smtp();
+#
+
+sub put_smtp() {
+
+    &put_output("smtp_from",  sprintf("%8.2f", $smtp_froms));
+    &put_output("smtp_tops",  sprintf("%8.2f", $smtp_MaxSize));
+    if ($smtp_froms) {
+	&put_output("smtp_sizes",  sprintf("%8.2f", $smtp_sizes/$smtp_froms));
+    } else {
+	&put_output("smtp_sizes",  sprintf("%8.2f", 0));
+    }
+    &put_output("smtp_sent",  sprintf("%8.2f", $smtp_sent));
+    &put_output("smtp_maxd",  sprintf("%8.2f", $smtp_MaxSeconds));
+    if ($smtp_sent) {
+	&put_output("smtp_delay", sprintf("%8.2f", $smtp_seconds/$smtp_sent));
+    } else {
+	&put_output("smtp_delay", sprintf("%8.2f", 0));
+    }
+    &put_output("smtp_fail",  sprintf("%8.2f", $smtp_fail));
+    &put_output("smtp_rtrs",  sprintf("%8.2f", $smtp_retries));
+    &put_output("smtp_queued",  sprintf("%8.2f", $smtp_queued));
+    &put_output("smtp_torf",  sprintf("%8.2f", $smtp_t_or_f));
+    &put_output("smtp_c_ml",  sprintf("%8.2f", $smtp_check_mail));
+    &put_output("smtp_c_rt",  sprintf("%8.2f", $smtp_check_rcpt));
+    &put_output("smtp_ntfs",  sprintf("%8.2f", $smtp_notifies));
+    &put_output("smtp_dsns",  sprintf("%8.2f", $smtp_dsns));
+
+    &put_output("smtp_undf",  sprintf("%8.2f", $smtp_undefs));
+
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Get values for mailq columns
+#
+# usage: &measure_mailq( );
+#
+
+sub measure_mailq () {
+
+    open (MFD, "$MAILQCMD |");
+    $line = <MFD>;
+    close (MFD);
+
+    if ($line =~ /(\d+)/i) {
+	$mailq_t = $1;
+    } else {
+	$mailq_t = 0;
+    }
+    $mailq_total += $mailq_t;
+
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# init mailq vars
+#
+# usage: &init_mailq_vars();
+#
+
+sub init_mailq_vars() {
+    $mailq_total      = 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Put the mailq values for output
+#
+# usage: &put_mailq();
+#
+
+sub put_mailq() {
+
+    &put_output("mailq_total",  sprintf("%8.2f", $mailq_total));
+
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# init merit_radius vars
+#
+# usage: &init_merit_radius_vars();
+#
+
+sub init_merit_radius_vars() {
+    $merit_radius_auth          = 0;
+    $merit_radius_auth_ok       = 0;
+    $merit_radius_auth_nok      = 0;
+
+    $merit_radius_acct_start    = 0;
+    $merit_radius_acct_stop     = 0;
+
+    $merit_radius_rem_auth      = 0;
+    $merit_radius_rem_auth_ok   = 0;
+    $merit_radius_rem_auth_nok  = 0;
+
+    $merit_radius_undefs        = 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Get values for merit_radius columns
+#
+# usage: &measure_merit_radius( );
+#
+
+sub measure_merit_radius () {
+
+
+    #################################### insert bail out for too much
+    #################################### time spent ??
+    $buf = <$Merit_RADIUSFD>;
+    while ($buf) {
+	## process line read and check for eof
+	if ($buf) {
+	    &process_merit_radius_line ($buf);
+	}
+	if ($Merit_RADIUSFD->eof) {
+	    printf "Merit_RADIUS: eof on $Merit_RADIUSFile\n" if $debug;
+	    last; # get out of while($buf)
+	}
+	$buf = <$Merit_RADIUSFD>;
+    } ## while ($buf)
+
+
+    # test for file change via different inode or filesize decrease
+    $dev = $ino = $mode = $nlink = $uid = $gid = $rdev =
+	$size = $atime = $mtime = $ctime = $blksize = $blocks = '';
+    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+     $atime,$mtime,$ctime,$blksize,$blocks) = stat($Merit_RADIUSFile);
+    if (!$dev) {
+	&logit ("can't stat $Merit_RADIUSFile");
+	warn "$progname: can't stat $Merit_RADIUSFile\n";
+	return 1;
+    }
+    printf "Merit_RADIUSFD: merit_radius_ino=%s vs. ino=%s\tmerit_radius_size=%s vs. size=%s\n", $merit_radius_ino, $ino, $merit_radius_size, $size if $debug;
+    if (($merit_radius_ino != $ino) || ($merit_radius_size > $size)) {
+	undef $Merit_RADIUSFD;
+	printf "Merit_RADIUS: file change on $Merit_RADIUSFile\n" if $debug;
+	$Merit_RADIUSFD = new IO::File "$Merit_RADIUSFile", "r";
+	if (!defined ($Merit_RADIUSFD)) {
+	    &logit ("can't re-open $Merit_RADIUSFile");
+	    warn "$progname: can't re-open $Merit_RADIUSFile\n";
+	    $merit_radius_ino = $merit_radius_size = 0;
+	    return 2;
+	}
+	$merit_radius_ino = $ino;
+	$merit_radius_size = $size;
+    }
+
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Parse merit_radius log line
+#
+# usage: &process_merit_radius_line ($buf);
+#
+
+sub process_merit_radius_line () {
+    my ($line) = @_;
+
+
+### AUTH RECEIVED
+# Mon Jul 24 00:02:16 2000: Received-Authentication: 214/28832 'luser' from 13.12.15.17 port 25 PPP
+
+    if ($line =~ /: Received-Authentication: .* from /i) {
+	$merit_radius_auth ++;
+	printf "Merit_RADIUS_AUTH: %s", $line if $debug;
+	printf "merit_radius_auth=%s\n", $merit_radius_auth if $debug;
+	return 0;
+    }
+
+### AUTH OK
+# Mon Jul 24 00:02:16 2000: Authentication: 214/28832 'luser2' from 13.12.25.17 port 35 PPP - OK -- total 0, holding 0
+
+    if ($line =~ /: Authentication: .* from .* OK /i) {
+	$merit_radius_auth_ok ++;
+	printf "Merit_RADIUS_AUTH_OK: %s", $line if $debug;
+	printf "merit_radius_auth_ok=%s\n", $merit_radius_auth_ok if $debug;
+	return 0;
+    }
+
+### AUTH FAILED
+# Mon Jul 24 01:49:20 2000: Authentication: 201/29347 'luser3' from 13.16.19.20 port 2 PPP - FAILED Authentication failure -- total 0, holding 0
+
+    if ($line =~ /: Authentication: .* from .* FAILED Authentication /i) {
+	$merit_radius_auth_nok ++;
+	printf "Merit_RADIUS_AUTH_NOK: %s", $line if $debug;
+	printf "merit_radius_auth_nok=%s\n", $merit_radius_auth_nok if $debug;
+	return 0;
+    }
+
+### ACCT START RECEIVED
+# Mon Jul 24 00:02:16 2000: Received-Accounting: 215/8376 'luser4' from 13.16.15.17 port 35 $"5200DB70" PPP/13.16.19.25 Start
+### ACCT STOP RECEIVED
+# Mon Jul 24 00:02:19 2000: Received-Accounting: 176/8377 'luser5' from 13.16.11.18 port 1 $"040065AE" PPP/13.16.24.22 Stop/User-Request
+# Wed Aug  9 16:55:15 2000: getpwnam: good line for luser6 on file
+    if ( ($line =~ /: Received-Accounting: .* from /i) ||
+	 ($line =~ /: getpwnam: good line for /i) ){
+	printf "Merit_RADIUS_IGNORE: %s", $line if $debug;
+	return 0;
+    }
+
+### ACCT START OK
+# Mon Jul 24 00:02:16 2000: Accounting: 215/8376 'luser6' from 13.16.15.17 port 35 $"5200DB70" PPP/13.16.19.24 Start - OK -- total 0, holding 0
+
+    if ($line =~ /: Accounting: .* from .* Start - OK /i) {
+	$merit_radius_acct_start ++;
+	printf "Merit_RADIUS_ACCT_START: %s", $line if $debug;
+	printf "merit_radius_acct_start=%s\n", $merit_radius_acct_start if $debug;
+	return 0;
+    }
+
+### ACCT STOP OK
+# Mon Jul 24 00:02:19 2000: Accounting: 176/8377 'luser7' from 13.16.11.18 port 1 $"040065AE" PPP/13.16.24.22 Stop/User-Request - OK -- total 0, holding 0
+
+    if ($line =~ /: Accounting: .* from .* Stop.* OK /i) {
+	$merit_radius_acct_stop ++;
+	printf "Merit_RADIUS_ACCT_STOP: %s", $line if $debug;
+	printf "merit_radius_acct_stop=%s\n", $merit_radius_acct_stop if $debug;
+	return 0;
+    }
+
+### REMOTE AUTH RECEIVED
+# Mon Jul 24 20:53:38 2000: Received-AUTHENTICATE: 167/44566 'luser9 at realm.com' via some.host.com from some.nas.com port 6 PPP
+
+    if ($line =~ /: Received-AUTHENTICATE: .* via .* from /i) {
+	$merit_radius_rem_auth ++;
+	printf "Merit_RADIUS_REM_AUTH: %s", $line if $debug;
+	printf "merit_radius_rem_auth=%s\n", $merit_radius_rem_auth if $debug;
+	return 0;
+    }
+
+### REMOTE AUTH OK
+# Mon Jul 24 20:53:38 2000: AUTHENTICATE: 167/44566 'luser9 at realm.com' via some.host.com from some.nas.com port 6 PPP - OK -- total 0, holding 0
+
+    if ($line =~ /: AUTHENTICATE: .* via .* from .* OK /i) {
+	$merit_radius_rem_auth_ok ++;
+	printf "Merit_RADIUS_REM_AUTH_OK: %s", $line if $debug;
+	printf "merit_radius_rem_auth_ok=%s\n", $merit_radius_rem_auth_ok if $debug;
+	return 0;
+    }
+
+### REMOTE AUTH FAILED
+# Mon Jul 24 14:05:56 2000: AUTHENTICATE: 230/37578 'luser9 at realm.com' via some.host.com from i-Pass VNAS\0\0\0\0 port 1 - FAILED Authentication failure -- total 0, holding 0
+
+    if ($line =~ /: AUTHENTICATE: .* via .* from .* FAILED Authentication /i) {
+	$merit_radius_rem_auth_nok ++;
+	printf "Merit_RADIUS_REM_AUTH_NOK: %s", $line if $debug;
+	printf "merit_radius_rem_auth_nok=%s\n", $merit_radius_rem_auth_nok if $debug;
+	return 0;
+    }
+
+
+    $merit_radius_undefs ++;
+    printf "Merit_RADIUS_UNDEF: %s", $line if $debug;
+    printf "merit_radius_undefs=%s\n", $merit_radius_undefs if $debug;
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Put the merit_radius values for output
+#
+# usage: &put_merit_radius();
+#
+
+sub put_merit_radius() {
+
+    &put_output("merit_radius_auth",  sprintf("%8.2f", $merit_radius_auth));
+    &put_output("merit_radius_auth_ok",  sprintf("%8.2f", $merit_radius_auth_ok));
+    &put_output("merit_radius_auth_nok",  sprintf("%8.2f", $merit_radius_auth_nok));
+    &put_output("merit_radius_acct_start",  sprintf("%8.2f", $merit_radius_acct_start));
+    &put_output("merit_radius_acct_stop",  sprintf("%8.2f", $merit_radius_acct_stop));
+    &put_output("merit_radius_rem_auth",  sprintf("%8.2f", $merit_radius_rem_auth));
+    &put_output("merit_radius_rem_auth_ok",  sprintf("%8.2f", $merit_radius_rem_auth_ok));
+    &put_output("merit_radius_rem_auth_nok",  sprintf("%8.2f", $merit_radius_rem_auth_nok));
+
+    &put_output("merit_radius_undefs",  sprintf("%8.2f", $merit_radius_undefs));
+
+    return 0;
+}
+
+
+
+# -------------------------------------------------------------------
+#
+# init pop vars
+#
+# usage: &init_pop_vars();
+#
+
+sub init_pop_vars() {
+    $pop_connect      = 0;
+    $pop_login        = 0;
+    $pop_logout       = 0;
+
+    $pop_failure      = 0;
+    $pop_refused      = 0;
+
+    $pop_net_error    = 0;
+    $pop_local_error  = 0;
+
+    $pop_undefs       = 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Get values for pop columns
+#
+# usage: &measure_pop( );
+#
+
+sub measure_pop () {
+
+
+    #################################### insert bail out for too much
+    #################################### time spent ??
+    $buf = <$POPFD>;
+    while ($buf) {
+	## process line read and check for eof
+	if ($buf) {
+	    &process_pop_line ($buf);
+	}
+	if ($POPFD->eof) {
+	    printf "POP: eof on $POPFile\n" if $debug;
+	    last; # get out of while($buf)
+	}
+	$buf = <$POPFD>;
+    } ## while ($buf)
+
+
+    # test for file change via different inode or filesize decrease
+    $dev = $ino = $mode = $nlink = $uid = $gid = $rdev =
+	$size = $atime = $mtime = $ctime = $blksize = $blocks = '';
+    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+     $atime,$mtime,$ctime,$blksize,$blocks) = stat($POPFile);
+    if (!$dev) {
+	&logit ("can't stat $POPFile");
+	warn "$progname: can't stat $POPFile\n";
+	return 1;
+    }
+    printf "POPFD: pop_ino=%s vs. ino=%s\tpop_size=%s vs. size=%s\n", $pop_ino, $ino, $pop_size, $size if $debug;
+    if (($pop_ino != $ino) || ($pop_size > $size)) {
+	undef $POPFD;
+	printf "POP: file change on $POPFile\n" if $debug;
+	$POPFD = new IO::File "$POPFile", "r";
+	if (!defined ($POPFD)) {
+	    &logit ("can't re-open $POPFile");
+	    warn "$progname: can't re-open $POPFile\n";
+	    $pop_ino = $pop_size = 0;
+	    return 2;
+	}
+	$pop_ino = $ino;
+	$pop_size = $size;
+    }
+
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Parse pop log line
+#
+# usage: &process_pop_line ($buf);
+#
+
+sub process_pop_line () {
+    my ($line) = @_;
+
+
+    if ($line !~ / ipop3d\[\d+\]: /) {
+        return 0;
+    }
+
+### connect
+# Aug 11 07:01:50 host1 ipop3d[13929]: connect from 14.5.8.10
+
+    if ($line =~ /: connect from /i) {
+	$pop_connect ++;
+	printf "POP_CONNECT: %s", $line if $debug;
+	printf "pop_connect=%s\n", $pop_connect if $debug;
+	return 0;
+    }
+
+### login + auth
+# Aug 11 07:01:57 host1 ipop3d[13928]: Login user=luser2 host=host.domain.pt [13.16.6.27] nmsgs=0/0
+# Aug 11 07:02:06 host1 ipop3d[13936]: Auth user=luser3 host=2-4-4.domain.pt [13.16.2.18] nmsgs=0/0
+
+    if ( ($line =~ /: Login user=/i) ||
+	 ($line =~ /: Auth user=/i) ) {
+	$pop_login ++;
+	printf "POP_LOGIN: %s", $line if $debug;
+	printf "pop_login=%s\n", $pop_login if $debug;
+	return 0;
+    }
+
+### logout
+# Aug 11 07:01:50 host1 ipop3d[13929]: Logout user=luser4 host=[14.6.8.10] nmsgs=0 ndele=0
+# Aug 11 11:20:24 host1 ipop3d[1866]: Autologout user=luser5 host=3-0-0.domain.pt [13.16.1.18]
+
+    if ($line =~ /: .*[lL]ogout user=/i) {
+	$pop_logout ++;
+	printf "POP_LOGOUT: %s", $line if $debug;
+	printf "pop_LOGOUT=%s\n", $pop_logout if $debug;
+	return 0;
+    }
+
+### failure
+# Aug 11 09:19:19 host1 ipop3d[22171]: Login failure user=luser44 host=4-0-0.domain.pt [13.16.12.1]
+# Aug 11 09:19:22 host1 ipop3d[22171]: AUTHENTICATE LOGIN failure host=4-0-0.domain.pt [13.16.12.1]
+# Aug 11 09:47:47 host1 ipop3d[25308]: AUTHENTICATE luser323 failure host=[13.12.24.24]
+
+    if ($line =~ / failure /i) {
+	$pop_failure ++;
+	printf "POP_FAILURE: %s", $line if $debug;
+	printf "pop_failure=%s\n", $pop_failure if $debug;
+	return 0;
+    }
+
+### refused
+# Aug 11 13:32:14 host1 ipop3d[28886]: refused connect from 13.17.8.28
+
+    if ($line =~ /: refused connect from /i) {
+	$pop_refused ++;
+	printf "POP_REFUSED: %s", $line if $debug;
+	printf "pop_refused=%s\n", $pop_refused if $debug;
+	return 0;
+    }
+
+### local_error
+# Aug 11 11:50:36 host1 ipop3d[13132]: Error opening or locking INBOX user=luser10 host=3-4-3.domain.pt [13.16.4.7]
+
+    if ($line =~ /: Error opening or locking INBOX user=/i) {
+	$pop_local_error ++;
+	printf "POP_LOCAL_ERROR: %s", $line if $debug;
+	printf "pop_local_error=%s\n", $pop_local_error if $debug;
+	return 0;
+    }
+
+### net_error
+# Aug 11 07:36:14 host1 ipop3d[15759]: Command stream end of file while reading line user=luser234 host=9-9-9-domain.pt [13.16.4.5]
+# Aug 11 09:50:09 host1 ipop3d[24960]: Connection reset by peer while reading line user=luser555 host=[12.5.19.16]
+# Aug 11 12:15:01 host1 ipop3d[16601]: Connection timed out while reading line user=luser7985 host=4-5-6.domain.pt [13.16.1.15]
+
+    if ( ($line =~ /: Command stream end of file while reading line user=/i) ||
+	 ($line =~ /: Connection reset by peer while reading line user=/i) ||
+	 ($line =~ /: Connection timed out while reading line user=/i) ){
+	$pop_net_error ++;
+	printf "POP_NET_ERROR: %s", $line if $debug;
+	printf "pop_net_error=%s\n", $pop_net_error if $debug;
+	return 0;
+    }
+
+
+    $pop_undefs ++;
+    printf "POP_UNDEF: %s", $line if $debug;
+    printf "pop_undefs=%s\n", $pop_undefs if $debug;
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Put the pop values for output
+#
+# usage: &put_pop();
+#
+
+sub put_pop() {
+
+    &put_output("pop_connect",  sprintf("%8.2f", $pop_connect));
+    &put_output("pop_login",  sprintf("%8.2f", $pop_login));
+    &put_output("pop_logout",  sprintf("%8.2f", $pop_logout));
+
+    &put_output("pop_failure",  sprintf("%8.2f", $pop_failure));
+    &put_output("pop_refused",  sprintf("%8.2f", $pop_refused));
+
+    &put_output("pop_net_error",  sprintf("%8.2f", $pop_net_error));
+    &put_output("pop_local_error",  sprintf("%8.2f", $pop_local_error));
+
+    &put_output("pop_undefs",  sprintf("%8.2f", $pop_undefs));
+
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Get values for radiator radius columns
+#
+# usage: &measure_radius( );
+#
+
+sub measure_radius () {
+    #################################### insert bail out for too much
+    #################################### time spent ??
+
+  my $upper_ts= time;
+
+#Begin GET Accounting
+
+    $query  = "SELECT ACCT_SESSION_TIME,ACCT_STATUS_TYPE FROM ACCOUNTING ";
+    $query .= " WHERE ACCT_STATUS_TYPE = 'Stop'";
+    $query .= " AND TIMESTAMP > $radius_base_ts";
+    $query .= " AND TIMESTAMP < $upper_ts";
+
+    ($rad_time,$rad_sessions) = calculateRadVals($query);
+
+    ## incremental/accumulated values
+##    $radius_inc_time += $rad_time;
+##    $radius_inc_sessions += $rad_sessions;
+
+#END GET Accounting
+
+##    `$ECHO "$radius_inc_time:$radius_inc_sessions" > $ACCUM_radius_DB`;
+    $radius_base_ts += ($upper_ts - $radius_base_ts);
+    return 0;
+}
+
+##
+# IN:   query
+# RET:  time, sessions
+##
+sub calculateRadVals{
+  my $query = shift(@_);
+
+#print "radius query: $query\n";
+
+    my ($rad_t,$rad_s)= (0,0);
+    $sth = $RADdbh->prepare($query);
+    $sth ->execute();
+
+    $"=" \t ";
+    while ( @row = $sth -> fetchrow_array()){
+        #print "$row[0].$row[1]: $eca\n";
+        $rad_t += $row[0];
+        $rad_s++;
+    }
+
+    #print "Time: $rad_t seconds\t Sess: $rad_s sessions\n";
+    return ($rad_t,$rad_s);
+}
+
+
+# -------------------------------------------------------------------
+#
+# Put the radiator radius  values for output
+#
+# usage: &put_radius();
+#
+
+sub put_radius() {
+
+    &put_output("rad_time",  sprintf("%8.2f", $rad_time));
+    &put_output("rad_sessions",  sprintf("%8.2f", $rad_sessions));
+
+#incremental graph
+##    &put_output("radius_inc_time",  sprintf("%8.2f", $radius_inc_time));
+ ##   &put_output("radius_inc_sessions",  sprintf("%8.2f", $radius_inc_sessions));
+
+
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Get values for dns columns
+#
+# usage: &measure_dns( );
+#
+
+sub measure_dns () {
+
+
+    #################################### insert bail out for too much
+    #################################### time spent ??
+    $buf = <$DNSFD>;
+    while ($buf) {
+	## process line read and check for eof
+	if ($buf) {
+	    &process_dns_line ($buf);
+	}
+	if ($DNSFD->eof) {
+	    printf "DNS: eof on $DNSFile\n" if $debug;
+	    last; # get out of while($buf)
+	}
+	$buf = <$DNSFD>;
+    } ## while ($buf)
+
+
+    # test for file change via different inode or filesize decrease
+    $dev = $ino = $mode = $nlink = $uid = $gid = $rdev =
+	$size = $atime = $mtime = $ctime = $blksize = $blocks = '';
+    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+     $atime,$mtime,$ctime,$blksize,$blocks) = stat($DNSFile);
+    if (!$dev) {
+	&logit ("can't stat $DNSFile");
+	warn "$progname: can't stat $DNSFile\n";
+	return 1;
+    }
+    printf "DNSFD: dns_ino=%s vs. ino=%s\tdns_size=%s vs. size=%s\n", $dns_ino, $ino, $dns_size, $size if $debug;
+    if (($dns_ino != $ino) || ($dns_size > $size)) {
+	undef $DNSFD;
+	printf "DNS: file change on $DNSFile\n" if $debug;
+	$DNSFD = new IO::File "$DNSFile", "r";
+	if (!defined ($DNSFD)) {
+	    &logit ("can't re-open $DNSFile");
+	    warn "$progname: can't re-open $DNSFile\n";
+	    $dns_ino = $dns_size = 0;
+	    return 2;
+	}
+	$dns_ino = $ino;
+	$dns_size = $size;
+    }
+
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# init dns vars
+#
+# usage: &init_dns_vars();
+#
+
+sub init_dns_vars() {
+
+    $dns_usage_started       = 0;
+    $dns_nstats_started      = 0;
+    $dns_xstats_started      = 0;
+
+    &init_dns_usage_vars();
+    &init_dns_nstats_vars();
+    &init_dns_xstats_vars();
+
+    &init_odns_vars();
+}
+sub init_dns_usage_vars () {
+    $dns_cpu_u      = 0;
+    $dns_cpu_s      = 0;
+    $dns_ccpu_u     = 0;
+    $dns_ccpu_s     = 0;
+}
+sub init_dns_nstats_vars () {
+    $dns_a          = 0;
+    $dns_ptr        = 0;
+    $dns_mx         = 0;
+    $dns_any        = 0;
+
+    $dns_ns         = 0;
+    $dns_soa        = 0;
+    $dns_axfr       = 0;
+    $dns_aaaa       = 0;
+    $dns_other      = 0;
+}
+sub init_dns_xstats_vars () {
+    $dns_rr         = 0;
+    $dns_rq         = 0;
+    $dns_rother     = 0;
+
+    $dns_sans       = 0;
+    $dns_snaans     = 0;
+    $dns_snxd       = 0;
+    $dns_sother     = 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# init odns vars    (save old values)
+#
+# usage: &init_odns_vars();
+#
+
+sub init_odns_vars() {
+    &init_odns_usage_vars();
+    &init_odns_nstats_vars();
+    &init_odns_xstats_vars();
+}
+
+sub init_odns_usage_vars() {
+    $odns_cpu_u      = $dns_cpu_u      ;
+    $odns_cpu_s      = $dns_cpu_s      ;
+    $odns_ccpu_u     = $dns_ccpu_u     ;
+    $odns_ccpu_s     = $dns_ccpu_s     ;
+
+    &init_dns_usage_vars();
+}
+sub init_odns_nstats_vars() {
+    $odns_a          = $dns_a          ;
+    $odns_ptr        = $dns_ptr        ;
+    $odns_mx         = $dns_mx         ;
+    $odns_any        = $dns_any        ;
+
+    $odns_ns         = $dns_ns         ;
+    $odns_soa        = $dns_soa        ;
+    $odns_axfr       = $dns_axfr       ;
+    $odns_aaaa       = $dns_aaaa       ;
+    $odns_other      = $dns_other      ;
+
+    &init_dns_nstats_vars();
+}
+sub init_odns_xstats_vars() {
+    $odns_rr         = $dns_rr         ;
+    $odns_rq         = $dns_rq         ;
+    $odns_rother     = $dns_rother     ;
+
+    $odns_sans       = $dns_sans       ;
+    $odns_snaans     = $dns_snaans     ;
+    $odns_snxd       = $dns_snxd       ;
+    $odns_sother     = $dns_sother     ;
+
+    &init_dns_xstats_vars();
+}
+
+
+# -------------------------------------------------------------------
+#
+# calc dns delta
+#
+# usage: &calc_dns_delta();
+#
+
+sub calc_dns_delta() {
+    &calc_dns_usage_delta();
+    &calc_dns_nstats_delta();
+    &calc_dns_xstats_delta();
+}
+
+sub calc_dns_usage_delta() {
+    my $temp = 0;
+
+    if ($dns_cpu_u < $odns_cpu_u) {
+	$odns_cpu_u = $dns_cpu_u;
+    } else {
+	$temp = $dns_cpu_u; $dns_cpu_u = $dns_cpu_u - $odns_cpu_u; $odns_cpu_u = $temp;
+    }
+    if ($dns_cpu_s < $odns_cpu_s) {
+	$odns_cpu_s = $dns_cpu_s;
+    } else {
+	$temp = $dns_cpu_s; $dns_cpu_s = $dns_cpu_s - $odns_cpu_s; $odns_cpu_s = $temp;
+    }
+    if ($dns_ccpu_u < $odns_ccpu_u) {
+	$odns_ccpu_u = $dns_ccpu_u;
+    } else {
+	$temp = $dns_ccpu_u; $dns_ccpu_u = $dns_ccpu_u - $odns_ccpu_u; $odns_ccpu_u = $temp;
+    }
+    if ($dns_ccpu_s < $odns_ccpu_s) {
+	$odns_ccpu_s = $dns_ccpu_s;
+    } else {
+	$temp = $dns_ccpu_s; $dns_ccpu_s = $dns_ccpu_s - $odns_ccpu_s; $odns_ccpu_s = $temp;
+    }
+}
+sub calc_dns_nstats_delta() {
+    my $temp = 0;
+
+    if ($dns_a < $odns_a) {
+	$odns_a = $dns_a;
+    } else {
+	$temp = $dns_a; $dns_a = $dns_a - $odns_a; $odns_a = $temp;
+    }
+    if ($dns_ptr < $odns_ptr) {
+	$odns_ptr = $dns_ptr;
+    } else {
+	$temp = $dns_ptr; $dns_ptr = $dns_ptr - $odns_ptr; $odns_ptr = $temp;
+    }
+    if ($dns_mx < $odns_mx) {
+	$odns_mx = $dns_mx;
+    } else {
+	$temp = $dns_mx; $dns_mx = $dns_mx - $odns_mx; $odns_mx = $temp;
+    }
+    if ($dns_any < $odns_any) {
+	$odns_any = $dns_any;
+    } else {
+	$temp = $dns_any; $dns_any = $dns_any - $odns_any; $odns_any = $temp;
+    }
+
+    if ($dns_ns < $odns_ns) {
+	$odns_ns = $dns_ns;
+    } else {
+	$temp = $dns_ns; $dns_ns = $dns_ns - $odns_ns; $odns_ns = $temp;
+    }
+    if ($dns_soa < $odns_soa) {
+	$odns_soa = $dns_soa;
+    } else {
+	$temp = $dns_soa; $dns_soa = $dns_soa - $odns_soa; $odns_soa = $temp;
+    }
+    if ($dns_axfr < $odns_axfr) {
+	$odns_axfr = $dns_axfr;
+    } else {
+	$temp = $dns_axfr; $dns_axfr = $dns_axfr - $odns_axfr; $odns_axfr = $temp;
+    }
+    if ($dns_aaaa < $odns_aaaa) {
+	$odns_aaaa = $dns_aaaa;
+    } else {
+	$temp = $dns_aaaa; $dns_aaaa = $dns_aaaa - $odns_aaaa; $odns_aaaa = $temp;
+    }
+    if ($dns_other < $odns_other) {
+	$odns_other = $dns_other;
+    } else {
+	$temp = $dns_other; $dns_other = $dns_other - $odns_other; $odns_other = $temp;
+    }
+}
+sub calc_dns_xstats_delta() {
+    my $temp = 0;
+
+    if ($dns_rr < $odns_rr) {
+	$odns_rr = $dns_rr;
+    } else {
+	$temp = $dns_rr; $dns_rr = $dns_rr - $odns_rr; $odns_rr = $temp;
+    }
+    if ($dns_rq < $odns_rq) {
+	$odns_rq = $dns_rq;
+    } else {
+	$temp = $dns_rq; $dns_rq = $dns_rq - $odns_rq; $odns_rq = $temp;
+    }
+    if ($dns_rother < $odns_rother) {
+	$odns_rother = $dns_rother;
+    } else {
+	$temp = $dns_rother; $dns_rother = $dns_rother - $odns_rother; $odns_rother = $temp;
+    }
+
+    if ($dns_sans < $odns_sans) {
+	$odns_sans = $dns_sans;
+    } else {
+	$temp = $dns_sans; $dns_sans = $dns_sans - $odns_sans; $odns_sans = $temp;
+    }
+    if ($dns_snaans < $odns_snaans) {
+	$odns_snaans = $dns_snaans;
+    } else {
+	$temp = $dns_snaans; $dns_snaans = $dns_snaans - $odns_snaans; $odns_snaans = $temp;
+    }
+    if ($dns_snxd < $odns_snxd) {
+	$odns_snxd = $dns_snxd;
+    } else {
+	$temp = $dns_snxd; $dns_snxd = $dns_snxd - $odns_snxd; $odns_snxd = $temp;
+    }
+    if ($dns_sother < $odns_sother) {
+	$odns_sother = $dns_sother;
+    } else {
+	$temp = $dns_sother; $dns_sother = $dns_sother - $odns_sother; $odns_sother = $temp;
+    }
+}
+
+
+# -------------------------------------------------------------------
+#
+# Parse dns log line
+#
+# usage: &process_dns_line ($buf);
+#
+
+sub process_dns_line () {
+    my ($line) = @_;
+
+#
+# Oct 24 14:27:49 Ns named[17279]: USAGE 972394069 970586866 CPU=188.82u/82.79s CHILDCPU=0u/0s
+# Oct 24 14:27:49 Ns named[17279]: NSTATS 972394069 970586866 0=6 A=322014 NS=25 SOA=415 PTR=35772 MX=111 SRV=110 ANY=238
+# Oct 24 14:27:49 Ns named[17279]: XSTATS 972394069 970586866 RR=293985 RNXD=22941 RFwdR=205718 RDupR=3603 RFail=508 RFErr=0 RErr=141 RAXFR=0 RLame=2636 ROpts=0 SSysQ=58851 SAns=205888 SFwdQ=169140 SDupQ=23529 SErr=0 RQ=358773 RIQ=0 RFwdQ=0 RDupQ=8397 RTCP=206 SFwdR=205718 SFail=3 SFErr=0 SNaAns=204478 SNXD=45736
+#
+    if ($line !~ / named\[\d+\]: (USAGE|NSTATS|XSTATS) /) {
+	return 0;
+    }
+
+
+# Oct 24 14:27:49 Ns named[17279]: USAGE 972394069 970586866 CPU=188.82u/82.79s CHILDCPU=0u/0s
+    if ($line =~ /: USAGE \d+ \d+ CPU=([\d\.]+)u\/([\d\.]+)s CHILDCPU=([\d\.]+)u\/([\d\.]+)s/) {
+
+	$dns_cpu_u = $1;
+	$dns_cpu_s = $2;
+	$dns_ccpu_u = $3;
+	$dns_ccpu_s = $4;
+
+	printf "DNS_USAGE: %s", $line if $debug;
+	printf "dns_cpu_u=%s, dns_cpu_s=%s, dns_ccpu_u=%s, dns_ccpu_s=%s\n", $dns_cpu_u, $dns_cpu_s, $dns_ccpu_u, $dns_ccpu_s if $debug;
+
+	if ($dns_usage_started) {
+	    &calc_dns_usage_delta(); # puts delta into vars to print -&- saves into old
+	} else {
+	    $dns_usage_started = 1;
+	    &init_odns_usage_vars();  # saves old and cleans current values
+	}
+
+# Oct 24 14:27:49 Ns named[17279]: NSTATS 972394069 970586866 0=6 A=322014 NS=25 SOA=415 PTR=35772 MX=111 SRV=110 ANY=238
+    } elsif ($line =~ /: NSTATS \d+ \d+ /) {
+	my $l;
+
+	($l = $line) =~ s/^.*: NSTATS \d+ \d+ //;  # trim beginning
+	chop $l;
+
+	@types = split(' ',$l);
+
+	$dns_other = 0;
+	while (@types) {
+	    ($t,$v) = split ('=', pop @types);
+	    if ($t eq 'A') {
+		$dns_a = $v;
+	    } elsif ($t eq 'PTR') {
+		$dns_ptr = $v;
+	    } elsif ($t eq 'MX') {
+		$dns_mx = $v;
+	    } elsif ($t eq 'ANY') {
+		$dns_any = $v;
+	    } elsif ($t eq 'NS') {
+		$dns_ns = $v;
+	    } elsif ($t eq 'SOA') {
+		$dns_soa = $v;
+	    } elsif ($t eq 'AXFR') {
+		$dns_axfr = $v;
+	    } elsif ($t eq 'AAAA') {
+		$dns_aaaa = $v;
+	    } else {
+		$dns_other += $v;
+	    }
+	}
+
+	printf "DNS_NSTATS: %s", $line if $debug;
+	printf "dns_a=%s, dns_ptr=%s, dns_mx=%s, dns_any=%s, dns_ns=%s, dns_soa=%s, dns_axfr=%s, dns_aaaa=%s, dns_other=%s\n", $dns_a, $dns_ptr, $dns_mx, $dns_any, $dns_ns, $dns_soa, $dns_axfr, $dns_aaaa, $dns_other if $debug;
+
+	if ($dns_nstats_started) {
+	    &calc_dns_nstats_delta(); # puts delta into vars to print -&- saves into old
+	} else {
+	    $dns_nstats_started = 1;
+	    &init_odns_nstats_vars();  # saves old and cleans current values
+	}
+
+# Oct 24 14:27:49 Ns named[17279]: XSTATS 972394069 970586866 RR=293985 RNXD=22941 RFwdR=205718 RDupR=3603 RFail=508 RFErr=0 RErr=141 RAXFR=0 RLame=2636 ROpts=0 SSysQ=58851 SAns=205888 SFwdQ=169140 SDupQ=23529 SErr=0 RQ=358773 RIQ=0 RFwdQ=0 RDupQ=8397 RTCP=206 SFwdR=205718 SFail=3 SFErr=0 SNaAns=204478 SNXD=45736
+    } elsif ($line =~ /: XSTATS \d+ \d+ /) {
+	my $l;
+
+	($l = $line) =~ s/^.*: XSTATS \d+ \d+ //;  # trim beginning
+	chop $l;
+
+	@types = split(' ',$l);
+
+	$dns_rother = $dns_sother = 0;
+	while (@types) {
+	    ($t,$v) = split ('=', pop @types);
+	    if ($t eq 'RR') {
+		$dns_rr = $v;
+	    } elsif ($t eq 'RQ') {
+		$dns_rq = $v;
+	    } elsif ($t =~ /^R/) {
+		$dns_rother += $v;
+	    } elsif ($t eq 'SAns') {
+		$dns_sans = $v;
+	    } elsif ($t eq 'SNaAns') {
+		$dns_snaans = $v;
+	    } elsif ($t eq 'SNXD') {
+		$dns_snxd = $v;
+	    } elsif ($t =~ /^S/) {
+		$dns_sother += $v;
+	    }
+	}
+
+	printf "DNS_XSTATS: %s", $line if $debug;
+	printf "dns_rr=%s, dns_rq=%s, dns_rother=%s, dns_sans=%s, dns_snaans=%s, dns_snxd=%s, dns_sother=%s\n", $dns_rr, $dns_rq, $dns_rother, $dns_sans, $dns_snaans, $dns_snxd, $dns_sother if $debug;
+
+	if ($dns_xstats_started) {
+	    &calc_dns_xstats_delta(); # puts delta into vars to print -&- saves into old
+	} else {
+	    $dns_xstats_started = 1;
+	    &init_odns_xstats_vars();  # saves old and cleans current values
+	}
+
+    }
+
+    return 0;
+}
+
+
+# -------------------------------------------------------------------
+#
+# Put the dns values for output
+#
+# usage: &put_dns();
+#
+
+sub put_dns() {
+
+    &put_output("dns_cpu_u",  sprintf("%8.2f", $dns_cpu_u));
+    &put_output("dns_cpu_s",  sprintf("%8.2f", $dns_cpu_s));
+    &put_output("dns_ccpu_u",  sprintf("%8.2f", $dns_ccpu_u));
+    &put_output("dns_ccpu_s",  sprintf("%8.2f", $dns_ccpu_s));
+
+    &put_output("dns_a",  sprintf("%8.2f", $dns_a));
+    &put_output("dns_ptr",  sprintf("%8.2f", $dns_ptr));
+    &put_output("dns_mx",  sprintf("%8.2f", $dns_mx));
+    &put_output("dns_any",  sprintf("%8.2f", $dns_any));
+
+    &put_output("dns_ns",  sprintf("%8.2f", $dns_ns));
+    &put_output("dns_soa",  sprintf("%8.2f", $dns_soa));
+    &put_output("dns_axfr",  sprintf("%8.2f", $dns_axfr));
+    &put_output("dns_aaaa",  sprintf("%8.2f", $dns_aaaa));
+    &put_output("dns_other",  sprintf("%8.2f", $dns_other));
+
+    &put_output("dns_rr",  sprintf("%8.2f", $dns_rr));
+    &put_output("dns_rq",  sprintf("%8.2f", $dns_rq));
+    &put_output("dns_rother",  sprintf("%8.2f", $dns_rother));
+
+    &put_output("dns_sans",  sprintf("%8.2f", $dns_sans));
+    &put_output("dns_snaans",  sprintf("%8.2f", $dns_snaans));
+    &put_output("dns_snxd",  sprintf("%8.2f", $dns_snxd));
+    &put_output("dns_sother",  sprintf("%8.2f", $dns_sother));
+
+    return 0;
+}
+

Added: trunk/orca/contrib/orcaservices/orcaservices_running.pl.in
==============================================================================
--- trunk/orca/contrib/orcaservices/orcaservices_running.pl.in	(original)
+++ trunk/orca/contrib/orcaservices/orcaservices_running.pl.in	Sat Jul 13 21:25:42 2002
@@ -0,0 +1,41 @@
+# orcaservices_running: warn if orcaservices files are not up to date.
+#
+# Copyright (C) 2000 Carlos Canau and KPNQwest Portugal
+# Copyright (C) 1998, 1999 Blair Zajac and Yahoo!, Inc.
+
+use strict;
+use POSIX qw(strftime);
+
+# Set this to the list of directories that contain the output from
+# percoservices.se.
+my @stats_dirs = ('@ORCASERVICES_DIR@');
+
+foreach my $stats_dir (@stats_dirs) {
+
+  die "$0: unable to change to `$stats_dir'" unless chdir $stats_dir;
+
+  die "$0: unable to open `.' for reading: $!\n" unless opendir(DIR, '.');
+
+  my @hosts = sort grep { $_ !~ /^\./ } readdir(DIR);
+
+  closedir(DIR);
+
+  print "Now in $stats_dir\n";
+
+  my $percol = strftime("percol-%Y-%m-%d", localtime());
+
+  foreach my $host (@hosts) {
+    my $file = "$host/$percol";
+    unless (-f $file) {
+      warn "$0: $file does not exist.\n";
+      next;
+    }
+    my $age = (-M $file)*(24*60);
+    if ( $age > 8) {
+      $file= sprintf "%35s", $file;
+      $age = sprintf "%8.2f", $age;
+      warn "$0: $file is $age minutes old.\n";
+      next;
+    }
+  }
+}

Added: trunk/orca/contrib/orcaservices/restart_orcaservices.sh.in
==============================================================================
--- trunk/orca/contrib/orcaservices/restart_orcaservices.sh.in	(original)
+++ trunk/orca/contrib/orcaservices/restart_orcaservices.sh.in	Sat Jul 13 21:25:42 2002
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# This stops and restarts orcaservices.se.
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+
+# Kill any running orcaservicess.
+$bindir/stop_orcaservices
+
+# Start the orcaservices.
+$bindir/start_orcaservices

Added: trunk/orca/contrib/orcaservices/S99orcaservices.sh.in
==============================================================================
--- trunk/orca/contrib/orcaservices/S99orcaservices.sh.in	(original)
+++ trunk/orca/contrib/orcaservices/S99orcaservices.sh.in	Sat Jul 13 21:25:42 2002
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+
+case "$1" in
+'start')
+	if [ -x $bindir/start_orcaservices ]; then
+		umask 022
+		$bindir/start_orcaservices
+	else
+		echo "$0: $bindir/start_orcaservices does not exist or is not executable."
+	fi
+	;;
+
+'stop')
+	if [ -x $bindir/stop_orcaservices ]; then
+		$bindir/stop_orcaservices
+	fi
+	;;
+
+*)
+	echo "Usage: $0 { start | stop }"
+	exit 1
+	;;
+
+esac
+exit 0

Added: trunk/orca/contrib/orcaservices/stop_orcaservices.sh.in
==============================================================================
--- trunk/orca/contrib/orcaservices/stop_orcaservices.sh.in	(original)
+++ trunk/orca/contrib/orcaservices/stop_orcaservices.sh.in	Sat Jul 13 21:25:42 2002
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+AWK=@AWK@
+
+# Kill any running orcallators.
+pids=`/usr/ucb/ps auxww | $AWK '/orcaservices.pl/ && !/awk/ {print $2}'`
+if test "$pids" != ""; then
+  echo "Killing pids $pids."
+  kill -HUP $pids
+  sleep 1
+  pids=`/usr/ucb/ps auxww | $AWK '/orcaservices.pl/ && !/awk/ {print $2}'`
+  if test "$pids" != ""; then
+    kill -TERM $pids
+    sleep 1
+    pids=`/usr/ucb/ps auxww | $AWK '/orcaservices.pl/ && !/awk/ {print $2}'`
+    if test "$pids" != ""; then
+      kill -9 $pids
+      sleep 1
+    fi
+  fi
+fi

Added: trunk/orca/contrib/orcaservices/orcaservices.cfg.in
==============================================================================
--- trunk/orca/contrib/orcaservices/orcaservices.cfg.in	(original)
+++ trunk/orca/contrib/orcaservices/orcaservices.cfg.in	Sat Jul 13 21:25:42 2002
@@ -0,0 +1,395 @@
+base_dir		@RRD_DIR@/orcaservices
+rrd_dir			.
+state_file		orca.state
+html_dir		@HTML_DIR at -services
+expire_images		1
+find_times		0:10 1:00 6:00 12:00 19:00
+
+warn_email		root at localhost
+late_interval		interval + 30
+
+
+#
+# ATTENTION: hardcoded /var/orca/orcaservices/ in find_files
+# you might need to change this to your values
+#
+group orcaservices {
+find_files		/var/orca/orcaservices/(.*)/(?:(?:orcaservices)|(?:percol))-\d{4}-\d{2}-\d{2}(?:\.(?:Z|gz|bz2))?
+column_description	first_line
+date_source		column_name timestamp
+date_format		%s
+interval		300
+reopen			1
+filename_compare	sub {
+			  my ($ay, $am, $ad) = $a =~ /-(\d{4})-(\d\d)-(\d\d)/;
+			  my ($by, $bm, $bd) = $b =~ /-(\d{4})-(\d\d)-(\d\d)/;
+			  if (my $c = (( $ay       <=>  $by) ||
+			               ( $am       <=>  $bm) ||
+			               (($ad >> 3) <=> ($bd >> 3)))) {
+			    return 2*$c;
+			  }
+			  $ad <=> $bd;
+			}
+}
+
+#
+# ATTENTION: change this to your values
+#
+html_top_title		Services Status
+
+#
+# ATTENTION: change this to your values
+#
+html_page_header
+  <a href="http://www.kpnQwest.pt/">
+    <img border=0 alt="kpnQwest Portugal"
+     src="http://www.kpnqwest.pt/images/kqlogopt_mini.gif"
+     width=101 height=61></a>
+  <spacer type=vertical size=4>
+
+html_page_footer
+  <spacer type=vertical size=20>
+  <font face="Arial,Helvetica">
+    These plots brought to you by your local system administrator.
+  </font>
+
+
+plot {
+title			%g SMTP Mail Queue
+source			orcaservices
+data			mailq_total
+legend			Msgs. in queue (5m)
+y_legend		Number of Messages
+line_type		line2
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#SMTP_Mail_Queue
+}
+
+plot {
+title			%g SMTP Messages in 5 minutes
+source			orcaservices
+data			smtp_from
+data			smtp_sent
+legend			Messages In (5m)
+legend			Messages Out (5m)
+y_legend		Number of Messages
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#SMTP_Messages_in_5_minutes
+}
+
+plot {
+title			%g SMTP Size
+source			orcaservices
+data			smtp_sizes
+data			smtp_tops
+line_type		area
+line_type		line1
+legend			5 min average
+legend			Peak 5 minute
+y_legend		Message size (bytes)
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#SMTP_Size
+}
+
+plot {
+title			%g SMTP Delay
+source			orcaservices
+data			smtp_delay
+data			smtp_maxd
+line_type		area
+line_type		line1
+legend			5 min average
+legend			Peak 5 minute
+y_legend		Message Delay (seconds)
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#SMTP_Delay
+}
+
+plot {
+title			%g SMTP Retries and Queueing
+source			orcaservices
+data			smtp_rtrs
+data			smtp_queued
+legend			Retries (5m)
+legend			Messages Queued (5m)
+y_legend		Number of Messages
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#SMTP_Retries_and_Queueing
+}
+
+plot {
+title			%g SMTP Failed
+source			orcaservices
+data			smtp_torf
+data			smtp_c_ml
+data			smtp_c_rt
+data			smtp_ntfs
+legend			Temp or Fatal Error (5m)
+legend			Check Mail (5m)
+legend			Check Rcpt (5m)
+legend			Portmaster Notifies (5m)
+y_legend		Number of Messages
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#SMTP_Failed
+}
+
+plot {
+title			%g SMTP DSN and Undefs
+source			orcaservices
+data			smtp_dsns
+data			smtp_undf
+legend			Number of DSNs (5m)
+legend			Undefined log (5m)
+y_legend		Number of Messages
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#SMTP_DSN_and_Undefs
+}
+
+
+
+
+plot {
+title			%g MERIT RADIUS AUTH in 5 minutes
+source			orcaservices
+data			radius_auth
+data			radius_auth_ok
+data			radius_auth_nok
+legend			Auth (5m)
+legend			Auth OK (5m)
+legend			Auth FAILED (5m)
+y_legend		Number of Auth Packets
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#MERIT_RADIUS_AUTH_in_5_minutes
+}
+
+plot {
+title			%g MERIT RADIUS ACCT in 5 minutes
+source			orcaservices
+data			radius_acct_start
+data			radius_acct_stop
+legend			Start records (5m)
+legend			Stop records (5m)
+y_legend		Number of Acct Packets
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#MERIT_RADIUS_ACCT_in_5_minutes
+}
+
+plot {
+title			%g MERIT RADIUS REMOTE AUTH in 5 minutes
+source			orcaservices
+data			radius_rem_auth
+data			radius_rem_auth_ok
+data			radius_rem_auth_nok
+legend			Remote Auth (5m)
+legend			Remote Auth OK (5m)
+legend			Remote Auth FAILED (5m)
+y_legend		Number of Remote Auth Packets
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#MERIT_RADIUS_REMOTE_AUTH_in_5_minutes
+}
+
+plot {
+title			%g MERIT RADIUS UNDEFS in 5 minutes
+source			orcaservices
+data			radius_undefs
+legend			Undef lines (5m)
+y_legend		Number of undef lines
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#MERIT_RADIUS_UNDEFS_in_5_minutes
+}
+
+
+
+plot {
+title			%g POP SESSIONS in 5 minutes
+source			orcaservices
+data			pop_connect
+data			pop_login
+data			pop_logout
+legend			Connect (5m)
+legend			Login (5m)
+legend			Logout (5m)
+y_legend		Units in 5 minutes
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#POP_SESSIONS_in_5_minutes
+}
+
+plot {
+title			%g POP DENIED in 5 minutes
+source			orcaservices
+data			pop_failure
+data			pop_refused
+legend			Failures (5m)
+legend			Refused (5m)
+y_legend		Units in 5 minutes
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#POP_DENIED_in_5_minutes
+}
+
+plot {
+title			%g POP FAILURES in 5 minutes
+source			orcaservices
+data			pop_net_error
+data			pop_local_error
+legend			Network errors (5m)
+legend			Local errors (5m)
+y_legend		Units in 5 minutes
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#POP_FAILURES_in_5_minutes
+}
+
+plot {
+title			%g POP UNDEFS in 5 minutes
+source			orcaservices
+data			pop_undefs
+legend			Undefs (5m)
+y_legend		Units in 5 minutes
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#POP_UNDEFS_in_5_minutes
+}
+
+plot {
+title			%g Radius time usage
+source			orcaservices
+line_type		line2
+data			rad_time/60
+legend			Time consumption (5 min)
+y_legend		Minutes
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#Radius_time_usage
+}
+
+plot {
+title			%g Radius sessions
+source			orcaservices
+line_type		line2
+data			rad_sessions
+legend			Number of Sessions (5 min)
+y_legend		Terminated Sessions
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#Radius_sessions
+}
+
+
+
+plot {
+title			%g NAMED CPU Usage in 1 hour
+source			orcaservices
+data			dns_cpu_u
+data			dns_cpu_s
+data			dns_ccpu_u
+data			dns_ccpu_s
+line_type		line2
+line_type		line2
+line_type		line2
+line_type		line2
+legend			User
+legend			System
+legend			Child User
+legend			Child System
+y_legend		Seconds in 1 hour
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#NAMED_CPU_Usage_in_1_hour
+}
+
+plot {
+title			%g NAMED Major queries
+source			orcaservices
+data			dns_a
+data			dns_ptr
+data			dns_mx
+data			dns_any
+line_type		line2
+line_type		line2
+line_type		line2
+line_type		line2
+legend			A
+legend			PTR
+legend			MX
+legend			ANY
+y_legend		Units in 1 hour
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#NAMED_Major_queries
+}
+
+plot {
+title			%g NAMED Minor queries
+source			orcaservices
+data			dns_ns
+data			dns_soa
+data			dns_axfr
+data			dns_aaaa
+data			dns_other
+line_type		line2
+line_type		line2
+line_type		line2
+line_type		line2
+line_type		line2
+legend			NS
+legend			SOA
+legend			AXFR
+legend			AAAA
+legend			OTHER
+y_legend		Units in 1 hour
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#NAMED_Minor_queries
+}
+
+plot {
+title			%g NAMED Received
+source			orcaservices
+data			dns_rr
+data			dns_rq
+data			dns_rother
+line_type		line2
+line_type		line2
+line_type		line2
+legend			R-Responses
+legend			R-Queries
+legend			R-OTHER
+y_legend		Units in 1 hour
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#NAMED_Received
+}
+
+plot {
+title			%g NAMED Sent
+source			orcaservices
+data			dns_sans
+data			dns_snaans
+data			dns_snxd
+data			dns_sother
+line_type		line2
+line_type		line2
+line_type		line2
+line_type		line2
+legend			S-Answer
+legend			S-NA Answer
+legend			S-Negative
+legend			S-OTHER
+y_legend		Units in 1 hour
+data_min		0
+data_max		U
+href			http://o-s.kpnqwest.pt/orcaservices.html#NAMED_Sent
+}

Added: trunk/orca/contrib/orcaservices/README
==============================================================================
--- trunk/orca/contrib/orcaservices/README	(original)
+++ trunk/orca/contrib/orcaservices/README	Sat Jul 13 21:25:42 2002
@@ -0,0 +1,155 @@
+##
+##
+## OrcaServices.pl, a log generating services usage monitor
+##
+##
+
+##
+## This program logs many different services usage to a log file
+## for later processing.
+##
+
+##
+## Author: Carlos Canau <Carlos.Canau at KPNQwest.pt>.
+## Documentation:	Jose Carlos <jcp at KPNQwest.pt>.
+##
+
+##
+## Portions adapted from Orcallator.se written by Blair Zajac
+## Portions ported to perl from Orcallator.se written by Blair Zajac
+## other portions adapted from several other open source scripts
+##
+##
+
+PERL_SCRIPTS
+	orcaservices_running
+		warn if orcaservices files are not up to date.
+		Not changed by canau.
+	orcaservices.pl
+		main data collector
+
+SHELL_SCRIPTS
+	restart_orcaservices
+		guess!
+	stop_orcaservices
+		I'll give you a hint... stopping
+	start_orcaservices
+		need a hint, look above
+	S99orcaservices
+		used for automatic start of orcaservices
+
+Other Files:
+ 	orcaservices.cfg
+
+		Configuration of services to monitor
+		graph details etc
+
+        $libdir/orcaservices.$HOSTNAME
+                services can be disabled editing this file.
+                $libdir defaults to /usr/local/lib
+
+                Services can be disabled using the param for file with
+                the switch for input file and setting it to off: ex:
+                --smtp_logfile=off
+
+        $libdir/orcaservices.DB.$HOSTNAME
+                $libdir defaults to /usr/local/lib
+                auth info for accessing database
+                SYNTAX:  proto:drv:database:user:pass
+                CAREFUL: mind the file permissions! chmod 0600
+
+Other Notes:
+	Changed scripts have the original copy in [FILE_NAME].ORIG
+
+###########################################################################
+INSTALLATION STEPS
+###########################################################################
+
+1) Install Time-HiRes -or- disable  line "use Time::HiRes" in the code
+
+2) Install DBI -or- disable line "use  DBI" in the code -AND- don't do
+radius stats via the "--radius_db=off" parameter
+
+3) cd [base_dir]/orca-0.26/
+   ./configure  [OPTIONS]
+   make
+   make install
+
+   * if orcaservices should run at boottime
+
+   make orcaservices_run_at_boot
+
+   Most of the skeleton code of orcaservices comes from orcallator. So
+   everything is very similar.
+
+4) You might need to edit orcaservices.pl to suit your needs. Look for
+   code need the ATTENTION string.  You'll probably need to edit
+   orcaservices.cfg.in.
+
+
+###########################################################################
+CURRENT VALUES
+###########################################################################
+
+NAMED
+-----
+DEFAULT: $def_dns_logfile = "/var/log/named";
+DISABLE: --dns_logfile=off
+
+	Reads hourly stats from named log file.
+
+SENDMAIL
+--------
+DEFAULT: $def_smtp_logfile = "/var/log/syslog";
+DISABLE: --smtp_logfile=off
+
+	Reads syslog from sendmail.
+
+MERIT RADIUS
+------------
+DEFAULT: $def_merit_radius_logfile = "/usr/local/etc/raddb/logfile";
+DISABLE: --merit_radius_logfile=off
+
+	Reads syslog from Merit Radius.
+
+POP3
+----
+DEFAULT: $def_pop_logfile = "/var/log/ipop3d.log";
+DISABLE: --pop_logfile=off
+
+	Reads syslog from ipop3d.
+
+RADIUS FROM DATABASE
+--------------------
+DEFAULT: $def_radius_auth = "/usr/local/lib/orcaservices.DB.$nodename";
+DISABLE: --radius_db=off
+
+
+	Reads Radius stop records from Database and do stats.  You
+	might need to change the SQL query in the code.  You'll have
+	to create the orcaservices.DB.$hostname file with the database
+	options.
+
+MAILQ
+-----
+DEFAULT: $def_mailq = "on";
+DISABLE: --mailq=off
+
+
+###########################################################################
+TODO
+###########################################################################
+
+. better installation
+. better documentation
+. more types of monitorization
+. rip WWW code from orcallator.se or re-write newer
+. ...
+
+###########################################################################
+FINAL RAVINGS
+###########################################################################
+
+Feel free to extend this package.  Any bug fixes and enhancements sent
+to o-s at kqnet.pt will be appreciated, dissected, scorned and probably
+included in future releases (not necessarily in that order :-)))).

Modified: trunk/orca/orcallator/orcallator_running.pl.in
==============================================================================
--- trunk/orca/orcallator/orcallator_running.pl.in	(original)
+++ trunk/orca/orcallator/orcallator_running.pl.in	Sat Jul 13 21:25:42 2002
@@ -1,6 +1,6 @@
 # orcallator_running: warn if orcallator files are not up to date.
 #
-# Copyright (C) 1998, 1999 Blair Zajac and GeoCities, Inc.
+# Copyright (C) 1998, 1999 Blair Zajac and Yahoo!, Inc.
 
 use strict;
 use POSIX qw(strftime);

Modified: trunk/orca/orcallator/Makefile.in
==============================================================================
--- trunk/orca/orcallator/Makefile.in	(original)
+++ trunk/orca/orcallator/Makefile.in	Sat Jul 13 21:25:42 2002
@@ -4,8 +4,8 @@
 exec_prefix	= @exec_prefix@
 bindir		= @bindir@
 libdir		= @libdir@
-MKDIR		= @MKDIR@
 INSTALL		= @INSTALL@
+MKDIR		= @MKDIR@
 PERL_HEAD	= @PERL_HEAD@
 ORCALLATOR_DIR	= @ORCALLATOR_DIR@
 RRD_DIR		= @RRD_DIR@
@@ -56,7 +56,6 @@
 
 Makefile:	Makefile.in
 		cd .. && CONFIG_FILES=orcallator/Makefile ./config.status
-		$(MAKE)
 
 orcallator.cfg:			orcallator.cfg.in
 		cd .. && CONFIG_FILES=orcallator/orcallator.cfg ./config.status

Modified: trunk/orca/orcallator/orcallator.cfg.in
==============================================================================
--- trunk/orca/orcallator/orcallator.cfg.in	(original)
+++ trunk/orca/orcallator/orcallator.cfg.in	Sat Jul 13 21:25:42 2002
@@ -1,5 +1,8 @@
 # Orca configuration file for orcallator files.
 
+# Require at least this version of Orca.
+require			Orca 0.263
+
 # base_dir is prepended to the paths find_files, html_dir, rrd_dir,
 # and state_file only if the path does not match the regular
 # expression ^\\?\.{0,2}/, which matches /, ./, ../, and \./.
@@ -34,6 +37,14 @@
 warn_email		root at localhost
 late_interval		interval + 30
 
+# These parameters specify which plots to generate.
+generate_hourly_plot	0
+generate_daily_plot	1
+generate_weekly_plot	1
+generate_monthly_plot	1
+generate_quarterly_plot	1
+generate_yearly_plot	1
+
 # This defines where the find the source data files and the format of
 # those files.  Notes about the fields:
 # find_files
@@ -53,9 +64,7 @@
 find_files		@ORCALLATOR_DIR@/(.*)/(?:(?:orcallator)|(?:percol))-\d{4}-\d{2}-\d{2}(?:\.(?:Z|gz|bz2))?
 column_description	first_line
 date_source		column_name timestamp
-date_format		%s
 interval		300
-reopen			1
 filename_compare	sub {
 			  my ($ay, $am, $ad) = $a =~ /-(\d{4})-(\d\d)-(\d\d)/;
 			  my ($by, $bm, $bd) = $b =~ /-(\d{4})-(\d\d)-(\d\d)/;
@@ -103,12 +112,15 @@
 source			orcallator
 data			usr%
 data			sys%
-data			100 - usr% - sys%
+data			wio%
+data			idle%
 line_type		area
 line_type		stack
 line_type		stack
+line_type		stack
 legend			User
 legend			System
+legend			Wait IO
 legend			Idle
 y_legend		Percent
 data_min		0
@@ -228,56 +240,28 @@
 href			http://www.gps.caltech.edu/~blair/orca/docs/orcallator.html#web_server_error_rate
 }
 
+# Interface bits per second for 10 Mbit interfaces.
 plot {
-title			%g Interface Bits Per Second: be0
-source			orcallator
-data			1024 * 8 * be0InKB/s
-data			1024 * 8 * be0OuKB/s
-line_type		area
-line_type		line1
-legend			Input
-legend			Output
-y_legend		Bits/s
-data_min		0
-data_max		100000000
-href			http://www.gps.caltech.edu/~blair/orca/docs/orcallator.html#interface_bits_per_second
-}
-
-plot {
-title			%g Interface Bits Per Second: elxl0
+title			%g Interface Bits Per Second: $1
 source			orcallator
-data			1024 * 8 * elxl0InKB/s
-data			1024 * 8 * elxl0OuKB/s
+data			1024 * 8 * ((?:(?:elxl)|(?:le)|(?:qe))\d+)InKB/s
+data			1024 * 8 * $1OuKB/s
 line_type		area
 line_type		line1
 legend			Input
 legend			Output
 y_legend		Bits/s
 data_min		0
-data_max		100000000
-href			http://www.gps.caltech.edu/~blair/orca/docs/orcallator.html#interface_bits_per_second
-}
-
-plot {
-title			%g Interface Bits Per Second: hme0
-source			orcallator
-data			1024 * 8 * hme0InKB/s
-data			1024 * 8 * hme0OuKB/s
-line_type		area
-line_type		line1
-legend			Input
-legend			Output
-y_legend		Bits/s
-data_min		0
-data_max		100000000
+data_max		10000000
 href			http://www.gps.caltech.edu/~blair/orca/docs/orcallator.html#interface_bits_per_second
 }
 
+# Interface bits per second for 100 Mbit interfaces.
 plot {
-title			%g Interface Bits Per Second: hme1
+title			%g Interface Bits Per Second: $1
 source			orcallator
-data			1024 * 8 * hme1InKB/s
-data			1024 * 8 * hme1OuKB/s
+data			1024 * 8 * ((?:(?:be)|(?:hme))\d+)InKB/s
+data			1024 * 8 * $1OuKB/s
 line_type		area
 line_type		line1
 legend			Input
@@ -288,40 +272,26 @@
 href			http://www.gps.caltech.edu/~blair/orca/docs/orcallator.html#interface_bits_per_second
 }
 
+# Interface bits per second for 1 Gbit interfaces.
 plot {
-title			%g Interface Bits Per Second: le0
-source			orcallator
-data			1024 * 8 * le0InKB/s
-data			1024 * 8 * le0OuKB/s
-line_type		area
-line_type		line1
-legend			Input
-legend			Output
-y_legend		Bits/s
-data_min		0
-data_max		10000000
-href			http://www.gps.caltech.edu/~blair/orca/docs/orcallator.html#interface_bits_per_second
-}
-
-plot {
-title			%g Interface Bits Per Second: le1
+title			%g Interface Bits Per Second: $1
 source			orcallator
-data			1024 * 8 * le1InKB/s
-data			1024 * 8 * le1OuKB/s
+data			1024 * 8 * (v?ge\d+)InKB/s
+data			1024 * 8 * $1OuKB/s
 line_type		area
 line_type		line1
 legend			Input
 legend			Output
 y_legend		Bits/s
 data_min		0
-data_max		10000000
+data_max		1000000000
 href			http://www.gps.caltech.edu/~blair/orca/docs/orcallator.html#interface_bits_per_second
 }
 
 plot {
 title			%g Interface Packets Per Second: $1
 source			orcallator
-data			(.*\d)Ipkt/s
+data			(.*\d+)Ipkt/s
 data			$1Opkt/s
 line_type		area
 line_type		line1
@@ -337,7 +307,7 @@
 plot {
 title			%g Interface Errors Per Second: $1
 source			orcallator
-data			(.*\d)IErr/s
+data			(.*\d+)IErr/s
 data			$1OErr/s
 line_type		area
 line_type		line1
@@ -350,40 +320,40 @@
 }
 
 plot {
-title			%g Interface Nocanput Rate
+title			%g Interface Deferred Packet Rate
 source			orcallator
-data			(.*\d)NoCP/s
+data			(.*\d+)Defr/s
 line_type		area
 legend			$1
-y_legend		Nocanput/s
+y_legend		Defers/s
 data_min		0
 flush_regexps		1
-href			http://www.gps.caltech.edu/~blair/orca/docs/orcallator.html#interface_nocanput_rate
+href			http://www.gps.caltech.edu/~blair/orca/docs/orcallator.html#interface_deferred_packet_rate
 }
 
 plot {
-title			%g Interface Deferred Packet Rate
+title			%g Interface Collisions
 source			orcallator
-data			(.*\d)Defr/s
+data			(.*\d+)Coll%
 line_type		area
 legend			$1
-y_legend		Defers/s
+y_legend		Percent
 data_min		0
+data_max		200
 flush_regexps		1
-href			http://www.gps.caltech.edu/~blair/orca/docs/orcallator.html#interface_deferred_packet_rate
+href			http://www.gps.caltech.edu/~blair/orca/docs/orcallator.html#interface_collisions
 }
 
 plot {
-title			%g Interface Collisions
+title			%g Interface Nocanput Rate
 source			orcallator
-data			(.*\d)Coll%
+data			(.*\d+)NoCP/s
 line_type		area
 legend			$1
-y_legend		Percent
+y_legend		Nocanput/s
 data_min		0
-data_max		200
 flush_regexps		1
-href			http://www.gps.caltech.edu/~blair/orca/docs/orcallator.html#interface_collisions
+href			http://www.gps.caltech.edu/~blair/orca/docs/orcallator.html#interface_nocanput_rate
 }
 
 plot {

Modified: trunk/orca/orcallator/orcallator.se
==============================================================================
--- trunk/orca/orcallator/orcallator.se	(original)
+++ trunk/orca/orcallator/orcallator.se	Sat Jul 13 21:25:44 2002
@@ -4,23 +4,57 @@
 // This program logs many different system quantities to a log file
 // for later processing.
 //
-// Author: Blair Zajac <bzajac at akamai.com>.
+// Author: Blair Zajac <blair at gps.caltech.edu>.
 //
 // Portions copied from percollator.se written by Adrian Cockroft.
 //
-// Version 1.23: Feb 25, 2000	When orcallator was running on a system with
-//				DiskSuite, the same physical disk was listed
-//				multiple times when it appeared in the same
-//				metadevice.  The solution to the problem is
-//				not to build the c0t0d0 name but use the long
-//				disk name provided by the long_name string.
-//				Patch contributed by Paul Haldane
-//				<Paul.Haldane at newcastle.ac.uk>.
+// Version 1.28b4: Mar 27, 2001	Recoded measure_disk() to access the RAWDISK
+//				interface to sys_kstat device information to
+//				allow the activity on Sun's A1000 and Clariion
+//				Raid controller drives to be seen.  Apparently
+//				the pseudo drivers do not update the kstat
+//				interface.  It is also inverts the fix
+//				provided by version 1.23 to avoid over-counting
+//				md devices.  By suppressing stats from slices
+//				and metadevices and instead reporting on full
+//				devices such as c0t0d0 or sd0.  Note: This may
+//				have introduced an interaction with the
+//				live_rules.se class monitoring of drive
+//				performance.  Prevent floppy disks and tape
+//				drives from RAWDISK.  Added wio% to measure
+//				wait time since the idle calculation is wrong
+//				without this.  Prevent filesystems mounted
+//				under /snapshots from being seen.  Patch
+//				contributed by Alan LeGrand
+//				<alegrand at wallace.com>.
+// Version 1.27: Mar 27, 2001	Print the portion of time running in idle mode
+//				with some process waiting for block I/O as
+//				wio% and otherwise completely idle time as
+//				idle%.
+// Version 1.26: Feb  5, 2001	Make sure to check the return from stat() on
+//				the web server access log in case the file is
+//				missing.  Use fstat() instead of stat() when a
+//				file descriptor is available.
+// Version 1.25: Mar 30, 2000	Fix a typo where nil was misspelled as nik.
+// Version 1.24: Mar 25, 2000	When orcallator.se was running on a system
+//				with an older version of SE the p_vmstat.scan
+//				variable is an integer and the sprintf to
+//				%8.3f fails, resulting in a perceived scan rate
+//				of 0 pages per second.  Now always add 0.0 to
+//				p_vmstat.scan to get a double.
+// Version 1.23: Feb 25, 2000	When orcallator.se was running on a system
+//				with DiskSuite, the same physical disk was
+//				listed multiple times when it appeared in
+//				several metadevices.  The solution to the
+//				problem is not to build the c0t0d0 name but
+//				use the long disk name provided by the
+//				long_name string.  Patch contributed by Paul
+//				Haldane <Paul.Haldane at newcastle.ac.uk>.
 // Version 1.22: Jan 14, 2000	Include code to record NFS v2 and v3 server
-//				statistics.  The new statistics are: nfss_calls,
-//				the number of NFS calls to the NFS server,
-//				nfss_bad, the number of bad NFS calls per
-//				second, and v{2,3}{reads,writes}, which are
+//				statistics.  The new statistics are:
+//				nfss_calls, the number of NFS calls to the NFS
+//				server, nfss_bad, the number of bad NFS calls
+//				per second, and v{2,3}{reads,writes}, which are
 //				nfss_calls broken down into NFS version 2 and
 //				NFS version 3 calls.  The sum of v{2,3}{reads,
 //				writes} will be less than nfss_calls as the
@@ -29,7 +63,7 @@
 //				Haldane <Paul.Haldane at newcastle.ac.uk>.  This
 //				code is enabled by the standard -DWATCH_OS or
 //				individually by -DWATCH_NFS_SERVER.  The
-//				define -DWATCH_NFS has been supperseded by
+//				define -DWATCH_NFS has been superseded by
 //				-DWATCH_NFS_CLIENT, but to keep backwards
 //				compatibility, -DWATCH_NFS_CLIENT will be
 //				defined if -DWATCH_NFS is defined.
@@ -69,7 +103,7 @@
 //				mount point's disk space and inode capacity,
 //				usage, available for non-root users and
 //				percent used.  This comes from Duncan Lawie
-//				tyger at hoopoes.com. Add some smarts so that if
+//				tyger at hoopoes.com.  Add some smarts so that if
 //				the number of interfaces, physical disks, or
 //				mounted partitions changes, then a new header
 //				is printed.  This will prevent column name and
@@ -120,6 +154,7 @@
 #define WATCH_NFS_CLIENT	1
 #define WATCH_NFS_SERVER	1
 #define WATCH_MOUNTS		1
+#define USE_RAWDISK		1
 #define WATCH_DISK		1
 #define WATCH_DNLC		1
 #define WATCH_INODE		1
@@ -283,7 +318,7 @@
 int		hz;				// Clock tick rate.
 int		page_size;			// Page size in bytes.
 long		boot_time;			// Boot time of the system.
-long		interval = SAMPLE_INTERVAL;	// Sampling interval. 
+long		interval = SAMPLE_INTERVAL;	// Sampling interval.
 
 #ifdef WATCH_CPU
 int		can_read_kernel = 0;		// If the kernel can be read.
@@ -377,6 +412,251 @@
 
 #endif
 
+// RAWDISK BEGIN
+#ifdef USE_RAWDISK
+#include <sys_kstat.se>
+// This extention accesses the sys_kstat.se interface to the kstat IO
+// queues to extract info on drives not available in the kstat.se
+// kstat$disk interface.  Global data shared between function calls.
+struct RawDisk {
+  // Exposed interface (matches kstat)
+  char long_name[16];
+  char short_name[8];
+  double reads;
+  double kreads;
+  double writes;
+  double kwrites;
+  double avg_wait;
+  double avg_serv;
+  double service;
+  double wait_percent;
+  double run_percent;
+
+  // Hidden internal registers to track sys_kstats counters.
+  int       _number;		// kstat disk #
+  ulonglong _nread;		// Number of bytes read
+  ulonglong _nwritten;		// Number of bytes written
+  uint      _reads;		// Number of read operations
+  uint      _writes;		// Number of write operations
+  longlong  _wtime;		// Cumulative wait (pre-service) time
+  longlong  _wlentime;		// Cumulative wait length*time product
+  longlong  _wlastupdate;	// Last time wait queue changed
+  longlong  _rtime;		// Cumulative run (service) time
+  longlong  _rlentime;		// Cumulative run length*time product
+  longlong  _rlastupdate;	// Last time run queue changed
+  uint      _wcnt;		// Count of elements in wait state
+  uint      _rcnt;		// Count of elements in run state
+};
+
+// Define global for tracking raw disk data.
+#define MAX_RAWDISKS	512
+RawDisk		RAW_disk[MAX_RAWDISKS];
+int		RAW_disk_map=0;
+int		RAW_disk_count=0;
+double		RAW_disk_lastupdate;
+
+// Function to scan kstat and map short device names to long device names.
+raw_disk_map() {
+  int i;
+  int j=0;
+  char long_name[16];
+  char short_name[16];
+
+  // SE for 2.6 & 2.7 appears to have a bug where MAX_DISK is too
+  // large when an A1000 raid controller is present.  It's not really
+  // SE as iostat had to be patched for the same bug.  The bug appears
+  // to be tied to a failure to update the kstat interface diskinfo
+  // uses to map short names to long names.  Since raw_disk_update has
+  // already identified how many physical devices are present and they
+  // are listed first we limit our self to mapping the first
+  // RAW_disk_count device name.
+  for (i=0; i<RAW_disk_count; i++) {
+    strcpy(long_name,GLOBAL_disk_info[i].long_name);
+    if (long_name[0] == 'c' && strchr(long_name, 's') == nil) {
+      strcpy(short_name,GLOBAL_disk_info[i].short_name);
+      for (j=0; j<RAW_disk_count;j++) {
+        if (strcmp(RAW_disk[j].short_name, short_name) == 0) {
+          strcpy(RAW_disk[j].long_name, long_name);
+          break;
+        }
+      }
+    }
+  }
+  RAW_disk_map = 0;
+}
+
+raw_disk_update() {
+  int         rdisk;
+  ulong       ul;
+  kstat_ctl_t kc[1];
+  kstat_t     kp[1];
+  kstat_t     nkp[1];
+  kstat_io_t  kio;
+  ulonglong   _nread;
+  ulonglong   _nwritten;
+  uint        _reads;
+  uint        _writes;
+  longlong    _wtime;
+  longlong    _wlentime;
+  longlong    _wlastupdate;
+  longlong    _rtime;
+  longlong    _rlentime;
+  longlong    _rlastupdate;
+  longlong    _wcnt;
+  longlong    _rcnt;
+
+  double      read_writes;
+  double      big_etime;
+  double      elapsed_etime;
+  double      hz_etime;
+  double      nanosecond = NANOSEC;
+  double      update;
+  double      delta;
+  timeval_t   time_update[1];
+  ulong       time_void;
+  char        short_name[8];
+
+  gettimeofday(time_update,time_void);
+  update = time_update[0].tv_sec + (time_update[0].tv_usec / 1000000.0);
+  delta  = update - RAW_disk_lastupdate;
+  RAW_disk_lastupdate = update;
+
+  kc[0] = kstat_open();
+  // Read them.
+  if (kstat_read(kc,kp,0) == -1) {
+    perror("raw_disk_update:kstat_read");
+    exit(1);
+  }
+
+  // Traverse the chain looking for IO events.
+  for (ul=kc[0].kc_chain; ul !=0; ul=nkp[0].ks_next) {
+    struct_fill(nkp[0],ul);
+    if (nkp[0].ks_type == KSTAT_TYPE_IO) {
+      strcpy(short_name, nkp[0].ks_name);
+      if (short_name[0] != 'm' &&
+          short_name[0] != 'n' &&
+          strchr(short_name,',') == nil) {
+        // Try to locate device.
+        for (rdisk=0; rdisk<RAW_disk_count;rdisk++) {
+          if (strcmp(RAW_disk[rdisk].short_name, short_name) == 0) {
+            break;
+          }
+        }
+
+        // It must be new.  Add it!
+        if (rdisk == RAW_disk_count) {
+          // Must be a tape drive or something else.  Schedule device
+          // name map cycle.
+          RAW_disk_map = 1;
+          strcpy(RAW_disk[rdisk].long_name, short_name);
+          strcpy(RAW_disk[rdisk].short_name, short_name);
+          RAW_disk[rdisk]._reads       = 0;
+          RAW_disk[rdisk]._nread       = 0;
+          RAW_disk[rdisk]._rlentime    = 0;
+          RAW_disk[rdisk]._rlastupdate = boot_time;
+          RAW_disk[rdisk]._rcnt        = 0;
+          RAW_disk[rdisk]._writes      = 0;
+          RAW_disk[rdisk]._nwritten    = 0;
+          RAW_disk[rdisk]._wlentime    = 0;
+          RAW_disk[rdisk]._wlastupdate = boot_time;
+          RAW_disk[rdisk]._wcnt        = 0;
+          RAW_disk_count++;
+        }
+
+        // Update the device registers.
+        if (kstat_read(kc,nkp,0) == -1) {
+          perror("raw_disk_update:kstat_read error");
+          exit(1);
+        } else {
+          // Read sys_kstat device IO queue to find out about recent
+          // activity.  We validate data that is returned.  Solaris
+          // 2.6 has occasional glitches when updating certain disks
+          // (c0t0d0) so we cover up the glitches by using data from
+          // the previous cycle.  Eventually, we will get a good
+          // update.  Fixing the data is not necessarily the best
+          // choice.  Currently only kio.nread glitches.  Correcting
+          // the error forces the IOs to get attributed to the next IO
+          // cycle.
+          struct_fill(kio,nkp[0].ks_data);
+          _nread  =  kio.nread;
+          if (RAW_disk[rdisk]._nread > _nread) {
+            _nread = RAW_disk[rdisk]._nread;
+          }
+          _reads = kio.reads;
+	  if (RAW_disk[rdisk]._reads > _reads) {
+            _reads = RAW_disk[rdisk]._reads;
+          }
+          _rlentime    = kio.rlentime;
+          _rtime       = kio.rtime;
+          _rlastupdate = kio.wlastupdate;
+          _rcnt        = kio.rcnt;
+          _nwritten    = kio.nwritten;
+          if (RAW_disk[rdisk]._nwritten > _nwritten) {
+            _nwritten = RAW_disk[rdisk]._nwritten;
+          }
+          _writes = kio.writes;
+          if (RAW_disk[rdisk]._writes > _writes) {
+            _writes = RAW_disk[rdisk]._nwritten;
+          }
+          _wlentime    = kio.wlentime;
+          _wtime       = kio.wtime;
+          _wlastupdate = kio.wlastupdate;
+          _wcnt        = kio.wcnt;
+
+          elapsed_etime = (_wlastupdate - RAW_disk[rdisk]._wlastupdate);
+          if (elapsed_etime > 0)  {
+            hz_etime = elapsed_etime / nanosecond;
+            big_etime = 1024.0 * hz_etime;
+          } else {
+            elapsed_etime = nanosecond;
+            hz_etime = 1.0;
+            big_etime = 1024.0;
+          }
+          RAW_disk[rdisk].reads  =(_reads-RAW_disk[rdisk]._reads)  /hz_etime;
+          RAW_disk[rdisk].kreads =(_nread-RAW_disk[rdisk]._nread)  /big_etime;
+          RAW_disk[rdisk].writes =(_writes-RAW_disk[rdisk]._writes)/hz_etime;
+          RAW_disk[rdisk].kwrites=(_nwritten-RAW_disk[rdisk]._nwritten) / big_etime;
+
+          read_writes = elapsed_etime * (RAW_disk[rdisk].reads + RAW_disk[rdisk].writes) / 1024.0;
+          if (read_writes > 0) {
+            RAW_disk[rdisk].avg_wait = (_wlentime - RAW_disk[rdisk]._wlentime) / read_writes;
+            RAW_disk[rdisk].avg_serv = (_rlentime - RAW_disk[rdisk]._rlentime) / read_writes;
+            RAW_disk[rdisk].service  = RAW_disk[rdisk].avg_wait + RAW_disk[rdisk].avg_serv;
+          } else {
+            RAW_disk[rdisk].avg_wait = 0.0;
+            RAW_disk[rdisk].avg_serv = 0.0;
+            RAW_disk[rdisk].service  = 0.0;
+          }
+
+          // Update the counters.
+          RAW_disk[rdisk].run_percent  = 100.0 * (_rtime  - RAW_disk[rdisk]._rtime) / elapsed_etime;
+          RAW_disk[rdisk].wait_percent = 100.0 * (_wtime - RAW_disk[rdisk]._wtime) / elapsed_etime;
+          RAW_disk[rdisk]._writes      = _writes;
+          RAW_disk[rdisk]._nwritten    = _nwritten;
+          RAW_disk[rdisk]._wlastupdate = _wlastupdate;
+          RAW_disk[rdisk]._wlentime    = _wlentime;
+          RAW_disk[rdisk]._wtime       = _wtime;
+          RAW_disk[rdisk]._wcnt        = _wcnt;
+          RAW_disk[rdisk]._reads       = _reads;
+          RAW_disk[rdisk]._nread       = _nread;
+          RAW_disk[rdisk]._rlastupdate = _rlastupdate;
+          RAW_disk[rdisk]._rlentime    = _rlentime;
+          RAW_disk[rdisk]._rtime       = _rtime;
+          RAW_disk[rdisk]._rcnt        = _rcnt;
+        }
+      }
+    }
+  }
+  kstat_close(kc);
+
+  // Map long device names for any drives that we just discovered.
+  if (RAW_disk_map == 1) {
+    raw_disk_map();
+  }
+}
+#endif
+// RAWDISK_END
+
 // Variables for handling output.
 string		compress = getenv("COMPRESSOR"); // How to compress logs.
 ulong		ofile;				// File pointer to the logging file.
@@ -486,15 +766,16 @@
       interval = atoi(argv[1]);
       break;
     default:
-      fprintf(stderr, "usage: se [Defines] %s [interval]\n", program_name);
-      fprintf(stderr, "%s can use the following environmental variables:\n", program_name);
-      fprintf(stderr, "   setenv OUTDIR      /var/orcallator/logs - log file directory, default stdout\n");
-      fprintf(stderr, "   setenv WEB_SERVER  apache - string to search for number of web servers\n");
-      fprintf(stderr, "   setenv WEB_LOG     /ns-home/httpd-80/logs/access - location of web server log\n");
-      fprintf(stderr, "   setenv GATEWAY     some.where.com - special address to monitor\n");
-      fprintf(stderr, "   setenv SEARCHURL   srch.cgi - match for search scripts, default is search.cgi\n");
-      fprintf(stderr, "   setenv COMPRESSOR  \"gzip -9\" - compress previous day logs using this command\n");
-      fprintf(stderr, "Defines:\n");
+      fprintf(stderr, "usage: se [-Defines] %s [interval]\n", program_name);
+      fprintf(stderr, "The default interval is %d seconds.\n", SAMPLE_INTERVAL);
+      fprintf(stderr, "%s uses the following environmental variables:\n", program_name);
+      fprintf(stderr, "   OUTDIR       directory to write log files, output to stdout if not set\n");
+      fprintf(stderr, "   WEB_SERVER   string to search for number of web servers, i.e. httpd\n");
+      fprintf(stderr, "   WEB_LOG      location of web server access log, i.e. /httpd/logs/access\n");
+      fprintf(stderr, "   GATEWAY      special address to monitor, i.e. some.where.com\n");
+      fprintf(stderr, "   SEARCHURL    match for search scripts, default is search.cgi\n");
+      fprintf(stderr, "   COMPRESSOR   compress previous days logs with this command, i.e. \"gzip -9\"\n");
+      fprintf(stderr, "Add these defines to enable monitoring of specific subsystems:\n");
       fprintf(stderr, "   -DWATCH_WEB        watch web server access logs\n");
       fprintf(stderr, "   -DWATCH_PROXY      use WEB_LOG as a NCSA style proxy log\n");
       fprintf(stderr, "   -DWATCH_SQUID      use WEB_LOG as a Squid log\n");
@@ -611,11 +892,14 @@
   // Initialize the web server watching variables.  Move the file pointer
   // to the end of the web access log and note the current time.
   if (www_log_filename != nil) {
-    www_fd = fopen(www_log_filename, "r");
+    www_fd   = fopen(www_log_filename, "r");
+    www_ino  = 0;
+    www_size = 0;
     if (www_fd != 0) {
-      stat(www_log_filename, www_stat);
-      www_ino  = www_stat[0].st_ino;
-      www_size = www_stat[0].st_size;
+      if (fstat(www_fd, www_stat) == 0) {
+        www_ino  = www_stat[0].st_ino;
+        www_size = www_stat[0].st_size;
+      }
       // Move to the end of the file.
       fseek(www_fd, 0, 2);
     }
@@ -667,6 +951,10 @@
   tmp_rfsproccnt_v2 = kstat$rfsproccnt_v2;
   tmp_rfsproccnt_v3 = kstat$rfsproccnt_v3;
 #endif
+
+#ifdef USE_RAWDISK
+   raw_disk_update();
+#endif
 }
 
 measure_os(long now, tm_t tm_now)
@@ -763,16 +1051,16 @@
   states = "wwwwwwwwwww";
   strftime(tm_buf, sizeof(tm_buf), "%T", tm_now);
 
-  states[0] = state_char(lr_disk$dr.state); 
-  states[1] = state_char(lr_net$nr.state);     
-  states[2] = state_char(lr_rpcclient$r.state); 
-  states[3] = state_char(lr_swapspace$s.state);     
-  states[4] = state_char(lr_ram$ram.state);    
-  states[5] = state_char(lr_kmem$kmem.state);   
-  states[6] = state_char(lr_cpu$cpu.state);    
-  states[7] = state_char(lr_mutex$m.state);     
-  states[8] = state_char(lr_dnlc$dnlc.state);   
-  states[9] = state_char(lr_inode$inode.state);   
+  states[0] = state_char(lr_disk$dr.state);
+  states[1] = state_char(lr_net$nr.state);
+  states[2] = state_char(lr_rpcclient$r.state);
+  states[3] = state_char(lr_swapspace$s.state);
+  states[4] = state_char(lr_ram$ram.state);
+  states[5] = state_char(lr_kmem$kmem.state);
+  states[6] = state_char(lr_cpu$cpu.state);
+  states[7] = state_char(lr_mutex$m.state);
+  states[8] = state_char(lr_dnlc$dnlc.state);
+  states[9] = state_char(lr_inode$inode.state);
   states[10]= state_char(lr_tcp$tcp.state);
 
   put_output(" timestamp",  sprintf("%10d", now));
@@ -825,7 +1113,7 @@
       // the previous and current mpid over a 5 second interval to
       // calculate the long interval difference.
       mpid_current += mpid5_diff;
-      mpid_now      = mpid5_now;   
+      mpid_now      = mpid5_now;
     }
     else {
       sleep(sleep_till - now);
@@ -850,11 +1138,13 @@
   // double, so cast everything to double using + 0.0.
   put_output(" usr%",    sprintf("%5.1f", pvm.user_time + 0.0));
   put_output(" sys%",    sprintf("%5.1f", pvm.system_time + 0.0));
+  put_output(" wio%",    sprintf("%5.1f", pvm.wait_time + 0.0));
+  put_output("idle%",    sprintf("%5.1f", pvm.idle_time + 0.0));
   put_output(" 1runq",   sprintf("%6.2f", tmp_kstat_misc.avenrun_1min/256.0));
   put_output(" 5runq",   sprintf("%6.2f", tmp_kstat_misc.avenrun_5min/256.0));
   put_output("15runq",   sprintf("%6.2f", tmp_kstat_misc.avenrun_15min/256.0));
   put_output("#proc",    sprintf("%5lu",  tmp_kstat_misc.nproc));
-  put_output("scanrate", sprintf("%8.3f", pvm.scan));
+  put_output("scanrate", sprintf("%8.3f", pvm.scan + 0.0));
 
   // Calculate the rate of new process spawning.
   if (can_read_kernel != 0) {
@@ -890,9 +1180,9 @@
   current_count = 0;
   for (i=0; i<tmp_nr.net_count; i++) {
     // Skip unused interfaces.
-//    if (GLOBAL_net[i].up == 0) {
-//      continue;
-//    }
+//  if (GLOBAL_net[i].up == 0) {
+//    continue;
+//  }
     ++current_count;
     put_output(sprintf("%5sIpkt/s", tmp_nr.names[i]),
 	       sprintf("%11.3f", GLOBAL_net[i].ipackets));
@@ -1002,6 +1292,13 @@
       if (tmp_mnt.mnt_mountp =~ "^/cdrom/") {
         continue;
       }
+
+      // Skip snapshot file systems to avoid output format changes as
+      // they are mounted and umounted.
+      if (tmp_mnt.mnt_mountp =~ "^/snapshots/") {
+        continue;
+      }
+
       if (statvfs(tmp_mnt.mnt_mountp, vfs_array) == -1) {
         continue;
       }
@@ -1069,6 +1366,7 @@
   double total_writek;
   int    previous_count = -1;
   int    i;
+  int    disk_count;
 
   mean_disk_busy = 0.0;
   peak_disk_busy = 0.0;
@@ -1076,20 +1374,48 @@
   total_writes   = 0.0;
   total_readk    = 0.0;
   total_writek   = 0.0;
+  disk_count     = 0;
+
+#ifdef USE_RAWDISK
+  for (i=0; i<RAW_disk_count; i++) {
+    // Block the listing of tape drives for now.
+    if (RAW_disk[i].short_name[1] == 't' && RAW_disk[i].short_name[0] == 's') {
+      continue;
+    }
+    // Block the listing of floppy drives for now.
+    if (RAW_disk[i].short_name[0] == 'f' && RAW_disk[i].short_name[1] == 'd') {
+      continue;
+    }
+    disk_count++;
+    put_output(sprintf("disk_runp_%s", RAW_disk[i].long_name),
+               sprintf("%16.5f", RAW_disk[i].run_percent));
+    total_reads    += RAW_disk[i].reads;
+    total_writes   += RAW_disk[i].writes;
+    total_readk    += RAW_disk[i].kreads;
+    total_writek   += RAW_disk[i].kwrites;
+    mean_disk_busy += RAW_disk[i].run_percent;
+    if (RAW_disk[i].run_percent > peak_disk_busy) {
+       peak_disk_busy = RAW_disk[i].run_percent;
+    }
+  }
+#else
   for (i=0; i<GLOBAL_disk_count; i++) {
+    disk_count++;
     put_output(sprintf("disk_runp_%s", GLOBAL_disk[i].info.long_name),
                sprintf("%16.5f", GLOBAL_disk[i].run_percent));
-    total_reads     += GLOBAL_disk[i].reads;
-    total_writes    += GLOBAL_disk[i].writes;
-    total_readk     += GLOBAL_disk[i].kreads;
-    total_writek    += GLOBAL_disk[i].kwrites;
+    total_reads    += GLOBAL_disk[i].reads;
+    total_writes   += GLOBAL_disk[i].writes;
+    total_readk    += GLOBAL_disk[i].kreads;
+    total_writek   += GLOBAL_disk[i].kwrites;
     mean_disk_busy += GLOBAL_disk[i].run_percent;
     if (GLOBAL_disk[i].run_percent > peak_disk_busy) {
       peak_disk_busy = GLOBAL_disk[i].run_percent;
     }
   }
-  if (GLOBAL_disk_count != 0) {
-    mean_disk_busy = mean_disk_busy/GLOBAL_disk_count;
+#endif
+
+  if (disk_count != 0) {
+    mean_disk_busy = mean_disk_busy/disk_count;
   }
 
   put_output("disk_peak", sprintf("%9.3f", peak_disk_busy));
@@ -1101,9 +1427,9 @@
 
   // If the number of disks has changed, say due to a add_drv, then print
   // new headers.
-  if (previous_count != GLOBAL_disk_count) {
+  if (previous_count != disk_count) {
     print_header   = 1;
-    previous_count = GLOBAL_disk_count;
+    previous_count = disk_count;
   }
 }
 #endif
@@ -1274,7 +1600,7 @@
 #elif WATCH_YAHOO
   /*
    * Yahoo log format.  Fields in square brackets will only appear in the
-   * log file if the data actually exists (ie. you will never see a null
+   * log file if the data actually exists (i.e. you will never see a null
    * Referrer field).  Further, fields labelled here with "(CONFIG)" will
    * only appear if they are enabled via the YahooLogOptions configuration
    * directive.
@@ -1343,7 +1669,7 @@
   if (ishead == 0) {
     dwnld_totalz += z;
   }
-  
+
 #else	/* common or netscape proxy formats */
   strtok(nil, " ");		/* -.           */
   strtok(nil, " ");		/* -.           */
@@ -1439,7 +1765,7 @@
       break;
   }
   word = strtok(nil, " [");		/* [transfer total time x.xxx. */
-  if (word == nik) {
+  if (word == nil) {
     return;
   }
   xf = atof(word);
@@ -1528,42 +1854,48 @@
       /*
        * See if the file has been switched or truncated.
        */
-      stat(www_log_filename, www_stat);
-      if (www_ino != www_stat[0].st_ino || www_size > www_stat[0].st_size) {
-        if (www_fd != 0) {
-          /* Close the old log file. */
-          fclose(www_fd);
-        }
+      if (stat(www_log_filename, www_stat) == 0) {
+        if (www_ino != www_stat[0].st_ino || www_size > www_stat[0].st_size) {
+          /*
+           * Close the old log file.
+           */
+          if (www_fd != 0) {
+            fclose(www_fd);
+          }
 
-        /*
-         * The log file has changed, open the new one.
-         */
-        www_fd = fopen(www_log_filename, "r");
-        if (www_fd != 0) {
-          www_ino = www_stat[0].st_ino;
-          buf[BUFSIZ-1] = 127;
-          while(fgets(buf, BUFSIZ, www_fd) != nil) {
-            httpops += 1.0;
-            if (www_gatelen > 0) {
-              if (strncmp(buf, www_gateway, www_gatelen) == 0) {
-                gateops += 1.0;
+          /*
+           * The log file has changed, open the new one.
+           */
+          www_fd = fopen(www_log_filename, "r");
+          if (www_fd != 0) {
+            fstat(www_fd, www_stat);
+            www_ino = www_stat[0].st_ino;
+            buf[BUFSIZ-1] = 127;
+            while(fgets(buf, BUFSIZ, www_fd) != nil) {
+              httpops += 1.0;
+              if (www_gatelen > 0) {
+                if (strncmp(buf, www_gateway, www_gatelen) == 0) {
+                  gateops += 1.0;
+                }
               }
-            }
-            accesslog(buf);
+              accesslog(buf);
 
-            /*
-             * If the line is longer than the buffer, then ignore the rest
-             * of the line.
-             */
-            while (buf[BUFSIZ-1] == 0    &&
-                   buf[BUFSIZ-2] != '\n') {
-              buf[BUFSIZ-1] = 127;
-              if (fgets(buf, BUFSIZ, www_fd) == nil) {
-                break;
+              /*
+               * If the line is longer than the buffer, then ignore
+               * the rest of the line.
+               */
+              while (buf[BUFSIZ-1] == 0    &&
+                     buf[BUFSIZ-2] != '\n') {
+                buf[BUFSIZ-1] = 127;
+                if (fgets(buf, BUFSIZ, www_fd) == nil) {
+                  break;
+                }
               }
             }
           }
         }
+        /* Remember size for next time. */
+        www_size = www_stat[0].st_size;
       }
 
       www5_now      = gethrtime();
@@ -1574,9 +1906,6 @@
         httpops5 = dtmp;
       }
       lastops = httpops;
-
-      /* Remember size for next time. */
-      www_size = www_stat[0].st_size;
     }
   }
   else {

Modified: trunk/orca/orcallator/orcallator_column.pl
==============================================================================
--- trunk/orca/orcallator/orcallator_column.pl	(original)
+++ trunk/orca/orcallator/orcallator_column.pl	Sat Jul 13 21:25:45 2002
@@ -1,13 +1,14 @@
 # orcallator_column: display selected columns from orcallator output.
 #
-# Copyright (C) 1998, 1999 Blair Zajac and GeoCities, Inc.
+# Copyright (C) 1998-2001 Blair Zajac and Yahoo!/GeoCities, Inc.
 
 use strict;
 
 $| = 1;
 
-# This is the list of columns to plot.
-my @column_titles;
+# This is the list of regular expressions that match column names to
+# plot.
+my @column_regexs;
 
 # Plot the maximum data.
 my $display_max = 0;
@@ -16,12 +17,19 @@
 my $col_width             = 9;
 my $string_format         = "%${col_width}s";
 my $number_format         = "%${col_width}.2f";
-my @default_column_titles = qw(httpop/s http/p5s httpb/s NoCP);
+my @default_column_regexs = qw(httpop/s http/p5s httpb/s NoCP);
 
 while (@ARGV and $ARGV[0] =~ /^-\w/) {
   my $arg = shift;
   if ($arg eq '-c') {
-    push(@column_titles, shift);
+    unless (@ARGV) {
+      die "$0: no argument for -c.\n";
+    }
+    my $value = shift;
+    unless (defined $value) {
+      die "$0: undefined value passed to -c.\n";
+    }
+    push(@column_regexs, $value);
   }
   elsif ($arg eq '-m') {
     $display_max = 1;
@@ -35,18 +43,23 @@
   -m instead of printing all the data, show only the maximum value
 If no -c options are given, then by default the following column titles
 are used:
-  @default_column_titles
+  @default_column_regexs
+If you want to process standard input, then you must list - on the
+command line.
 END
   exit 1;
 }
 
 # If no column titles were set, then choose these.
- at column_titles = @default_column_titles unless @column_titles;
+ at column_regexs = @default_column_regexs unless @column_regexs;
+
+# Compile the regular expressions.
+my @column_res = map { qr/$_/ } @column_regexs;
 
 # Unless the maximum is choosen, add the date to the list of columns.
-unshift(@column_titles, 'locltime');
+unshift(@column_regexs, 'locltime');
 
-# Find the length of the longest file.
+# Find the string length of the longest filename.
 my $col1_length = 0;
 foreach my $file (@ARGV) {
   my $len = length($file);
@@ -56,47 +69,55 @@
 
 for (my $a=0; $a<@ARGV; ++$a) {
   my $file = $ARGV[$a];
-  open(FILE, $file) or die "$0: unable to open `$file' for reading: $!\n";
+  open(FILE, $file) or
+    die "$0: unable to open `$file' for reading: $!\n";
 
-  my @line = split(' ', <FILE>);
+  # Read the file and on each line look for redefinitions of the
+  # column names.
+  my @column_titles;
   my @column_pos;
-  my @data;
+  my $column_pos_set;
+  my %max_values;
+  while (<FILE>) {
+    my @line = split;
 
-  # Find the columns that contain the names.
-  my @col_titles = @column_titles;
-  for (my $i=0; $i<@col_titles; ++$i) {
-    my $name = $col_titles[$i];
-    my $col = -1;
-    for (my $j=0; $j<@line; ++$j) {
-      if ($line[$j] =~ /$name/) {
-        $col = $j;
-        $col_titles[$i] = $line[$j];
-        last;
+    # If the line has the string timestamp in it, then use it to find
+    # the proper column number for the requested data.
+    if (/timestamp/) {
+      @column_titles = ();
+      @column_pos    = ();
+      foreach my $regex (@column_regexs) {
+        my $re = qr/$regex/;
+        for (my $j=0; $j<@line; ++$j) {
+          my $column_title = $line[$j];
+          if ($column_title =~ $re) {
+            push(@column_pos,    $j);
+            push(@column_titles, $column_title);
+            unless (defined $max_values{$column_title}) {
+              $max_values{$column_title} = -1e20;
+            }
+          }
+        }
       }
+      $column_pos_set = 1;
+      next;
     }
-    die "$0: cannot column matching `$name' in $file.\n" if $col == -1;
-    push(@column_pos, $col);
-    push(@data, -1e20);
-  }
 
-  printf $col1_format, "Machine";
-  grep { printf "$string_format ", $_ } @col_titles;
-  print "\n";
+    next unless $column_pos_set;
 
-  while (<FILE>) {
-    my @line = split;
     my @d = @line[@column_pos];
     if ($display_max) {
-      for (my $i=0; $i<@data; ++$i) {
+      for (my $i=0; $i<@d; ++$i) {
+        my $column_title = $column_titles[$i];
         if (is_numeric($d[$i])) {
-          $data[$i] = $d[$i] if $d[$i] > $data[$i];
-        }
-        else {
-          $data[$i] = $d[$i];
+          if ($d[$i] > $max_values{$column_title}) {
+            $max_values{$column_title} = $d[$i];
+          }
+        } else {
+          $max_values{$column_title} = $d[$i];
         }
       }
-    }
-    else {
+    } else {
       printf $col1_format, $file;
       foreach my $d (@d) {
         printf is_numeric($d) ? "$number_format " : "$string_format ", $d;
@@ -105,12 +126,17 @@
     }
   }
 
+  printf $col1_format, "Machine";
+  grep { printf "$string_format ", $_ } @column_titles;
+  print "\n";
+
   close(FILE);
 
   if ($display_max) {
     printf $col1_format, $file;
-    foreach my $d (@data) {
-      printf is_numeric($d) ? "$number_format " : "$string_format ", $d;
+    foreach my $title (@column_titles) {
+      my $max = $max_values{$title};
+      printf is_numeric($max) ? "$number_format " : "$string_format ", $max;
     }
     print "\n";
   }
@@ -127,13 +153,12 @@
   $! = 0;
   my($num, $unparsed) = strtod($str);
   if (($str eq '') || ($unparsed != 0) || $!) {
-    return undef;
+    return;
   } else {
     return $num;
   }
 }
 
 sub is_numeric {
-  my $a = shift;
-  defined getnum($a);
+  defined getnum(shift);
 }

Modified: trunk/orca/orcallator/start_orcallator.sh.in
==============================================================================
--- trunk/orca/orcallator/start_orcallator.sh.in	(original)
+++ trunk/orca/orcallator/start_orcallator.sh.in	Sat Jul 13 21:25:45 2002
@@ -13,25 +13,41 @@
 UNAME=@UNAME@
 ORCALLATOR_DIR=@ORCALLATOR_DIR@
 SE=@SE@
-WATCH_WEB="@WATCH_WEB@"
+
+# WEB_LOG contains the location of the web server log file that
+# orcallator.se should read.
 WEB_LOG=@WEB_LOG@
 
+# WATCH_WEB contains the command line options to SE to tell
+# orcallator.se the format of the web server logs.
+WATCH_WEB="-DWATCH_WEB"               # For NCSA style access log
+WATCH_WEB="-DWATCH_WEB -DWATCH_PROXY" # For proxy NCSA style access log
+WATCH_WEB="-DWATCH_WEB -DWATCH_SQUID" # For Squid style access log
+WATCH_WEB="@WATCH_WEB@"
+
+# These are the various patch defines to make sure SE works around
+# various problems.
+SE_PATCHES=
+#SE_PATCHES="$SE_PATCHES -DLE_PATCH"
+#SE_PATCHES="$SE_PATCHES -DHME_PATCH"
+#SE_PATCHES="$SE_PATCHES -DHME_PATCH_IFSPEED"
+
 # Check if the SE executable was found upon configure.
 if test -z "$SE"; then
-  echo "When you configured Orca the se executable was not found.  If you"
-  echo "do not have the SE toolkit installed on your system, then follow"
-  echo "the steps in section 8 of INSTALL."
-  echo ""
-  echo "Once you have the SE toolkit installed on your system, then either"
-  echo "rerun configure so that it finds se, or edit start_orcallator.sh"
-  echo "and define SE to the location of se."
+  cat <<END 1>&2
+When you configured Orca the se executable was not found.  If you
+do not have the SE toolkit installed on your system, then follow
+the steps in section 10 of INSTALL file that came with Orca.
+
+Once you have the SE toolkit installed on your system, then either
+rerun configure so that it finds se, or edit start_orcallator.sh
+and define SE to the location of se.
+END
   exit 1
 fi
 
 if test ! -x "$SE"; then
-  echo "The SE executable at"
-  echo "  $SE"
-  echo "does not exist or is not executable.  Please correct this problem."
+  echo "$0: the SE executable at $SE does not exist or is not executable." 1>&2
   exit 1
 fi
 
@@ -39,6 +55,12 @@
 # anything past the first `.'.
 uname=`$UNAME -n | $CUT -d. -f1`
 
+# Make sure the hostname can be found.
+if test -z "$uname"; then
+  echo "$0: cannot determine the hostname of this system." 1>&2
+  exit 1
+fi
+
 # The directory these files go into is $ORCALLATOR_DIR/HOSTNAME
 OUTDIR=$ORCALLATOR_DIR/$uname
 
@@ -48,7 +70,7 @@
 # Check if orcallator is already running.
 pids=`/usr/ucb/ps auxww | $AWK '/orcallator.se/ && !/awk/ {print $2}'`
 if test "$pids" != ""; then
-  echo "Orcallator already running.  Exiting."
+  echo "$0: orcallator already running." 1>&2
   exit 1
 fi
 
@@ -67,13 +89,13 @@
 fi
 
 if test ! -d $OUTDIR; then
-  echo "Unable to create $OUTDIR/" 1>&2
+  echo "$0: unable to create $OUTDIR/" 1>&2
   exit 2
 fi
 
 # Now start the logging.
 echo "Starting logging"
-$SE $LE_PATCH -DWATCH_OS $WATCH_WEB $libdir/orcallator.se &
+nohup $SE $SE_PATCHES -DWATCH_OS $WATCH_WEB $libdir/orcallator.se &
 
 # Write the PID of orcallator to a file to make killing easier.
 pid=$!

Modified: trunk/orca/config/PerlHead1.in
==============================================================================
--- trunk/orca/config/PerlHead1.in	(original)
+++ trunk/orca/config/PerlHead1.in	Sat Jul 13 21:25:45 2002
@@ -1,4 +1,2 @@
 #!@PERL@ -w # -*- perl -*-
 
-require 5.004_01;
-

Modified: trunk/orca/config/PerlHead2.in
==============================================================================
--- trunk/orca/config/PerlHead2.in	(original)
+++ trunk/orca/config/PerlHead2.in	Sat Jul 13 21:25:45 2002
@@ -5,5 +5,3 @@
 & eval 'exec perl -w -S $0 $argv:q'
     if 0;
 
-require 5.004_01;
-

Modified: trunk/orca/TODO
==============================================================================
--- trunk/orca/TODO	(original)
+++ trunk/orca/TODO	Sat Jul 13 21:25:45 2002
@@ -1,16 +1,27 @@
-XXX Fix the bug where if a legend is listed in a plot {} then the
-XXX number of colored boxes in the generated plot are more than the
-XXX data that appears there.
+* Bug: If there is no match made in a find_files, then handle this case.
+  See the message in my Sent box at 11/8/2000 4:00 PM with a subject
+  Unable to view orca graphs.
 
 This is a pretty comprehensive to-do list for Orca and the related data
 gathering tools.  Any comments and additions to this list are welcome.
 
-To motivate the discussion of this to do list, let me give some background
-on our setup.  GeoCities site has over 100 hosts.  I've been running
-orcallator.se on some hosts since September 1998 that have stored over
-300 source text files. Currently I have 34472 files using 7.3 gigabytes
-of storage.  I have 9 different orcallator.cfg for different classes
-of machines.
+To motivate the discussion of this to do list, let me give some
+background on our setup.  GeoCities site has over 100 hosts.  I've
+been running orcallator.se on some hosts since September 1998 that
+have stored over 300 source text files. Currently I have 34472 files
+using 7.3 gigabytes of storage.  I have 9 different orcallator.cfg for
+different classes of machines.
+
+* Orca: Have an install option just for orcallator.se and not the
+        Orca whole pacckage.
+
+* Orca: Add flag to put Orca in background or daemonize it.
+
+* Orca: bug fix:
+
+	Fix the bug where if a legend is listed in a plot {} then the
+	number of colored boxes in the generated plot are more than
+	the data that appears there.
 
 * Orca: Load arbitrarily formatted source text files.
 
@@ -251,6 +262,11 @@
 	Since orcallator.se measures HTTP proxy and caching statistics,
 	update orcallator.cfg.in to display these data sets.
 
+* orcallator.se: Temperature measurements
+
+	Since /usr/platform/sun4u/sbin/prtdiag -v measures the ambient
+	and CPU temperature, get orcallator.se to measure this data.
+
 * Orca:
 
 	Do what it takes to remove the same Ethernet port listings in
@@ -338,7 +354,7 @@
           Also, suggestions for what to do if things are bad.
         + Finer resolution (more graphs) on each Data Set.
           For example, a graph for each disk, when you click on that graph
-          you get a graph for each: 
+          you get a graph for each:
           Bytes read
           Bytes written
           KBytes read
@@ -384,7 +400,7 @@
           or swap thrashing.
           Maybe we should plot the sr field of vmstat. p.329
         + Page Usage
-          Unless you know how memory subsystems work, 
+          Unless you know how memory subsystems work,
           this graph is hard to read. The only obvious
           thing this graph tells you is if the Free List
           is too small. The Free List can be fine, but you

Modified: trunk/orca/INSTALL
==============================================================================
--- trunk/orca/INSTALL	(original)
+++ trunk/orca/INSTALL	Sat Jul 13 21:25:45 2002
@@ -2,8 +2,9 @@
 
  1) Install Perl 5.004_01 or later.
 
- 2) Decide where Orca's binaries, RRD, HTML, and orcallator directories
-    will reside.  Make sure performance concerns are handled.
+ 2) Decide where Orca's binaries, RRD, HTML, and orcallator
+    directories will reside.  Make sure performance concerns are
+    handled.
 
  3) Determine which Perl modules need compiling and installing.
     Optionally download newer versions of these modules.
@@ -36,16 +37,21 @@
 
  1) Install Perl 5.004_01 or later.
 
-    This step is too large to go into here.  The bottom line is to follow
-    the instructions at
+    This step is too large to go into here.  The bottom line is to
+    follow the instructions at
 
-       http://language.perl.com/info/software.html
+       http://www.perl.com/pub/language/info/software.html
 
- 2) Decide where Orca's binaries, RRD, HTML, and orcallator directories
-    will reside.  Make sure performance concerns are handled.
+    or download a binary package from
 
-    First choose the location where Orca will be installed.  By default,
-    Orca will install into the following structure:
+       http://aspn.activestate.com/ASPN/Downloads/ActivePerl/
+
+ 2) Decide where Orca's binaries, RRD, HTML, and orcallator
+    directories will reside.  Make sure performance concerns are
+    handled.
+
+    First choose the location where Orca will be installed.  By
+    default, Orca will install into the following structure:
 
     $prefix                     Prefix, set with --prefix=
     $prefix/bin                 Binaries, set with --bindir=
@@ -54,8 +60,8 @@
     $prefix/var/orca/rrd        RRD directory, set with --with-rrd-dir
     $prefix/var/orca/orcallator Orcallator directory, set with --with-orcallator-dir
 
-    The HTML output directory is not set by default and must be specified
-    by the Orca administrator.
+    The HTML output directory is not set by default and must be
+    specified by the Orca administrator.
 
     By default $prefix is set to /usr/local.  The -- arguments shown
     above should be given to the configure script described below
@@ -64,58 +70,99 @@
     --prefix=/opt/orca to the configure script.
 
     Because Orca is extremely IO intensive, I recommend the following
-    architecture.  Choose one host that can locally mount all the RRD data
-    files and the directory containing the HTML and image files that are
-    viewed by Orca users.  If these two locations must be on separate
-    hosts and one directory must be NFS mounted to the Orca host, then
-    I recommend that the RRD data file be local instead of the HTML and
-    image files, since the RRD files are much more read/write intensive.
+    architecture.  Choose one host that can locally mount all the RRD
+    data files and the directory containing the HTML and image files
+    that are viewed by Orca users.  If these two locations must be on
+    separate hosts and one directory must be NFS mounted to the Orca
+    host, then I recommend that the RRD data file be local instead of
+    the HTML and image files, since the RRD files are much more
+    read/write intensive.
 
     If you are going to use the orcallator Orca addon to monitor your
-    Sun Solaris systems, then you will in addition need to decide where
-    to have orcallator store its data files.  By default, these data
-    files are written to once every 5 minutes, so IO is not an issue.
-    The issue here is that orcallator needs to run as root and all of
-    the orcallator output files from all your hosts need to be written
-    into the same NFS shared directory that Orca can read.  It is not too
-    important that the directory that orcallator writes into be mounted
-    locally on the machine that Orca will run on, since Orca will only
-    read each file every five minutes.
-
-    If you are running orcallator on a system running a web, proxy,
-    or Squid server, you can have orcallator watch the logs generated
-    by these programs.  In this case, note the location of the log file
+    Sun Solaris systems, then you will in addition need to decide
+    where to have orcallator store its data files.  By default, these
+    data files are written to once every 5 minutes, so IO is not an
+    issue.  The issue here is that orcallator needs to run as root and
+    all of the orcallator output files from all your hosts need to be
+    written into the same NFS shared directory that Orca can read.  It
+    is not too important that the directory that orcallator writes
+    into be mounted locally on the machine that Orca will run on,
+    since Orca will only read each file every five minutes.
+
+    If you are running orcallator on a system running a web, proxy, or
+    Squid server, you can have orcallator watch the logs generated by
+    these programs.  In this case, note the location of the log file
     for the configure script.
 
- 3) Determine which Perl modules need compiling and installing.
+ 3) Configure Orca.
+
+    Now that you have decided where the RRD, HTML, and optionally the
+    orcallator data files and the web server access logs, are located,
+    run the configure script with the following arguments:
+
+    % ./configure --prefix=ORCA_PREFIX_DIRECTORY \
+                  --with-rrd-dir=RRD_DIR_LOCATION \
+                  --with-html-dir=HTML_DIR_LOCATION \
+                  --with-orcallator-dir=ORCALLATOR_DIR_LOCATION \
+                  --with-TYPE-log=LOG_LOCATION
+
+    If you choose nothing else, the --with-html-dir must always be
+    used, otherwise configure will fail.
+
+    If you use a web, proxy, or Squid server, you can have orcallator
+    gather statistics from the log file.  Use this table to decide
+    which configure option to use.  Note that the Apache and NCSA
+    servers use the Common Log Format.
+
+    Log Type                                   Configure Option
+    ----------------------------------------------------------------
+    Common Log Format                          --with-ncsa-log=FILE
+    Common Log Format with Proxy Information   --with-proxy-log=FILE
+    Squid Log Format                           --with-squid-log=FILE
+
+    Configure will let you use only one of these --with-TYPE-log
+    options.
+
+    The configure script will find where your version of Perl and some
+    other assorted programs are located.  It will also determine if
+    you have the necessary Perl modules to run Orca.  If it does not
+    find the required modules, the modules that are included with the
+    Orca distribution will be built.
+
+    Configure will also determine if you run one of the operating
+    systems where a shared librrd.so library will be built and
+    installed in $libdir.
+
+ 4) Determine which Perl modules need compiling and installing.
     Optionally download newer versions of these modules.
 
-    Orca requires the following Perl modules at the specified versions:
+    Orca requires the following Perl modules at the specified
+    versions:
 
     Name			Required Version	Included With Orca
-    -----------------------------------------------------------------------
+    ----------------------------------------------------------------------
     Data::Dumper		2.101 or greater	2.101
-    Digest::MD5			2.09 or greater		2.09
+    Digest::MD5			2.13 or greater		2.13
     Math::IntervalSearch	1.05 or greater		1.05
-    RRDs			1.0.13 or greater	1.0.13
-    Storable			0.6.9 or greater	0.6.9
+    RRDs			1.0.33 or greater	1.0.33
+    Storable			1.0.11 or greater	1.0.11
 
     All five of these modules are included with the Orca distribution
-    in the packages directory.  When you configure Orca in step 4),
+    in the packages directory.  When you configure Orca in step 3),
     configure will determine if you need any of these modules compiled
     and installed.  configure will then modify the packages/Makefile
     file to only build those modules that need to be installed.
 
-    All of the modules except for Math::IntervalSearch require a compiler
-    and generate shared libraries by default.
+    All of the modules except for Math::IntervalSearch require a
+    compiler and generate shared libraries by default.
 
     If you wish to download and install modules that have been updated
-    since this Orca package has been assembled, please use the following
-    information.
+    since this Orca package has been assembled, please use the
+    following information.
 
     Data::Dumper
 
-      http://www.perl.com/CPAN/authors/id/GSAR/Data-Dumper-2.101.tar.gz
+      http://www.perl.com/CPAN/authors/id/G/GS/GSAR/Data-Dumper-2.101.tar.gz
 
       % gunzip -c Data-Dumper-2.101.tar.gz | tar xvf -
       % cd Data-Dumper-2.101
@@ -126,10 +173,10 @@
 
     Digest::MD5
 
-      http://www.perl.com/CPAN/authors/id/GAAS/Digest-MD5-2.09.tar.gz
+      http://www.perl.com/CPAN/authors/id/G/GA/GAAS/Digest-MD5-2.13.tar.gz
 
-      % gunzip -c Digest-MD5-2.09.tar.gz | tar xvf -
-      % cd Digest-MD5-2.09
+      % gunzip -c Digest-MD5-2.13.tar.gz | tar xvf -
+      % cd Digest-MD5-2.13
       % perl Makefile.PL
       % make
       % make test
@@ -137,7 +184,6 @@
 
     Math::IntervalSearch
 
-      ftp://ftp.gps.caltech.edu/pub/blair/Perl/Math-Interpolate-1.05.tar.gz
       http://www.perl.com/CPAN/authors/id/B/BZ/BZAJAC/Math-Interpolate-1.05.tar.gz
 
       % gunzip -c Math-Interpolate-1.05.tar.gz | tar xvf -
@@ -149,15 +195,15 @@
 
     RRDs
 
-      http://ee-staff.ethz.ch/~oetiker/webtools/rrdtool/pub/
+      http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/pub
 
-      RRDs is the Perl module that comes with RRDtool, a package written
-      by Tobias Oetiker.
+      RRDs is the Perl module that comes with RRDtool, a package
+      written by Tobias Oetiker.
 
       % gunzip -c rrdtool-?.??.??.tar.gz | tar xvf -
       % cd rrdtool-?.??.??
       % sh configure --verbose
-      % make                                [ To optimize: make CFLAGS=-O ]
+      % make
       % cd perl-shared
       % make test
       % make install
@@ -167,52 +213,15 @@
 
     Storable
 
-      http://www.perl.com/CPAN/authors/id/RAM/Storable-0.6.9.tar.gz
+      http://www.perl.com/CPAN/authors/id/R/RA/RAM/Storable-1.0.11.tar.gz
 
-      % gunzip -c Storable-0.6.9.tar.gz | tar xvf -
-      % cd Storable-0.6.9
+      % gunzip -c Storable-1.0.11.tar.gz | tar xvf -
+      % cd Storable-1.0.11
       % perl Makefile.PL
       % make
       % make test
       % make install
 
- 4) Configure Orca.
-
-    Now that you have decided where the RRD, HTML, and optionally the
-    orcallator data files and the web server access logs, are located,
-    run the configure script with the following arguments:
-
-    % ./configure --prefix=ORCA_PREFIX_DIRECTORY \
-                  --with-rrd-dir=RRD_DIR_LOCATION \
-                  --with-html-dir=HTML_DIR_LOCATION \
-                  --with-orcallator-dir=ORCALLATOR_DIR_LOCATION \
-                  --with-TYPE-log=LOG_LOCATION
-
-    If you choose nothing else, the --with-html-dir must always be used,
-    otherwise configure will fail.
-
-    If you use a web, proxy, or Squid server, you can have orcallator
-    gather statistics from the log file.  Use this table to decide which
-    configure option to use:
-
-    Log Type                                    Configure Option
-    -----------------------------------------------------------------
-    NCSA/Common Log Format                      --with-ncsa-log=FILE
-    Common Log Format with Proxy Information    --with-proxy-log=FILE
-    Squid Log Format                            --with-squid-log=FILE
-
-    Configure will let you use only one of these --with-TYPE-log options.
-
-    The configure script will find where your version of Perl and some
-    other assorted programs are located.  It will also determine if you
-    have the necessary Perl modules to run Orca.  If it does not find
-    the required modules, the modules that are included with the Orca
-    distribution will be built.
-
-    Configure will also determine if you run one of the operating
-    systems where a shared librrd.so library will be built and installed
-    in $libdir.
-
  5) Make Orca and any necessary Perl modules.
 
     To make Orca and these Perl modules run the following command:
@@ -221,8 +230,8 @@
 
  6) Test if the Perl modules properly compiled.
 
-    To check if the Perl modules were properly compiled run the following
-    command:
+    To check if the Perl modules were properly compiled run the
+    following command:
 
     % make test_modules
 
@@ -239,36 +248,36 @@
     HTML and image filenames that Orca creates have changed names.
     There are two separate issues.
 
-    The first is that the naming scheme for all generated HTML and image
-    (either PNG or GIF) files have changed.  Unless you want to leave
-    files with old names around wasting disk space, I recommend you cd
-    into your HTML directories and delete all files there.
-
-    The second issue is that the RRD data files have also changed names
-    and unless you want to reload all of your source data files and
-    waste more disk space on unused RRD files, I suggest that you run
-    following command:
+    The first is that the naming scheme for all generated HTML and
+    image (either PNG or GIF) files have changed.  Unless you want to
+    leave files with old names around wasting disk space, I recommend
+    you cd into your HTML directories and delete all files there.
+
+    The second issue is that the RRD data files have also changed
+    names and unless you want to reload all of your source data files
+    and waste more disk space on unused RRD files, I suggest that you
+    run following command:
 
     % make upgrade
 
     This will look through the all of the directories that Orca will
     install into and use (namely the $prefix, $exec_prefix, $bindir,
-    $libdir, $ORCALLATOR_DIR, and $RRD_DIR directories) and perform any
-    necessary file renaming.
+    $libdir, $ORCALLATOR_DIR, and $RRD_DIR directories) and perform
+    any necessary file renaming.
 
-    If you have some new directories that are not included in the above
-    list directories that make upgrade will cover, you can run the
-    src/upgrage_installation program with a list of directories to parse
-    and rename.  If you want to see what upgrage_installation will rename
-    without actually doing the rename, give it the -n option before any
-    directory names.
+    If you have some new directories that are not included in the
+    above list directories that make upgrade will cover, you can run
+    the src/upgrage_installation program with a list of directories to
+    parse and rename.  If you want to see what upgrage_installation
+    will rename without actually doing the rename, give it the -n
+    option before any directory names.
 
     Here is a description of the various differences between versions.
 
     0.23 -> 0.24
 
-       The following substitutions are now done to create any RRD, HTML and
-       image files.
+       The following substitutions are now done to create any RRD,
+       HTML and image files.
 
           orcallator -> o
           orca       -> o
@@ -280,20 +289,21 @@
 
     0.20 -> 0.21
 
-       Between version 0.20 and 0.21 of Orca, a major name change occurred
-       in all of the installed and generated files.  Any filenames
-       containing percollator, percol, and perc had the name orcallator
-       substituted in place.  Filenames containing the word percent are
-       properly protected and will not be renamed to contain the word
-       orcallatorent.  Percollator.se has been renamed to
-       orcallator.se and its output files are now named orcallator.
-       The default percollator.cfg has been renamed to orcallator.cfg
-       and the version of orcallator.cfg included here now looks for data
-       filenames of the form orcallator-1999-05-08 and percol-1999-05-8.
-       If you are running an Orca installation 0.20 or older and want to
-       rename all of the files and directories in your Orca installation
-       to the new scheme, then kill any running percollator.se's before
-       installing and running the following commands
+       Between version 0.20 and 0.21 of Orca, a major name change
+       occurred in all of the installed and generated files.  Any
+       filenames containing percollator, percol, and perc had the name
+       orcallator substituted in place.  Filenames containing the word
+       percent are properly protected and will not be renamed to
+       contain the word orcallatorent.  Percollator.se has been
+       renamed to orcallator.se and its output files are now named
+       orcallator.  The default percollator.cfg has been renamed to
+       orcallator.cfg and the version of orcallator.cfg included here
+       now looks for data filenames of the form orcallator-1999-05-08
+       and percol-1999-05-8.  If you are running an Orca installation
+       0.20 or older and want to rename all of the files and
+       directories in your Orca installation to the new scheme, then
+       kill any running percollator.se's before installing and running
+       the following commands
 
  9) Install Orca.
 
@@ -306,18 +316,24 @@
 10) [Solaris Only and Optional] Install orcallator.
     a) Install the SE toolkit.
 
-       Perform the installation instructions as listed on the web page
+       Get the SE toolkit and use the installation instructions at
+
+         http://www.setoolkit.com/
+
+       If you are running 2.6 or greater, then download SE 3.2 or
+       greater.  Otherwise you will need SE 3.0.
+
+       The web site
 
          http://www.sun.com/sun-on-net/performance/se3/
 
-       If you are running 2.6 or greater, then download SE 3.1 or greater.
-       Otherwise you will need SE 3.0.
+       is an older SE web site that contains other useful information.
 
-    b) Apply a patch to the SE 3.0 toolkit.  If you are running any other
-       release of SE, then do not install the patch.
+    b) Apply a patch to the SE 3.0 toolkit.  If you are running any
+       other release of SE, then do not install the patch.
 
-       By default the SE toolkit will install into /opt/RICHPse.
-       Run this command:
+       By default the SE toolkit will install into /opt/RICHPse.  Run
+       this command:
 
        % cd /opt/RICHPse % patch -s <
        THIS_DIR/patches/p_netstat_class.se.diff
@@ -325,8 +341,8 @@
     c) Examine Orca/orcallator programs.
 
        Orca's installation scripts also installs several programs and
-       configuration files necessary to have Orca monitor many different
-       statistics of your Sun Solaris systems.
+       configuration files necessary to have Orca monitor many
+       different statistics of your Sun Solaris systems.
 
        The following tools are installed in the $prefix/bin directory:
 
@@ -336,19 +352,21 @@
          orcallator_column  - print selected columns from orcallator output
          orcallator_running - run to see if any orcallators are not running
 
-    d) Install orcallator boot and halt time start/stop scripts
-       in /etc/rc?.d/.
+    d) Install orcallator boot and halt time start/stop scripts in
+       /etc/rc?.d/.
 
-       If you wish to have orcallator run when the machine boots, you can
-       install the included S99orcallator file into the proper /etc/*.d/
-       directories.  To make installing this easier, you can say
+       If you wish to have orcallator run when the machine boots, you
+       can install the included S99orcallator file into the proper
+       /etc/*.d/ directories.  To make installing this easier, you can
+       say
 
        % make orcallator_run_at_boot
 
        from either the top level Makefile or the orcallator/Makefile.
-       It will remove any old orcallator files and install S99orcallator
-       into /etc/init.d/orcallator, /etc/init.d/rc0.d/K01orcallator,
-       /etc/init.d/rc1.d/K01orcallator, and /etc/rc3.d/S99orcallator.
+       It will remove any old orcallator files and install
+       S99orcallator into /etc/init.d/orcallator,
+       /etc/init.d/rc0.d/K01orcallator,
+       /etc/init.d/rc1.d/K01orcallator and /etc/rc3.d/S99orcallator.
 
     e) Run start_orcallator on all systems.
 
@@ -356,17 +374,18 @@
 
        % $prefix/bin/start_orcallator
 
-       Orcallator will not generate an output data file until the first
-       update interval, which will be between 2.5 to 7.5 minutes after
-       orcallator is started.
+       Orcallator will not generate an output data file until the
+       first update interval, which will be between 2.5 to 7.5 minutes
+       after orcallator is started.
 
     f) Edit orcallator.cfg.
 
        You need to edit the installed orcallator.cfg file and remove
        all unneeded references.  In particular, you'll want to change
-       warn_email, which is the email address that receives emails when
-       orcallator generated files are out of date, which may signify a
-       orcallator program that has died and is no longer gathering data.
+       warn_email, which is the email address that receives emails
+       when orcallator generated files are out of date, which may
+       signify a orcallator program that has died and is no longer
+       gathering data.
 
 11) Run Orca.
 

Modified: trunk/orca/lib/homesteaders.cfg
==============================================================================
--- trunk/orca/lib/homesteaders.cfg	(original)
+++ trunk/orca/lib/homesteaders.cfg	Sat Jul 13 21:25:45 2002
@@ -73,7 +73,7 @@
       <td width=388 align=right>
         <font face="Arial,Helvetica" size=2>
           <a href="http://www.ee.ethz.ch/~oetiker">Tobias Oetiker</a>
-          <a href="mailto:oetiker at ee.ethz.ch">&lt;oetiker at ee.ethz.ch&gt;</a> 
+          <a href="mailto:oetiker at ee.ethz.ch">&lt;oetiker at ee.ethz.ch&gt;</a>
           and&nbsp;<a href="http://www.bungi.com">Dave&nbsp;Rand</a>&nbsp;
           <a href="mailto:dlr at bungi.com">&lt;dlr at bungi.com&gt;</a>
         </font>
@@ -86,7 +86,7 @@
   <font face="Arial,Helvetica">
     Please email requests for enhancements, comments, or suggestions
     to Dr. Blair Zajac
-    <a href="mailto:blair at akamai.com">&lt;blair at akamai.com&gt;</a>.
+    <a href="mailto:blair at gps.caltech.edu">&lt;blair at gps.caltech.edu&gt;</a>.
   </font>
 
 # These are the same plot except one of them do not allow deletions.

Modified: trunk/orca/lib/Makefile.in
==============================================================================
--- trunk/orca/lib/Makefile.in	(original)
+++ trunk/orca/lib/Makefile.in	Sat Jul 13 21:25:45 2002
@@ -3,8 +3,8 @@
 prefix		= @prefix@
 exec_prefix	= @exec_prefix@
 libdir		= @libdir@
-MKDIR		= @MKDIR@
 INSTALL		= @INSTALL@
+MKDIR		= @MKDIR@
 
 all:		Makefile orca.gif.hex rrdtool.gif.hex
 
@@ -39,4 +39,3 @@
 
 Makefile: Makefile.in
 	cd .. && CONFIG_FILES=lib/Makefile ./config.status
-	$(MAKE)

Modified: trunk/orca/lib/Orca/HTMLFile.pm
==============================================================================
--- trunk/orca/lib/Orca/HTMLFile.pm	(original)
+++ trunk/orca/lib/Orca/HTMLFile.pm	Sat Jul 13 21:25:45 2002
@@ -1,6 +1,6 @@
 # Orca::HTMLFile: Manage the creation of HTML files.
 #
-# Copyright (C) 1998, 1999 Blair Zajac and Yahoo!, Inc.
+# Copyright (C) 1998-2001 Blair Zajac and Yahoo!, Inc.
 
 package Orca::HTMLFile;
 
@@ -35,7 +35,7 @@
   print FD <<END;
 <html>
 <head>
-<title>$title</title>
+<title>Orca - $title</title>
 </head>
 <body bgcolor="#ffffff">
 
@@ -69,7 +69,7 @@
       <font FACE="Arial,Helvetica" size=2>
         Orca-$ORCA_VERSION by
         <a href="http://www.gps.caltech.edu/~blair/">Blair Zajac</a>
-        <a href="mailto:blair\@akamai.com">blair\@akamai.com</a>.
+        <a href="mailto:blair\@blair.gps.caltech.edu">blair\@gps.caltech.edu</a>.
       </font>
     </td>
     <td width=120 valign=center>

Modified: trunk/orca/lib/Orca/OpenFileHash.pm
==============================================================================
--- trunk/orca/lib/Orca/OpenFileHash.pm	(original)
+++ trunk/orca/lib/Orca/OpenFileHash.pm	Sat Jul 13 21:25:45 2002
@@ -1,6 +1,6 @@
 # Orca::OpenFileHash: Cache open file descriptors for the whole program.
 #
-# Copyright (C) 1998, 1999 Blair Zajac and Yahoo!, Inc.
+# Copyright (C) 1998-2001 Blair Zajac and Yahoo!, Inc.
 
 package Orca::OpenFileHash;
 

Modified: trunk/orca/lib/Orca/Config.pm
==============================================================================
--- trunk/orca/lib/Orca/Config.pm	(original)
+++ trunk/orca/lib/Orca/Config.pm	Sat Jul 13 21:25:45 2002
@@ -1,6 +1,6 @@
-# Orca::Config: Manage configuration options for Orca.
+# Orca::Config: Manage configuration parameters for Orca.
 #
-# Copyright (C) 1998, 1999 Blair Zajac and Yahoo!, Inc.
+# Copyright (C) 1998-2001 Blair Zajac and Yahoo!, Inc.
 
 package Orca::Config;
 
@@ -9,7 +9,15 @@
 use Exporter;
 use Orca::Constants     qw($opt_verbose
                            $is_sub_re
-                           die_when_called);
+                           die_when_called
+                           $ORCA_VERSION
+                           @CONST_IMAGE_PLOT_TYPES
+                           %CONST_IMAGE_PLOT_INFO
+                           @IMAGE_PLOT_TYPES
+                           @IMAGE_PDP_COUNTS
+                           @IMAGE_TIME_SPAN
+                           $MAX_PLOT_TYPE_LENGTH
+                           $INCORRECT_NUMBER_OF_ARGS);
 use Orca::SourceFileIDs qw(@sfile_fids);
 use vars qw(@EXPORT_OK @ISA $VERSION);
 
@@ -22,86 +30,127 @@
 
 # The following array and hashes hold the contents of the
 # configuration file.
-use vars         qw(%config_options %config_groups @config_plots);
-push(@EXPORT_OK, qw(%config_options %config_groups @config_plots));
-
-# These are state variables for reading the config file.  The
-# $pcl_group_name variable holds the name of the group when a
-# group is being defined.  If $pcl_group_name is '', then a group
-# configuration is not being read.  $pcl_plot_index is a string that
-# represents a number that is used as an index into @plots.  If the
-# string is negative, including -0, then the plot configuration is not
-# being defined, otherwise it holds the index into the @plots array
-# the is being defined.
+use vars         qw(%config_global
+                    @config_groups
+                    @config_groups_names
+                    @config_plots);
+push(@EXPORT_OK, qw(%config_global
+                    @config_groups
+                    @config_groups_names
+                    @config_plots));
+
+# This is a list of global parameters that control which plots
+# (i.e. monthly, yearly) are created.
+my $pre_plot_type  = 'generate_';
+my $post_plot_type = '_plot';
+my @plot_type_global_elements = map { "$pre_plot_type$_$post_plot_type" }
+                                @CONST_IMAGE_PLOT_TYPES;
+
+# The pcl_* variables are used to read the configuration file and how
+# to treat each configuration file parameter.
+
+# These are state variables are used for reading the config file.  The
+# variables pcl_group_index and pcl_plot_index are strings that
+# represent a number that is used as an index into @config_groups and
+# @config_plots respectively.  If the string is negative, including
+# -0, then the configuration is not being defined, otherwise it holds
+# the index into the appropriate array that is being defined.
+my $pcl_group_index = '-0';
+my $pcl_plot_index  = '-0';
 my $pcl_group_name  = '';
-my $pcl_plot_index = '-0';
 
-# The following options go into the options and files hashes.  If you
-# add any elements to pcl_plot_append_elements, make sure to update
+# This keeps track of group names that have been loaded.
+my %pcl_group_name_to_index;
+
+# The @pcl_X_elements are the list of valid options for the global,
+# group and plot sections of the configuration file.
+my %pcl_global_elements        =   (base_dir            => 1,
+                                    expire_images       => 1,
+                                    find_times          => 1,
+                                    html_dir            => 1,
+                                    html_page_footer    => 1,
+                                    html_page_header    => 1,
+                                    html_top_title      => 1,
+                                    late_interval       => 1,
+                                    max_filename_length => 1,
+                                    require             => 1,
+                                    rrd_dir             => 1,
+                                    state_file          => 1,
+                                    warn_email          => 1);
+map { $pcl_global_elements{$_} = 1 } @plot_type_global_elements;
+my %pcl_group_elements         =   (column_description  => 1,
+                                    date_parse          => 1,
+                                    date_source         => 1,
+                                    filename_compare    => 1,
+                                    find_files          => 1,
+                                    interval            => 1,
+                                    late_interval       => 1,
+                                    reopen              => 1);
+my %pcl_plot_elements          =   (base                => 1,
+                                    color               => 1,
+                                    data                => 1,
+                                    data_min            => 1,
+                                    data_max            => 1,
+                                    data_type           => 1,
+                                    flush_regexps       => 1,
+                                    href                => 1,
+                                    legend              => 1,
+                                    line_type           => 1,
+                                    logarithmic         => 1,
+                                    plot_height         => 1,
+                                    plot_min            => 1,
+                                    plot_max            => 1,
+                                    plot_width          => 1,
+                                    required            => 1,
+                                    rigid_min_max       => 1,
+                                    source              => 1,
+                                    summary_format      => 1,
+                                    title               => 1,
+                                    y_legend            => 1);
+
+# %pcl_group_append_elements and %pcl_plot_append_elements define
+# those parameters that generate a list of values and every appearance
+# of one in the configuration file appends the value to the array.  If
+# an entry is added to %pcl_plot_append_elements, make sure to update
 # Orca::SourceFile::add_plots.
-my @pcl_option_elements        = qw(base_dir
-                                    expire_images
-                                    find_times
-                                    html_dir
-                                    html_page_footer
-                                    html_page_header
-                                    html_top_title
-                                    late_interval
-                                    rrd_dir
-                                    state_file
-                                    sub_dir
-                                    warn_email);
-my @pcl_group_elements         = qw(column_description
-                                    date_format
-                                    date_source
-                                    filename_compare
-                                    find_files
-                                    interval
-                                    reopen);
-my @pcl_plot_elements          = qw(base
-                                    color
-                                    data
-                                    data_min
-                                    data_max
-                                    data_type
-                                    flush_regexps
-                                    href
-                                    legend
-                                    line_type
-                                    logarithmic
-                                    plot_height
-                                    plot_min
-                                    plot_max
-                                    plot_width
-                                    required
-                                    rigid_min_max
-                                    source
-                                    title
-                                    y_legend);
-my @pcl_plot_append_elements   = qw(color
-                                    data
-                                    legend
-                                    line_type);
-my @pcl_filepath_elements      = qw(find_files
-                                    html_dir
-                                    rrd_dir
-                                    state_file);
-my @pcl_no_arg_elements        = qw(flush_regexps
-                                    logarithmic
-                                    required
-                                    rigid_min_max);
-my %pcl_option_keep_as_array   =   ();
-my %pcl_group_keep_as_array    =   (column_description => 1,
-                                    date_source        => 1,
-                                    find_files         => 1);
-my %pcl_plot_keep_as_array     =   (data               => 1);
-
-# The following variables are used to check that the configuration file
-# contains the required options.  the @cc_required_* are the names of
-# the options that must occur in a configuration file.  The @cc_optional_*
-# options are options set to '' if they are not set in the configuration
-# file.
-my @cc_required_option         = qw(html_dir
+my %pcl_group_append_elements  =   ();
+my %pcl_plot_append_elements   =   (color               => 1,
+                                    data                => 1,
+                                    data_min            => 1,
+                                    data_max            => 1,
+                                    data_type           => 1,
+                                    legend              => 1,
+                                    line_type           => 1,
+                                    summary_format      => 1);
+
+# This is a list of parameters that need their paths cleaned up.
+my %pcl_filepath_elements      =   (find_files          => 1,
+                                    html_dir            => 1,
+                                    rrd_dir             => 1,
+                                    state_file          => 1);
+
+# This is a list of parameters that do not require an argument and
+# when there is no argument for the parameter, the value is set to
+# true.
+my %pcl_no_arg_elements        =   (flush_regexps       => 1,
+                                    logarithmic         => 1,
+                                    required            => 1,
+                                    rigid_min_max       => 1);
+
+# These are a list of parameters that keep all of the arguments to the
+# parameter, not just the first one.  Internally, the parameter value
+# is stored as a reference to an array.
+my %pcl_global_keep_as_array   =   ('require'           => 1);
+my %pcl_group_keep_as_array    =   (column_description  => 1,
+                                    date_source         => 1,
+                                    find_files          => 1);
+my %pcl_plot_keep_as_array     =   (data                => 1);
+
+# The following variables are used to check that the configuration
+# file contains the required parameters and that the parameters are
+# set to the correct values.  The @cc_required_* are the names of the
+# parameters that must occur in a configuration file.
+my @cc_required_global         = qw(html_dir
                                     rrd_dir
                                     state_file);
 my @cc_required_group          = qw(column_description
@@ -110,258 +159,519 @@
                                     interval);
 my @cc_required_plot           = qw(data
                                     source);
-my @cc_optional_option         = qw(expire_images
+
+# The parameters listed in @cc_default_is_true_* are set to 1 if they
+# are not set in the configuration file.
+my @cc_default_is_true_global  =   @plot_type_global_elements;
+my @cc_default_is_true_group   =   ();
+my @cc_default_is_true_plot    =   ();
+
+# The parameters listed in @cc_default_is_false_* are set to '' if
+# they are not set in the configuration file.
+my @cc_default_is_false_global = qw(expire_images
+                                    find_times
                                     html_page_footer
                                     html_page_header
                                     html_top_title
                                     late_interval
-                                    sub_dir
                                     warn_email);
-my @cc_optional_group          = qw(reopen);
-my @cc_optional_plot           = qw(flush_regexps
+my @cc_default_is_false_group  = qw(date_parse
+                                    reopen);
+my @cc_default_is_false_plot   = qw(flush_regexps
                                     href
+                                    late_interval
                                     plot_width
                                     plot_height);
 
+# These parameters are set to true if they do not appear in the
+# configuration file.
+my %pcl_global_default_is_true = map { ($_, 1) } @plot_type_global_elements;
+my %pcl_group_default_is_true  =   ();
+my %pcl_plot_default_is_true   =   ();
+
+
 # This is the default list of colors.
-my @cc_default_colors          =   ('00ff00',	# Green
-                                    '0000ff',	# Blue
-                                    'ff0000',	# Red
-                                    'a020f0',	# Magenta
-                                    'ffa500',	# Orange
-                                    'a52a2a',	# Brown
-                                    '00ffff',	# Cyan
-                                    '00aa00',	# Dark Green
-                                    'eeee00',	# Yellow
-                                    '5e5e5e',	# Dark Gray
-                                    '0000aa');	# Dark Blue
+my @cc_default_colors          =   ('00ff00',   # Green
+                                    '0000ff',   # Blue
+                                    'ff0000',   # Red
+                                    'a020f0',   # Magenta
+                                    'ffa500',   # Orange
+                                    'a52a2a',   # Brown
+                                    '00ffff',   # Cyan
+                                    '00aa00',   # Dark Green
+                                    'eeee00',   # Yellow
+                                    '707070',   # Dark Gray
+                                    'be711d',   # Rust 11
+                                    'dad1ff',   # Lilas
+                                    '7df5cb',   # Biz green
+                                    'ff81a9',   # Pink
+                                    'ffe114',   # Golden
+                                    '96a125',   # Olive
+                                    'ffd8ae',   # Peaches
+                                    'bebebe',   # Light Grey
+                                    'ebeec3',   # Taupe
+                                    '860033',   # Bourgogne
+                                    '19a48a',   # Ocean green
+                                    'b8a390',   # VLB
+                                    'a3c5a6',   # Blackboard green
+                                    'ffd2b2',   # Light orange
+                                    '000000',   # Black
+                                    'fff8bd',   # Post-it (tm) Yellow
+                                    'c7eaff',   # Ice blue
+                                    'd3ff52');  # Gatorade green
 
 sub get_color {
   $cc_default_colors[$_[0] % @cc_default_colors];
 }
 
+# Increment this count for each error in the configuration file.
+my $number_errors = 0;
+
 # This variable stores the anonymous subroutine that compares FIDs
 # when a group in the configuration files does not contain a
 # filename_compare parameter.
 my $cmp_fids_sub;
 
+# This subroutine takes a string and compiles it into a subroutine.
+sub compile_sub {
+  unless (@_ == 4) {
+    confess "$0: Orca::Config::compile_sub $INCORRECT_NUMBER_OF_ARGS";
+  }
+
+  my ($option, $where, $config_filename, $expr) = @_;
+
+  $expr = "sub { $expr }" if $expr !~ /$is_sub_re/o;
+
+  my $sub;
+  {
+    local $SIG{__DIE__}  = 'DEFAULT';
+    local $SIG{__WARN__} = \&die_when_called;
+    $sub = eval $expr;
+  }
+
+  if ($@) {
+    warn "$0: cannot evalulate `$option' in $where in ",
+         "`$config_filename':\n   $expr\nOutput: $@\n";
+    return;
+  } else {
+    return $sub;
+  }
+}
+
+# This subroutine takes an expression and creates an anonymous
+# subroutine that calculates the late interval.
+sub compile_late_interval {
+  unless (@_ == 3) {
+    confess "$0: Orca::Config::compile_late_interval $INCORRECT_NUMBER_OF_ARGS";
+  }
+
+  my ($where, $config_filename, $expr) = @_;
+
+  $expr =~ s/\binterval\b/\$_[0]/g;
+  my $sub = compile_sub('late_interval',
+                        $where,
+                        $config_filename,
+                        $expr);
+  return unless $sub;
+
+  local $SIG{__DIE__}  = 'DEFAULT';
+  local $SIG{__WARN__} = \&die_when_called;
+  eval '&$sub(3.1415926) + 0;';
+  if ($@) {
+    warn "$0: cannot execute `late_interval' in $where in ",
+         "`$config_filename':\n   $expr\nOutput: $@\n";
+    return;
+  } else {
+    return $sub;
+  }
+}
+
+# This subroutine takes an array reference, a list of number of
+# elements that should be in the array, and the default value to use
+# if there are no set values.  For the array elements that are not
+# set, use the last set value.
+sub fill_append_elements {
+  unless (@_ == 3) {
+    die "Orca::Config::fill_append_elements $INCORRECT_NUMBER_OF_ARGS";
+  }
+
+  my ($array_ref, $number_datas, $default_value) = @_;
+
+  unless (defined $array_ref->[0]) {
+    $array_ref->[0] = $default_value;
+  }
+  for (my $k=1; $k<$number_datas; ++$k) {
+    unless (defined $array_ref->[$k]) {
+      $array_ref->[$k] = $array_ref->[$k-1];
+    }
+  }
+}
+
 sub check_config {
   my $config_filename = shift;
 
-  # If rrd_dir is not set, then use base_dir.  Only die if both are
+  # Check that the required version of Orca is being used.
+  if (defined $config_global{require}) {
+    my @require = @{$config_global{require}};
+    if (@require == 2) {
+      unless ($require[0] eq 'Orca') {
+        ++$number_errors;
+        warn "$0: error: `require' only accepts `Orca' as first argument in ",
+             "`$config_filename'.\n";
+      }
+      my $number = $require[1];
+      if ($number !~ /^\d+(?:\.\d*)?$/ and $number !~ /^\.\d+$/) {
+        ++$number_errors;
+        warn "$0: error: `require' second argument `$number' is not a number ",
+             "in `$config_filename'.\n";
+      } elsif ($ORCA_VERSION < $number) {
+        ++$number_errors;
+        warn "$0: Orca version $ORCA_VERSION less than required version ",
+             "$number specified in `$config_filename'.\n";
+      }
+    } else {
+      ++$number_errors;
+      warn "$0: error: `require' needs two arguments in `$config_filename'.\n";
+    }
+  }
+
+  # If rrd_dir is not set, then use base_dir.  Only warn if both are
   # not set.
-  unless (defined $config_options{rrd_dir}) {
-    if (defined $config_options{base_dir}) {
-      $config_options{rrd_dir} = $config_options{base_dir};
+  unless (defined $config_global{rrd_dir}) {
+    if (defined $config_global{base_dir}) {
+      $config_global{rrd_dir} = $config_global{base_dir};
     } else {
-      die "$0: error: must define `rrd_dir' in `$config_filename'.\n";
+      ++$number_errors;
+      warn "$0: error: must set `rrd_dir' in `$config_filename'.\n";
     }
   }
 
   # Check that we the required options are satisfied.
-  foreach my $option (@cc_required_option) {
-    unless (defined $config_options{$option}) {
-      die "$0: error: must define `$option' in `$config_filename'.\n";
+  my $required_error = 0;
+  foreach my $option (@cc_required_global) {
+    unless (defined $config_global{$option}) {
+      $required_error = 1;
+      ++$number_errors;
+      warn "$0: error: must set `$option' in `$config_filename'.\n";
     }
   }
 
+  # Quit now if there were any required options that were not set
+  # since use of then will cause uninitialized warnings.
+  if ($required_error) {
+    die "$0: loading configuration file `$config_filename' got ",
+        "$number_errors error(s).\n";
+  }
+
   # Check if the html_dir and rrd_dir directories exist.
   foreach my $dir_key ('html_dir', 'rrd_dir') {
-    my $dir = $config_options{$dir_key};
-    die "$0: error: please create $dir_key `$dir'.\n" unless -d $dir;
+    my $dir = $config_global{$dir_key};
+    unless (-d $dir) {
+      ++$number_errors;
+      warn "$0: error: please create $dir_key `$dir'.\n";
+    }
   }
 
-  # Set any optional options to '' if it isn't defined.
-  foreach my $option (@cc_optional_option) {
-    $config_options{$option} = '' unless defined $config_options{$option};
+  # Set any optional global parameters to '' if it isn't defined in
+  # the configuration file.
+  foreach my $option (@cc_default_is_false_global) {
+    $config_global{$option} = '' unless defined $config_global{$option};
   }
 
-  # Late_interval is a valid mathematical expression. Replace the word
-  # interval with $_[0].  Try the subroutine to make sure it works.
-  unless ($config_options{late_interval}) {
-    $config_options{late_interval} = 'interval';
-  }
-  my $expr = "sub { $config_options{late_interval}; }";
-  $expr =~ s/interval/\$_[0]/g;
-  my $sub;
-  {
-    local $SIG{__DIE__}  = 'DEFAULT';
-    local $SIG{__WARN__} = \&die_when_called;
-    $sub = eval $expr;
+  # Set any optional global parameters to 1 if it isn't defined in the
+  # configuration file.
+  foreach my $option (@cc_default_is_true_global) {
+    $config_global{$option} = 1 unless defined $config_global{$option};
   }
-  if ($@) {
-    die "$0: cannot evaluate `late_interval' in `$config_filename':\n   ",
-        "$expr\nOutput: $@\n";
+
+  # Set the max_filename_length if it is not set and check it
+  # otherwise.
+  my $mfl = $config_global{max_filename_length};
+  if (defined $mfl) {
+    unless ($mfl =~ /^\d+$/ and $mfl > 63) {
+      ++$number_errors;
+      warn "$0: error: max_filename_length `$mfl' is not a number > 63.\n";
+    }
+  } else {
+    $config_global{max_filename_length} = 235;
   }
-  {
-    local $SIG{__DIE__}  = 'DEFAULT';
-    local $SIG{__WARN__} = \&die_when_called;
-    eval '&$sub(3.1415926) + 0;';
+
+  # Late_interval is a valid mathematical expression. Replace the word
+  # interval with $_[0].  Try the subroutine to make sure it works.
+  unless ($config_global{late_interval}) {
+    $config_global{late_interval} = 'interval';
   }
-  if ($@) {
-    die "$0: cannot execute `late_interval' in `$config_filename':\n   ",
-         "$expr\nOutput: $@\n";
+  my $global_late_interval_expr = $config_global{late_interval};
+  my $sub = compile_late_interval('global section',
+                                  $config_filename,
+                                  $config_global{late_interval});
+  if ($sub) {
+    $config_global{late_interval} = $sub;
+  } else {
+    ++$number_errors;
   }
-  $config_options{late_interval} = $sub;
 
   # Convert the list of find_times into an array of fractional hours.
   my @find_times;
-  unless (defined $config_options{find_times}) {
-    $config_options{find_times} = '';
-  }
-  foreach my $find_time (split(' ', $config_options{find_times})) {
+  foreach my $find_time (split(' ', $config_global{find_times})) {
     if (my ($hours, $minutes) = $find_time =~ /^(\d{1,2}):(\d{2})/) {
       # Because of the regular expression match we're doing, the hours
       # and minutes will only be positive, so check for hours > 23 and
       # minutes > 59.
       unless ($hours < 24) {
-        warn "$0: warning: ignoring find_times `$find_time': hours must be less than 24.\n";
+        ++$number_errors;
+        warn "$0: warning: ignoring find_times `$find_time': hours must be ",
+             "less than 24.\n";
         next;
       }
       unless ($minutes < 60) {
-        warn "$0: warning: ignoring find_times `$find_time': minutes must be less than 60.\n";
+        ++$number_errors;
+        warn "$0: warning: ignoring find_times `$find_time': minutes must be ",
+             "less than 60.\n";
         next;
       }
       push(@find_times, $hours + $minutes/60.0);
     } else {
+      ++$number_errors;
       warn "$0: warning: ignoring find_times `$find_time': illegal format.\n";
     }
   }
-  $config_options{find_times} = [ sort { $a <=> $b } @find_times ];
+  $config_global{find_times} = [ sort { $a <=> $b } @find_times ];
+
+  # Using the parameters in the configuration file, generate the list
+  # of plots to create.
+  @IMAGE_PLOT_TYPES = ();
+  @IMAGE_PDP_COUNTS = ();
+  @IMAGE_TIME_SPAN  = ();
+  $MAX_PLOT_TYPE_LENGTH = 0;
+  foreach my $type (@CONST_IMAGE_PLOT_TYPES) {
+    if ($config_global{"$pre_plot_type$type$post_plot_type"}) {
+      my $data_ref = $CONST_IMAGE_PLOT_INFO{$type};
+      unless ($data_ref) {
+        die "$0: internal error: \$CONST_IMAGE_PLOT_INFO{$type} is ",
+            "undefined.\n";
+      }
+      push(@IMAGE_PLOT_TYPES, $type);
+      push(@IMAGE_PDP_COUNTS, $data_ref->[0]);
+      push(@IMAGE_TIME_SPAN,  $data_ref->[1]);
+      my $type_length = length($type);
+      if ($type_length > $MAX_PLOT_TYPE_LENGTH) {
+        $MAX_PLOT_TYPE_LENGTH = $type_length;
+      }
+    }
+  }
+
+  # There must be at least one timespan plot.
+  unless (@IMAGE_PLOT_TYPES) {
+    ++$number_errors;
+    warn "$0: error: generate_*_plots parameters turn off all plots in ",
+         "`$config_filename'.\n";
+  }
 
   # There must be at least one group.
-  unless (keys %config_groups) {
-    die "$0: error: must define at least one `group' in `$config_filename'.\n";
+  unless (@config_groups) {
+    ++$number_errors;
+    warn "$0: error: must define at least one `group' in ",
+         "`$config_filename'.\n";
   }
 
   # For each group parameter there are required options.
-  foreach my $group_name (keys %config_groups) {
-    my $group = $config_groups{$group_name};
+  for (my $i=0; $i<@config_groups; ++$i) {
+    my $group      = $config_groups[$i];
+    my $group_name = $config_groups_names[$i];
 
+    $required_error = 0;
     foreach my $option (@cc_required_group) {
       unless (defined $group->{$option}) {
-        die "$0: error: must define `$option' for `group $group_name' ",
-            "in `$config_filename'.\n";
+        $required_error = 1;
+        ++$number_errors;
+        warn "$0: error: must set `$option' for `group $group_name' ",
+             "in `$config_filename'.\n";
       }
     }
 
-    # Optional group options will be set to '' here if they haven't
-    # been set by the user.
-    foreach my $option (@cc_optional_group) {
+    # Quit now if there were any required options that were not set
+    # since use of then will cause uninitialized warnings.
+    if ($required_error) {
+      die "$0: loading configuration file `$config_filename' got ",
+          "$number_errors error(s).\n";
+    }
+
+    # Set any optional group parameters to '' if it isn't defined in
+    # the configuration file.
+    foreach my $option (@cc_default_is_false_group) {
       $group->{$option} = '' unless defined $group->{$option};
     }
 
-    # Create the filename comparison function.  The function must be
-    # handle input ala sort() via the package global $a and $b variables.
-    if (defined $group->{filename_compare} or !$cmp_fids_sub) {
-      my $expr = defined $group->{filename_compare} ?
-                 $group->{filename_compare} :
-                 'sub { $a cmp $b }';
-      $expr = "sub { $expr }" if $expr !~ /$is_sub_re/o;
-      my $sub;
-      {
-        local $SIG{__DIE__}  = 'DEFAULT';
-        local $SIG{__WARN__} = \&die_when_called;
-        $sub = eval $expr;
+    # Set any optional group parameters to 1 if it isn't defined in
+    # the configuration file.
+    foreach my $option (@cc_default_is_true_group) {
+      $group->{$option} = 1 unless defined $group->{$option};
+    }
+
+    # Check that the interval is a number.
+    unless ($group->{interval} =~ /^\d+$/ and $group->{interval} > 0) {
+      ++$number_errors;
+      warn "$0: error: interval `$group->{interval}' for `group $group_name' ",
+           "is not an integer greater than 0 in `$config_filename'.\n";
+    }
+
+    # Check the late_interval.  If it does not exist, then use the
+    # global one.
+    my $expr;
+    if ($expr = $group->{late_interval}) {
+      $sub = compile_late_interval("`group $group_name'",
+                                   $config_filename,
+                                   $expr);
+      if ($sub) {
+        $group->{late_interval} = $sub;
+      } else {
+        ++$number_errors;
       }
+    } else {
+      $expr = $global_late_interval_expr;
+      $group->{late_interval} = $config_global{late_interval};
+    }
+    {
+      local $SIG{__DIE__}  = 'DEFAULT';
+      local $SIG{__WARN__} = \&die_when_called;
+      $sub = $group->{late_interval};
+      my $value;
+      eval '$value = &$sub($group->{interval});';
       if ($@) {
-        if ($group->{filename_compare}) {
-          die "$0: cannot compile `filename_compare' for group `$group_name' ",
-              "in `$config_filename':\n   $expr\nOutput: $@\n";
-        } else {
-          die "$0: internal error: cannot compile default ",
-              "`filename_compare':\n   $expr\nOutput: $@\n";
-        }
+        ++$number_errors;
+        warn "$0: cannot execute `late_interval' in `group $group_name' in ",
+             "`$config_filename':\n   $expr\nOutput: $@\n";
+      } elsif ($value !~ /^\d+$/ and $value <= 0) {
+        ++$number_errors;
+        warn "$0: `late_interval' in `group $group_name' did not generate an ",
+             "integer `$value' greater than 0.\n";
       }
+      $group->{late_interval} = $value;
+    }
 
-      # This subroutine looks fine.  Now change all the variables to use
-      # file IDs instead.
-      $expr =~ s/\$a(\W)/\$sfile_fids[\$a]$1/g;
-      $expr =~ s/\$b(\W)/\$sfile_fids[\$b]$1/g;
-      {
-        no strict;
-        local $SIG{__DIE__}  = 'DEFAULT';
-        local $SIG{__WARN__} = \&die_when_called;
-        $sub = eval $expr;
-      }
-      if ($@) {
-        if ($group->{filename_compare}) {
-          die "$0: cannot compile `filename_compare' for group `$group_name' ",
-              "in `$config_filename':\n   $expr\nOutput: $@\n";
+    # There are three intervals associated with each file.  The first
+    # is the data update interval.  This is the same interval used to
+    # generate the RRDs.  The second interval is the interval before
+    # the file is considered late and is larger than the data update
+    # interval.  This interval is calculated by using the mathematical
+    # expression given in the `late_interval' configuration option.
+    # If `late_interval' is not defined, then it gets defaulted to the
+    # data update interval.  The last interval is the interval to use
+    # to tell the program when to attempt to read the file next.
+    # Because it can take some time for the source files to be
+    # updated, we don't want to read the file immediately after the
+    # data update interval is done.  For this reason, choose a read
+    # interval that is somewhere in between the data source interval
+    # and the late_interval.  Use the multiplicative average of the
+    # data update interval and the late interval since the resulting
+    # value is closer to the data update interval.  Ie:
+    # (20 + 5)/2 = 12.5.  Sqrt(20*5) = 10.
+    $group->{read_interval} = sqrt($group->{interval}*$group->{late_interval});
+
+    # Create the filename comparison function.  The function must be
+    # handle input ala sort() via the package global $a and $b variables.
+    if ($group->{filename_compare} or !$cmp_fids_sub) {
+      $expr = $group->{filename_compare} ?
+              $group->{filename_compare} :
+              'sub { $a cmp $b }';
+      if (compile_sub('filename_compare',
+                      "`group $group_name'",
+                      $config_filename,
+                      $expr)) {
+        # This subroutine looks fine.  Now change all the variables to
+        # use file IDs instead.
+        $expr =~ s/\$a(\W)/\$sfile_fids[\$a]$1/g;
+        $expr =~ s/\$b(\W)/\$sfile_fids[\$b]$1/g;
+        $sub  = compile_sub('filename_compare',
+                            "group `$group_name'",
+                            $config_filename,
+                            $expr);
+        if ($sub) {
+          $cmp_fids_sub = $sub if !$group->{filename_compare};
+          $group->{filename_compare} = $sub;
         } else {
-          die "$0: internal error: cannot compile default ",
-              "`filename_compare':\n   $expr\nOutput: $@\n";
+          ++$number_errors;
         }
+      } else {
+        ++$number_errors;
       }
-      $cmp_fids_sub = $sub if !$group->{filename_compare};
-      $group->{filename_compare} = $sub;
     } else {
       $group->{filename_compare} = $cmp_fids_sub;
     }
 
     # Check that the date_source is either column_name followed by a
     # column name or file_mtime for the file modification time.  If a
-    # column_name is used, then the date_format is required.
+    # column_name is used, then compile the data_parse subroutine if
+    # it exists.
     my $date_source = $group->{date_source}[0];
+    $group->{date_parse} = 0;
     if ($date_source eq 'column_name') {
-      unless (@{$group->{date_source}} == 2) {
-        die "$0: error: incorrect number of arguments for `date_source' for ",
-            "`group $group_name'.\n";
-      }
-      unless (defined $group->{date_format}) {
-        die "$0: error: must define `date_format' with ",
-            "`date_source columns ...' for `group $group_name'.\n";
+      if (@{$group->{date_source}} != 2) {
+        ++$number_errors;
+        warn "$0: error: incorrect number of arguments for `date_source' for ",
+             "`group $group_name'.\n";
+      } elsif (my $expr = $group->{date_parse}) {
+        unless ($group->{date_parse} = compile_sub('date_parse',
+                                                   "group `$group_name'",
+                                                   $config_filename,
+                                                   $expr)) {
+          ++$number_errors;
+        }
       }
     } else {
       unless ($date_source eq 'file_mtime') {
-        die "$0: error: illegal argument for `date_source' for ",
+        ++$number_errors;
+        warn "$0: error: illegal argument for `date_source' for ",
              "`group $group_name'.\n";
       }
     }
     $group->{date_source}[0] = $date_source;
 
-    # Validate the regular expression for find_files and get a unique list
-    # of them.  Check if the regular expressions contain any ()'s that will
-    # place the found files into different groups.  If any ()'s are found,
-    # then the output HTML and image tree will use subdirectories for each
-    # group.
+    # Validate the regular expression for find_files and get a unique
+    # list of them.  Check if the regular expressions contain any ()'s
+    # that will place the found files into different groups.  If any
+    # ()'s are found, then the output HTML and image tree will use
+    # subdirectories for each group.
     #
-    # In this comment, all path names are Perl escaped, so the directory
-    # . would be written as \. instead.
+    # In this code comment, all path names are Perl escaped, so the
+    # directory . would be written as \. instead.
     #
-    # Since we do not want to search on the current directory, find any
-    # text that begins a regular expression with a \./ and remove it.  Also
-    # Remove any matches for /\./ in the path since they are unnecessary.
-    # However, do not remove searches for /./, since this can match single
-    # character files or directories.
-    my $sub_dir = 0;
+    # Since we do not want to search on the current directory, find
+    # any find_files' that begin a regular expression with a \./ and
+    # remove it.  Also remove any matches for /\./ in the path since
+    # they are unnecessary.  However, do not remove searches for /./,
+    # since this can match single character files or directories.
     my %find_files;
-    my $number_finds = @{$group->{find_files}};
-    for (my $i=0; $i<$number_finds; ++$i) {
-      my $orig_find = $group->{find_files}[$i];
-      my $find      = $orig_find;
-      $find         =~ s:^\\\./+::;
-      $find         =~ s:/+\\\./+:/:g;
-      $find         = $orig_find unless $find;
-      $group->{find_files}[$i] = $find;
-      my $test_string          = 'abcdefg';
-      local $SIG{__DIE__}      = 'DEFAULT';
-      local $SIG{__WARN__}     = \&die_when_called;
+    my $find_files = $group->{find_files};
+    my $number_finds = @$find_files;
+    for (my $j=0; $j<$number_finds; ++$j) {
+      my $orig_find        = $find_files->[$j];
+      my $find             = $orig_find;
+      $find                =~ s:^\\\./+::;
+      $find                =~ s:/+\\\./+:/:g;
+      $find                = $orig_find unless $find;
+      $find_files->[$j]    = $find;
+      my $test_string      = 'abcdefg';
+      local $SIG{__DIE__}  = 'DEFAULT';
+      local $SIG{__WARN__} = \&die_when_called;
       eval { $test_string =~ /$find/ };
       if ($@) {
-        die "$0: error: illegal regular expression in `find_files $orig_find' ",
-            "for `files $group_name' in `$config_filename':\n$@\n";
+        ++$number_errors;
+        warn "$0: error: illegal regular expression in `find_files ",
+             "$orig_find' for `files $group_name' in ",
+             "`$config_filename':\n$@\n";
+      } else {
+        $find_files{$find} = 1;
       }
-      $find_files{$find} = 1;
-      $sub_dir = 1 if $find =~ m:\(.+\):;
     }
     $group->{find_files} = [sort keys %find_files];
-    $group->{sub_dir}    = $sub_dir || $config_options{sub_dir};
   }
 
   # There must be at least one plot.
   unless (@config_plots) {
-    die "$0: error: must define at least one `plot' in `$config_filename'.\n";
+    ++$number_errors;
+    warn "$0: error: must define at least one `plot' in `$config_filename'.\n";
   }
 
   # Foreach plot there are required options.  Create default options
@@ -370,23 +680,39 @@
     my $plot = $config_plots[$i];
 
     my $j = $i + 1;
+    $required_error = 0;
     foreach my $option (@cc_required_plot) {
       unless (defined $plot->{$option}) {
-        die "$0: error: must define `$option' for `plot' #$j in ",
-            "`$config_filename'.\n";
+        $required_error = 1;
+        ++$number_errors;
+        warn "$0: error: must set `$option' for `plot' #$j in ",
+             "`$config_filename'.\n";
       }
     }
 
+    # Quit now if there were any required options that were not set
+    # since use of then will cause uninitialized warnings.
+    if ($required_error) {
+      die "$0: loading configuration file `$config_filename' got ",
+          "$number_errors error(s).\n";
+    }
+
     # Create an array for each plot that will have a list of images that
     # were generated from this plot.
     $plot->{creates} = [];
 
-    # Optional options will be set to '' here if they haven't been set
-    # by the user.
-    foreach my $option (@cc_optional_plot) {
+    # Set any optional plot parameters to '' if it isn't defined in
+    # the configuration file.
+    foreach my $option (@cc_default_is_false_plot) {
       $plot->{$option} = '' unless defined $plot->{$option};
     }
 
+    # Set any optional plot parameters to 1 if it isn't defined in
+    # the configuration file.
+    foreach my $option (@cc_default_is_true_plot) {
+      $plot->{$option} = 1 unless defined $plot->{$option};
+    }
+
     # Set the default plot width and height.
     $plot->{plot_width}  =  500 unless $plot->{plot_width};
     $plot->{plot_height} =  125 unless $plot->{plot_height};
@@ -394,54 +720,76 @@
     # Make sure the base is either 1000 or 1024.
     if (defined $plot->{base} && length($plot->{base})) {
       if ($plot->{base} != 1000 and $plot->{base} != 1024) {
-        die "$0: error: plot #$j must define base to be either 1000 or 1024.\n";
+        ++$number_errors;
+        warn "$0: error: plot #$j must set base to be either 1000 or 1024.\n";
       }
     } else {
       $plot->{base} = 1000;
     }
 
-    # Set the plot minimum and maximum values to U unless they are
-    # set.
-    $plot->{data_min} = 'U' unless defined $plot->{data_min};
-    $plot->{data_max} = 'U' unless defined $plot->{data_max};
+    # Get the number of data's in this plot.
+    my $number_datas = @{$plot->{data}};
+
+    # If the data_min and data_max are not set, then set it to U.  Use
+    # the last set data_min and data_max for those that are not set.
+    $plot->{data_min} = [] unless defined $plot->{data_min};
+    $plot->{data_max} = [] unless defined $plot->{data_max};
+    fill_append_elements($plot->{data_min}, $number_datas, 'U');
+    fill_append_elements($plot->{data_max}, $number_datas, 'U');
 
     # The data type must be either gauge, absolute, or counter.
-    if (defined $plot->{data_type}) {
-      my $type = substr($plot->{data_type}, 0, 1);
-      if ($type eq 'g' or $type eq 'G') {
-        $plot->{data_type} = 'GAUGE';
-      } elsif ($type eq 'c' or $type eq 'C') {
-        $plot->{data_type} = 'COUNTER';
-      } elsif ($type eq 'a' or $type eq 'A') {
-        $plot->{data_type} = 'ABSOLUTE';
-      } elsif ($type eq 'd' or $type eq 'D') {
-        $plot->{data_type} = 'DERIVE';
+    $plot->{data_type} = [] unless defined $plot->{data_type};
+    for (my $k=0; $k<@{$plot->{data_type}}; ++$k) {
+      my $data_type = $plot->{data_type}[$k];
+      my $first_char = lc(substr($data_type, 0, 1));
+      if ($first_char eq 'g') {
+        $plot->{data_type}[$k] = 'GAUGE';
+      } elsif ($first_char eq 'c') {
+        $plot->{data_type}[$k] = 'COUNTER';
+      } elsif ($first_char eq 'a') {
+        $plot->{data_type}[$k] = 'ABSOLUTE';
+      } elsif ($first_char eq 'd') {
+        $plot->{data_type}[$k] = 'DERIVE';
       } else {
-        die "$0: error: `data_type $plot->{data_type}' for `plot' #$j in ",
-            "`$config_filename' must be gauge, counter, derive, or absolute.\n";
+        ++$number_errors;
+        my $l = $k + 1;
+        warn "$0: error: `data_type #$l `$data_type' for `plot' #$j in ",
+             "`$config_filename' must be gauge, counter, derive, or ",
+             "absolute.\n";
       }
-    } else {
-      $plot->{data_type} = 'GAUGE';
     }
+    fill_append_elements($plot->{data_type}, $number_datas, 'GAUGE');
 
-    # The data source needs to be a valid group name.
-    my $source = $plot->{source};
-    unless (defined $config_groups{$source}) {
-      die "$0: error: plot #$j `source $source' references non-existant ",
-          "`group' in `$config_filename'.\n";
-    }
-    unless ($plot->{source}) {
-      die "$0: error: plot #$j `source $source' requires one group_name ",
-          "argument in `$config_filename'.\n";
+    # The data source needs to be a valid group name.  Replace the
+    # group's name with its index.
+    my $source = delete $plot->{source};
+    unless (defined $source) {
+      ++$number_errors;
+      warn "$0: error: plot #$j `source $source' requires one group_name ",
+           "argument in `$config_filename'.\n";
+      next;
     }
+    my $source_index = $pcl_group_name_to_index{$source};
+    unless (defined $source_index) {
+      ++$number_errors;
+      warn "$0: error: plot #$j `source $source' references non-existant ",
+           "`group' in `$config_filename'.\n";
+      next;
+    }
+    $plot->{source_index} = $source_index;
 
     # Set the legends of any columns not defined.
     $plot->{legend} = [] unless defined $plot->{legend};
-    my $number_datas = @{$plot->{data}};
     for (my $k=@{$plot->{legend}}; $k<$number_datas; ++$k) {
       $plot->{legend}[$k] = "@{$plot->{data}[$k]}";
     }
 
+    # If the generic y_legend is not set, then set it equal to the
+    # first legend.
+    unless (defined $plot->{y_legend}) {
+      $plot->{y_legend} = $plot->{legend}[0];
+    }
+
     # Set the colors of any data not defined.
     $plot->{color} = [] unless defined $plot->{color};
     for (my $k=@{$plot->{color}}; $k<$number_datas; ++$k) {
@@ -449,6 +797,7 @@
     }
 
     # Check each line type setting.
+    $plot->{line_type} = [] unless defined $plot->{line_type};
     for (my $k=0; $k<$number_datas; ++$k) {
       if (defined $plot->{line_type}[$k]) {
       my $line_type = $plot->{line_type}[$k];
@@ -459,7 +808,8 @@
         } elsif ($line_type =~ /^stack$/i) {
           $line_type = 'STACK';
         } else {
-          die "$0: error: plot #$j illegal `line_type' `$line_type'.\n";
+          ++$number_errors;
+          warn "$0: error: plot #$j illegal `line_type' `$line_type'.\n";
         }
         $plot->{line_type}[$k] = $line_type;
       } else {
@@ -467,11 +817,11 @@
       }
     }
 
-    # If the generic y_legend is not set, then set it equal to the
-    # first legend.
-    unless (defined $plot->{y_legend}) {
-      $plot->{y_legend} = $plot->{legend}[0];
-    }
+    # If the summary_format is not set, then set it to a reasonable
+    # default.  Use the last set summary_format for those that are not
+    # set.
+    $plot->{summary_format} = [] unless defined $plot->{summary_format};
+    fill_append_elements($plot->{summary_format}, $number_datas, '%9.3lf %S');
 
     # If the title is not set, then set it equal to all of the legends
     # with the group name prepended.
@@ -485,6 +835,11 @@
     }
   }
 
+  if ($number_errors) {
+    die "$0: loading configuration file `$config_filename' got ",
+        "$number_errors error(s).\n";
+  }
+
   1;
 }
 
@@ -504,6 +859,8 @@
   $path;
 }
 
+# Go through each input line separately and keep a state of the type
+# of object being processed between global, group and plot options.
 sub process_config_line {
   my ($config_filename, $line_number, $line) = @_;
 
@@ -515,24 +872,28 @@
   # options that do not require an option argument and do not supply
   # one.
   if ($key ne '}') {
-    if (grep {$key eq $_} @pcl_no_arg_elements) {
+    if ($pcl_no_arg_elements{$key}) {
       push(@line, 1) unless @line;
     } else {
       unless (@line) {
-        warn "$0: warning: option `$key' needs arguments in `$config_filename' line $line_number.\n";
+        ++$number_errors;
+        warn "$0: warning: option `$key' needs arguments in ",
+             "`$config_filename' line $line_number.\n";
         return;
       }
     }
   }
 
-  # Clean up paths in the following order:
+  # If the option is a file path option, then clean up paths in the
+  # following order:
   # 1) Trim the path.
   # 2) Prepend the base_dir to paths that are not prepended by
   #    ^\\?\.{0,2}/, which matches /, ./, ../, and \./.
   # 3) Trim the resulting path.
-  if (grep {$key eq $_} @pcl_filepath_elements) {
-    my $base_dir = defined $config_options{base_dir}?
-      _trim_path($config_options{base_dir}) : '';
+  if ($pcl_filepath_elements{$key}) {
+    my $base_dir = defined $config_global{base_dir} ?
+                  _trim_path($config_global{base_dir}) :
+                  '';
     for (my $i=0; $i<@line; ++$i) {
       my $path = _trim_path($line[$i]);
       if ($base_dir) {
@@ -544,47 +905,51 @@
 
   my $value = "@line";
 
-  # Process the line differently if we're reading for a particular
-  # option.  This one is for groups.
-  if ($pcl_group_name) {
-    if ($key eq '}') {
-      $pcl_group_name = '';
-      return;
-    }
-    unless (grep {$key eq $_} @pcl_group_elements) {
-      warn "$0: warning: directive `$key' unknown for group at line $line_number in `$config_filename'.\n";
-      return;
-    }
-
-    if (defined $config_groups{$pcl_group_name}{$key}) {
-      warn "$0: warning: `$key' for group already defined at line $line_number in `$config_filename'.\n";
-    }
-    if ($pcl_group_keep_as_array{$key}) {
-      $config_groups{$pcl_group_name}{$key} = [ @line ];
-    } else {
-      $config_groups{$pcl_group_name}{$key} = $value;
-    }
-    return;
+  # Now check if a group or plot is being processed by examining the
+  # state variables.
+  my $index_ref;
+  my $config_ref;
+  my $pcl_elements_ref;
+  my $pcl_keep_as_array_ref;
+  my $pcl_append_elements_ref;
+  my $label;
+  if (substr($pcl_group_index, 0, 1) ne '-') {
+    $index_ref               = \$pcl_group_index;
+    $config_ref              = \@config_groups;
+    $pcl_elements_ref        = \%pcl_group_elements;
+    $pcl_keep_as_array_ref   = \%pcl_group_keep_as_array;
+    $pcl_append_elements_ref = \%pcl_group_append_elements;
+    $label                   = "group `$pcl_group_name'";
+  } elsif (substr($pcl_plot_index, 0, 1) ne '-') {
+    $index_ref               = \$pcl_plot_index;
+    $config_ref              = \@config_plots;
+    $pcl_elements_ref        = \%pcl_plot_elements;
+    $pcl_keep_as_array_ref   = \%pcl_plot_keep_as_array;
+    $pcl_append_elements_ref = \%pcl_plot_append_elements;
+    $label                   = "plot #$pcl_plot_index";
   }
 
-  # Handle options for plot.
-  if ($pcl_plot_index !~ /^-/) {
+  # At this point a group or plot is being read.
+  if ($index_ref) {
     if ($key eq '}') {
-      ++$pcl_plot_index;
-      $pcl_plot_index = "-$pcl_plot_index";
+      ++$$index_ref;
+      $$index_ref = "-$$index_ref";
       return;
     }
-    unless (grep {$key eq $_} @pcl_plot_elements) {
-      warn "$0: warning: directive `$key' unknown for plot at line $line_number in `$config_filename'.\n";
+
+    unless ($pcl_elements_ref->{$key}) {
+      ++$number_errors;
+      warn "$0: warning: directive `$key' unknown for $label at line ",
+           "$line_number in `$config_filename'.\n";
       return;
     }
 
     # Handle those elements that can just append.
-    if (grep { $key eq $_ } @pcl_plot_append_elements) {
-      unless (defined $config_plots[$pcl_plot_index]{$key}) {
-        $config_plots[$pcl_plot_index]{$key} = [];
+    if ($pcl_append_elements_ref->{$key}) {
+      unless (defined $config_ref->[$$index_ref]{$key}) {
+        $config_ref->[$$index_ref]{$key} = [];
       }
-      if ($pcl_plot_keep_as_array{$key}) {
+      if ($pcl_keep_as_array_ref->{$key}) {
         push(@{$config_plots[$pcl_plot_index]{$key}}, [ @line ]);
       } else {
         push(@{$config_plots[$pcl_plot_index]{$key}}, $value);
@@ -592,57 +957,78 @@
       return;
     }
 
-    if (defined $config_plots[$pcl_plot_index]{$key}) {
-      warn "$0: warning: `$key' for plot already defined at line $line_number in `$config_filename'.\n";
+    if (defined $config_ref->[$$index_ref]{$key}) {
+      ++$number_errors;
+      warn "$0: warning: `$key' for $label already defined at line ",
+           "$line_number in `$config_filename'.\n";
       return;
     }
-    if ($pcl_plot_keep_as_array{$key}) {
-      $config_plots[$pcl_plot_index]{$key} = [ @line ];
+
+    if ($pcl_keep_as_array_ref->{$key}) {
+      $config_ref->[$$index_ref]{$key} = [ @line ];
     } else {
-      $config_plots[$pcl_plot_index]{$key} = $value;
+      $config_ref->[$$index_ref]{$key} = $value;
     }
     return;
   }
 
-  # Take care of generic options.
-  if (grep {$key eq $_} @pcl_option_elements) {
-    if ($pcl_option_keep_as_array{$key}) {
-      $config_options{$key} = [ @line ];
+  # At this point the line is either a global option or the
+  # declaration of a group or a plot.  Take care of global parameters.
+  if ($pcl_global_elements{$key}) {
+    if ($pcl_global_keep_as_array{$key}) {
+      $config_global{$key} = [ @line ];
     } else {
-      $config_options{$key} = $value;
+      $config_global{$key} = $value;
     }
     return;
   }
 
-  # Take care of a group.
+  # At this point a group or a plot is being defined.
   if ($key eq 'group') {
     unless (@line) {
       die "$0: error: group needs a group name followed by { at ",
           "line $line_number in `$config_filename'.\n"
     }
-    $pcl_group_name = shift(@line);
+    $pcl_group_index =~ s:^-::;
+    $pcl_group_name =  shift(@line);
     unless (@line == 1 and $line[0] eq '{' ) {
-      warn "$0: warning: '{' required after `group $pcl_group_name' at ",
-           "line $line_number in `$config_filename'.\n";
-    }
-    if (defined $config_groups{$pcl_group_name}) {
-      warn "$0: warning: `group $key' at line $line_number in ",
-           "`$config_filename' previously defined.\n";
+      ++$number_errors;
+      if ($pcl_group_name eq '{') {
+        warn "$0: warning: 'group_name {' required after `group' at ",
+             "line $line_number in `$config_filename'.\n";
+      } else {
+        warn "$0: warning: '{' required after `group $pcl_group_name' at ",
+             "line $line_number in `$config_filename'.\n";
+      }
     }
+    if (defined $pcl_group_name_to_index{$pcl_group_name}) {
+      ++$number_errors;
+      die "$0: warning: `group $key' at line $line_number in ",
+          "`$config_filename' previously defined.\n";
+    }
+    $config_groups[$pcl_group_index]{index}      = $pcl_group_index;
+    $config_groups_names[$pcl_group_index]       = $pcl_group_name;
+    $pcl_group_name_to_index{$pcl_group_name}    = $pcl_group_index;
     return;
   }
 
   # Take care of plots to make.  Include in each plot its index.
   if ($key eq 'plot') {
     $pcl_plot_index =~ s:^-::;
-    $config_plots[$pcl_plot_index]{_index} = $pcl_plot_index;
+    $config_plots[$pcl_plot_index]{index} = $pcl_plot_index;
     unless (@line == 1 and $line[0] eq '{') {
-      warn "$0: warning: '{' required after `plot' at line $line_number in `$config_filename'.\n";
+      ++$number_errors;
+      $label = "@line";
+      $label = " $label" if $label;
+      warn "$0: warning: '{' required immediately after plot in `plot$label' ",
+           "at line $line_number in `$config_filename'.\n";
     }
     return;
   }
 
-  warn "$0: warning: unknown directive `$key' at line $line_number in `$config_filename'.\n";
+  ++$number_errors;
+  warn "$0: warning: unknown directive `$key' at line $line_number in ",
+       "`$config_filename'.\n";
 }
 
 sub load_config {
@@ -683,7 +1069,8 @@
     $line_number = $.;
   }
 
-  # Process any remaining line.
+  # If there is any remaining text, then process it as a complete
+  # line.
   if ($complete_line) {
     process_config_line($config_filename, $line_number, $complete_line);
   }

Modified: trunk/orca/lib/Orca/RRDFile.pm
==============================================================================
--- trunk/orca/lib/Orca/RRDFile.pm	(original)
+++ trunk/orca/lib/Orca/RRDFile.pm	Sat Jul 13 21:25:46 2002
@@ -1,6 +1,6 @@
 # Orca::RRDFile: Manage RRD file creation and updating.
 #
-# Copyright (C) 1998, 1999 Blair Zajac and Yahoo!, Inc.
+# Copyright (C) 1998-2001 Blair Zajac and Yahoo!, Inc.
 
 package Orca::RRDFile;
 
@@ -9,13 +9,14 @@
 use RRDs;
 use Orca::Constants qw($opt_verbose
           	       $ORCA_RRD_VERSION
-                       $incorrect_number_of_args
                        @RRA_PDP_COUNTS
-                       @RRA_ROW_COUNTS);
-use Orca::Config    qw(%config_options
-                       %config_groups
+                       @RRA_ROW_COUNTS
+                       $INCORRECT_NUMBER_OF_ARGS);
+use Orca::Config    qw(%config_global
+                       @config_groups
+                       @config_groups_names
                        @config_plots);
-use Orca::Utils     qw(recursive_mkdir);
+use Orca::Utils     qw(name_to_fsname recursive_mkdir);
 use vars            qw($VERSION);
 
 $VERSION = substr q$Revision: 0.01 $, 10;
@@ -25,49 +26,52 @@
 # order of these indexes change, make sure to rearrange the
 # constructor in new.
 sub I_RRD_FILENAME     () { 0 }
-sub I_NAME             () { 1 }
+sub I_DATA_EXPRESSION  () { 1 }
 sub I_NEW_DATA         () { 2 }
 sub I_CREATED_IMAGES   () { 3 }
 sub I_PLOT_REF         () { 4 }
-sub I_INTERVAL         () { 5 }
-sub I_RRD_VERSION      () { 6 }
-sub I_CHOOSE_DATA_SUBS () { 7 }
-sub I_RRD_UPDATE_TIME  () { 8 }
+sub I_DATA_NUMBER      () { 5 }
+sub I_INTERVAL         () { 6 }
+sub I_RRD_VERSION      () { 7 }
+sub I_CHOOSE_DATA_SUBS () { 8 }
+sub I_RRD_UPDATE_TIME  () { 9 }
 
 sub new {
-  unless (@_ == 5) {
-    confess "$0: Orca::RRDFile::new $incorrect_number_of_args";
+  unless (@_ == 6) {
+    confess "$0: Orca::RRDFile::new $INCORRECT_NUMBER_OF_ARGS";
   }
 
   my ($class,
-      $group_name,
+      $group_index,
       $subgroup_name,
-      $name,
-      $plot_ref) = @_;
-
-  # Remove any special characters from the unique name and do some
-  # replacements.
-  $name = &::escape_name($name);
-
-  # Create the paths to the data directory.
-  my $rrd_dir = $config_options{rrd_dir};
-  if ($config_groups{$group_name}{sub_dir}) {
-    $rrd_dir .= "/$subgroup_name";
-    unless (-d $rrd_dir) {
-      warn "$0: making directory `$rrd_dir'.\n";
-      recursive_mkdir($rrd_dir);
-    }
+      $data_expression,
+      $plot_ref,
+      $data_number) = @_;
+
+  # Escape any special characters from the data expression and do some
+  # replacements to make the name shorter.  Leave space at the end of
+  # the name to append '.rrd'.
+  $data_expression = name_to_fsname($data_expression, 4);
+
+  # Create the path to the RRD directory and filename.
+  my $group_name = $config_groups_names[$group_index];
+  my $dir = "$config_global{rrd_dir}/" .
+            name_to_fsname("${group_name}_${subgroup_name}", 0);
+  unless (-d $dir) {
+    warn "$0: making directory `$dir'.\n";
+    recursive_mkdir($dir);
   }
-  my $rrd_filename = "$rrd_dir/$name.rrd";
+  my $rrd_filename = "$dir/$data_expression.rrd";
 
   # Create the new object.
   my $self = bless [
     $rrd_filename,
-    $name,
+    $data_expression,
     {},
     {},
     $plot_ref,
-    int($config_groups{$group_name}{interval}+0.5),
+    $data_number,
+    int($config_groups[$group_index]{interval}+0.5),
     $ORCA_RRD_VERSION,
     {},
     -2
@@ -120,8 +124,8 @@
   $_[0]->[I_RRD_FILENAME];
 }
 
-sub name {
-  $_[0]->[I_NAME];
+sub data_expression {
+  $_[0]->[I_DATA_EXPRESSION];
 }
 
 sub rrd_update_time {
@@ -171,13 +175,14 @@
 
     # Assume that a maximum of two time intervals are needed before a
     # data source value is set to unknown.
-    my $interval = $self->[I_INTERVAL];
-   
-    my $data_source = "DS:Orca$ORCA_RRD_VERSION:" .
-                      $self->[I_PLOT_REF]{data_type};
-    $data_source   .= sprintf ":%d:", 2*$interval;
-    $data_source   .= $self->[I_PLOT_REF]{data_min} . ':';
-    $data_source   .= $self->[I_PLOT_REF]{data_max};
+    my $interval    = $self->[I_INTERVAL];
+    my $data_number = $self->[I_DATA_NUMBER];
+    my $data_source = "DS:Orca$ORCA_RRD_VERSION:"                  .
+                      $self->[I_PLOT_REF]{data_type}[$data_number] .
+                      sprintf(":%d:", 2*$interval)                 .
+                      $self->[I_PLOT_REF]{data_min}[$data_number]  .
+                      ':'                                          .
+                      $self->[I_PLOT_REF]{data_max}[$data_number];
     my @options = ($rrd_filename,
                    '-b', $times[0]-1,
                    '-s', $interval,
@@ -186,7 +191,7 @@
     # Create the round robin archives.  Take special care to not
     # create two RRA's with the same number of primary data points.
     # This can happen if the interval is equal to one of the
-    # consoldated intervals.
+    # consolidated intervals.
     my $count          = int($RRA_ROW_COUNTS[0]*300.0/$interval + 0.5);
     my @one_pdp_option = ("RRA:AVERAGE:0.5:1:$count");
 

Modified: trunk/orca/lib/Orca/DataFile.pm
==============================================================================
--- trunk/orca/lib/Orca/DataFile.pm	(original)
+++ trunk/orca/lib/Orca/DataFile.pm	Sat Jul 13 21:25:46 2002
@@ -1,6 +1,6 @@
 # Orca::DataFile: Base class for managing source data, RRD and image files.
 #
-# Copyright (C) 1998, 1999 Blair Zajac and Yahoo!, Inc.
+# Copyright (C) 1998-2001 Blair Zajac and Yahoo!, Inc.
 
 package Orca::DataFile;
 

Modified: trunk/orca/lib/Orca/NewState.pm
==============================================================================
--- trunk/orca/lib/Orca/NewState.pm	(original)
+++ trunk/orca/lib/Orca/NewState.pm	Sat Jul 13 21:25:46 2002
@@ -1,6 +1,6 @@
 # Orca::NewState: Keep state information between invocations of Orca.
 #
-# Copyright (C) 1998, 1999 Blair Zajac and Yahoo!, Inc.
+# Copyright (C) 1998-2001 Blair Zajac and Yahoo!, Inc.
 
 package Orca::NewState;
 

Modified: trunk/orca/lib/Orca/Constants.pm
==============================================================================
--- trunk/orca/lib/Orca/Constants.pm	(original)
+++ trunk/orca/lib/Orca/Constants.pm	Sat Jul 13 21:25:46 2002
@@ -1,18 +1,15 @@
 # Orca::Constants.pm: Global constants for Orca.
 #
-# Copyright (C) 1998, 1999 Blair Zajac and Yahoo!, Inc.
+# Copyright (C) 1998-2001 Blair Zajac and Yahoo!, Inc.
 
 package Orca::Constants;
 
 use strict;
 use Exporter;
-use vars qw(@EXPORT_OK @ISA $VERSION $ORCA_VERSION $ORCA_RRD_VERSION);
-
+use vars qw(@EXPORT_OK @ISA $VERSION);
 @ISA     = qw(Exporter);
 $VERSION = substr q$Revision: 0.01 $, 10;
 
-# Define the constants.
-
 # ORCA_VERSION		This version of Orca.
 # ORCA_RRD_VERSION	This is the version number used in creating the DS
 #			names in RRDs.  This should be updated any time a
@@ -20,89 +17,149 @@
 #			RRD files.  The DS name is a concatentation of the
 #			string Orca with this string of digits.
 # DAY_SECONDS		The number of seconds in one day.
-$ORCA_VERSION        =    '0.26beta1';
-$ORCA_RRD_VERSION    =    19990222;
+# IS_WIN32		If Orca is running on a Windows platform.
+use vars         qw($ORCA_VERSION $ORCA_RRD_VERSION);
+push(@EXPORT_OK, qw($ORCA_VERSION $ORCA_RRD_VERSION DAY_SECONDS IS_WIN32));
+$ORCA_VERSION        =  '0.263';
+$ORCA_RRD_VERSION    =  19990222;
 sub DAY_SECONDS      () { 24*60*60 };
-push(@EXPORT_OK, qw($ORCA_VERSION $ORCA_RRD_VERSION DAY_SECONDS));
+sub IS_WIN32         () { $^O eq 'MSWin32' };
 
-# These define the name of the different RRAs create in each RRD file,
-# how many primary data points go into a consolidated data point, and
-# how far back in time they go.
+# These define the name of the different round robin archives (RRAs)
+# to create in each RRD file, how many primary data points go into a
+# consolidated data point, and how far back in time they go.
 #
-# The first RRA one is every 5 minutes for 200 hours, the second is
-# every 30 minutes for 31 days, the third is every 2 hours for 100
-# days, and the last is every day for 3 years.
+# The first RRA is every 5 minutes for 200 hours, the second is every
+# 30 minutes for 31 days, the third is every 2 hours for 100 days, and
+# the last is every day for 3 years.
 #
-# The first array holds the names of the different plot types to
-# create.  The second array holds the number of 300 second intervals
-# are used to create a consolidated data point.  The third array is
-# the number of consolidated data points held in the RRA.
+# The first array holds the names of the different RRAs and is also
+# used in the list of plots to create.  The second array holds the
+# number of 300 second intervals are used to create a consolidated
+# data point.  The third array is the number of consolidated data
+# points held in the RRA.
 use vars         qw(@RRA_PLOT_TYPES @RRA_PDP_COUNTS @RRA_ROW_COUNTS);
 push(@EXPORT_OK, qw(@RRA_PLOT_TYPES @RRA_PDP_COUNTS @RRA_ROW_COUNTS));
- at RRA_PLOT_TYPES = qw(daily weekly monthly yearly);
- at RRA_PDP_COUNTS =   (    1,     6,     24,   288);
- at RRA_ROW_COUNTS =   ( 2400,  1488,   1200,  1098);
-
-# Define the different plots to create.  These settings do not need to
-# be exactly the same as the RRA definitions, but they can be.  Here
-# create a quarterly plot (100 days) between the monthly and yearly
-# plots.  The quarterly plot is updated daily.  The last array here
-# holds the number of days back in time to place data in the plot.  Be
-# careful to not increase this so much that the number of data points
-# to plot are greater than the number of pixels available for the
-# image, otherwise there will be a 30% slowdown due to a reduction
+BEGIN {
+  @RRA_PLOT_TYPES = qw(daily weekly monthly yearly);
+  @RRA_PDP_COUNTS =   (    1,     6,     24,   288);
+  @RRA_ROW_COUNTS =   ( 2400,  1488,   1200,  1098);
+}
+
+# Define all of the the different possible plots to create.  This
+# structure allows allows the user via the configuration file to turn
+# off particular plots to create, such the monthly one.  In addition
+# to the plot types that are structured in the RRD via its RRA's,
+# there is an additional hourly plot that is listed before the daily
+# plot and an additional quarterly plot (100 days) created between the
+# monthly and yearly plots.  The quarterly plot is updated daily.
+#
+# For each plot type, the first value in the array reference is the
+# number of 300 second intervals are used in a plot.  The second value
+# is the number of seconds graphed in the plots.  Be careful to not
+# increase the time interval so much that the number of data points to
+# plot are greater than the number of pixels available for the image,
+# otherwise there will be a 30% slowdown due to a reduction
 # calculation to resample the data to the lower resolution for the
 # plot.  For example, with 40 days of 2 hour data, there are 480 data
 # points.  For no slowdown to occur, the image should be at least 481
 # pixels wide.
-use vars         qw(@IMAGE_PLOT_TYPES @IMAGE_PDP_COUNTS @IMAGE_DAYS_BACK);
-push(@EXPORT_OK, qw(@IMAGE_PLOT_TYPES @IMAGE_PDP_COUNTS @IMAGE_DAYS_BACK));
- at IMAGE_PLOT_TYPES = (@RRA_PLOT_TYPES[0..2], 'quarterly', $RRA_PLOT_TYPES[3]);
- at IMAGE_PDP_COUNTS = (@RRA_PDP_COUNTS[0..2], @RRA_PDP_COUNTS[3, 3]);
- at IMAGE_DAYS_BACK  = (  1.5,  10,  40, 100, 428);
-# Data points ->    (432  , 480, 480, 100, 428);
-
-# This subroutine is compiled once to prevent compiling of the
-# subroutine sub { die $_[0] } every time an eval block is entered.
-sub die_when_called {
-  die $_[0];
+#
+# The @CONST_IMAGE_PLOT_TYPES variable contains the order in which
+# plots are created and all of the elements of
+# @CONST_IMAGE_PLOT_TITLES should appear as keys in
+# @CONST_IMAGE_PLOT_INFO.
+use vars         qw(@CONST_IMAGE_PLOT_TYPES %CONST_IMAGE_PLOT_INFO);
+push(@EXPORT_OK, qw(@CONST_IMAGE_PLOT_TYPES %CONST_IMAGE_PLOT_INFO));
+BEGIN {
+  @CONST_IMAGE_PLOT_TYPES = qw(hourly daily weekly monthly quarterly yearly);
+  %CONST_IMAGE_PLOT_INFO   =
+  ('hourly'    => [$RRA_PDP_COUNTS[0],   1.5*60*60],        #  18 data points
+   'daily'     => [$RRA_PDP_COUNTS[0],   1.5*DAY_SECONDS],  # 432 data points
+   'weekly'    => [$RRA_PDP_COUNTS[1],  10  *DAY_SECONDS],  # 480 data points
+   'monthly'   => [$RRA_PDP_COUNTS[2],  40  *DAY_SECONDS],  # 480 data points
+   'quarterly' => [$RRA_PDP_COUNTS[3], 100  *DAY_SECONDS],  # 100 data points
+   'yearly'    => [$RRA_PDP_COUNTS[3], 428  *DAY_SECONDS]); # 428 data points
+
+  # Ensure that the number of elements of @CONST_IMAGE_PLOT_TYPES
+  # exactly matches the keys of %CONST_IMAGE_PLOT_INFO.
+  unless (@CONST_IMAGE_PLOT_TYPES == keys %CONST_IMAGE_PLOT_INFO) {
+      die "$0: internal error: number of elements in ",
+          "\@CONST_IMAGE_PLOT_TYPES does not match number of keys in ",
+          "\%CONST_IMAGE_PLOT_INFO.\n";
+  }
+
+  foreach my $title (@CONST_IMAGE_PLOT_TYPES) {
+    unless (defined $CONST_IMAGE_PLOT_INFO{$title}) {
+      die "$0: internal error: element `$title' in ",
+          "\@CONST_IMAGE_PLOT_TYPES is not a key in ",
+          "\%CONST_IMAGE_PLOT_INFO.\n";
+    }
+  }
 }
-push(@EXPORT_OK, qw(die_when_called));
+
+# These variables hold copies of @CONST_IMAGE_PLOT_TYPES and
+# @CONST_IMAGE_PLOT_INFO with only those plot types that are specified
+# in the configuration file.
+use vars         qw(@IMAGE_PLOT_TYPES @IMAGE_PDP_COUNTS @IMAGE_TIME_SPAN);
+push(@EXPORT_OK, qw(@IMAGE_PLOT_TYPES @IMAGE_PDP_COUNTS @IMAGE_TIME_SPAN));
+
+# This holds the length of the longest plot type string that is
+# specified in the configuration file.
+use vars         qw($MAX_PLOT_TYPE_LENGTH);
+push(@EXPORT_OK, qw($MAX_PLOT_TYPE_LENGTH));
 
 # These variables are set once at program start depending upon the
-# command line arguments.
-#
+# command line arguments:
+# $opt_daemon			Daemonize Orca.
 # $opt_generate_gifs		Generate GIFs instead of PNGs.
+# $opt_log_filename		Output log filename.
 # $opt_once_only		Do only one pass through Orca.
-# $opt_rrd_update_only		Do not generate any images.
+# $opt_no_html			Do not generate any HTML files.
+# $opt_no_images		Do not generate any image files.
 # $opt_verbose			Be verbose about my running.
-#
-use vars         qw($opt_generate_gifs
+use vars         qw($opt_daemon
+                    $opt_generate_gifs
+                    $opt_log_filename
+                    $opt_no_html
+                    $opt_no_images
                     $opt_once_only
-                    $opt_rrd_update_only
                     $opt_verbose
                     $IMAGE_SUFFIX);
-push(@EXPORT_OK, qw($opt_generate_gifs
+push(@EXPORT_OK, qw($opt_daemon
+                    $opt_generate_gifs
+                    $opt_log_filename
+                    $opt_no_html
+                    $opt_no_images
                     $opt_once_only
-                    $opt_rrd_update_only
                     $opt_verbose
                     $IMAGE_SUFFIX));
+$opt_daemon          = 0;
 $opt_generate_gifs   = 0;
+$opt_log_filename    = '';
+$opt_no_html         = 0;
+$opt_no_images       = 0;
 $opt_once_only       = 0;
-$opt_rrd_update_only = 0;
 $opt_verbose         = 0;
 $IMAGE_SUFFIX        = 'png';
 
+# This constant stores the commonly used string to indicate that a
+# subroutine has been passed an incorrect number of arguments.
+use vars qw($INCORRECT_NUMBER_OF_ARGS);
+push(@EXPORT_OK, qw($INCORRECT_NUMBER_OF_ARGS));
+$INCORRECT_NUMBER_OF_ARGS = "passed incorrect number of arguments.\n";
+
+# This subroutine is compiled once to prevent compiling of the
+# subroutine sub { die $_[0] } every time an eval block is entered.
+sub die_when_called {
+  die $_[0];
+}
+push(@EXPORT_OK, qw(die_when_called));
+
 # This contains the regular expression string to check if a string
 # contains the "sub {" and "}" portions or this should be added.
 use vars         qw($is_sub_re);
 push(@EXPORT_OK, qw($is_sub_re));
 $is_sub_re = '^\s*sub\s*{.*}\s*$';
 
-# This constant stores the commonly used string to indicate that a
-# subroutine has been passed an incorrect number of arguments.
-use vars qw($incorrect_number_of_args);
-push(@EXPORT_OK, qw($incorrect_number_of_args));
-$incorrect_number_of_args = "passed incorrect number of arguments.\n";
-
 1;

Modified: trunk/orca/lib/Orca/OldState.pm
==============================================================================
--- trunk/orca/lib/Orca/OldState.pm	(original)
+++ trunk/orca/lib/Orca/OldState.pm	Sat Jul 13 21:25:46 2002
@@ -1,13 +1,13 @@
 # Orca::OldState: Keep state information between invocations of Orca.
 #
-# Copyright (C) 1998-2000 Blair Zajac and Yahoo!, Inc.
+# Copyright (C) 1998-2001 Blair Zajac and Yahoo!, Inc.
 
 package Orca::OldState;
 
 use strict;
 use Carp;
 use Orca::Constants     qw($opt_verbose
-                           $incorrect_number_of_args);
+                           $INCORRECT_NUMBER_OF_ARGS);
 use Orca::SourceFileIDs qw(@sfile_fids);
 use vars                qw(@EXPORT_OK @ISA $VERSION);
 
@@ -28,7 +28,7 @@
 # This loads the old source file state information.
 sub load_old_state {
   unless (@_ == 1) {
-    confess "$0: Orca::OldState::load_old_state $incorrect_number_of_args";
+    confess "$0: Orca::OldState::load_old_state $INCORRECT_NUMBER_OF_ARGS";
   }
 
   my $state_file = shift;
@@ -85,7 +85,7 @@
 # Write the state information for the source data files.
 sub save_old_state {
   unless (@_ == 2) {
-    confess "$0: Orca::OldState::save_old_state $incorrect_number_of_args";
+    confess "$0: Orca::OldState::save_old_state $INCORRECT_NUMBER_OF_ARGS";
   }
 
   my ($state_file, $state_ref) = @_;

Modified: trunk/orca/lib/Orca/SourceFile.pm
==============================================================================
--- trunk/orca/lib/Orca/SourceFile.pm	(original)
+++ trunk/orca/lib/Orca/SourceFile.pm	Sat Jul 13 21:25:46 2002
@@ -1,6 +1,6 @@
 # Orca::SourceFile: Manage the watching and loading of source data files.
 #
-# Copyright (C) 1998, 1999 Blair Zajac and Yahoo!, Inc.
+# Copyright (C) 1998-2001 Blair Zajac and Yahoo!, Inc.
 
 package Orca::SourceFile;
 
@@ -9,10 +9,11 @@
 use Digest::MD5         qw(md5);
 use Storable            qw(dclone);
 use Orca::Constants     qw($opt_verbose
-                           $incorrect_number_of_args
-                           die_when_called);
-use Orca::Config        qw(%config_options
-                           %config_groups
+                           die_when_called
+                           $INCORRECT_NUMBER_OF_ARGS);
+use Orca::Config        qw(%config_global
+                           @config_groups
+                           @config_groups_names
                            @config_plots
                            get_color);
 use Orca::OldState      qw($orca_old_state);
@@ -21,6 +22,7 @@
 use Orca::SourceFileIDs qw(@sfile_fids);
 use Orca::ImageFile;
 use Orca::RRDFile;
+use Orca::Utils         qw(email_message);
 use vars                qw(@ISA $VERSION);
 
 @ISA     = qw(Orca::DataFile);
@@ -28,7 +30,7 @@
 
 # This is a static variable that lists all of the column names for a
 # particular group.
-my %group_column_names;
+my @group_column_names;
 
 # This caches the reference to the array holding the column
 # descriptions for files that have their column descriptions in the
@@ -47,13 +49,13 @@
 # using the ORCA_DATAFILE_LAST_INDEX index.  Define these constant
 # subroutines as indexes into the array.  If the order of these
 # indexes change, make sure to rearrange the constructor in new.
-sub I_INTERVAL           () { ORCA_DATAFILE_LAST_INDEX +  1 }
-sub I_LATE_INTERVAL      () { ORCA_DATAFILE_LAST_INDEX +  2 }
-sub I_READ_INTERVAL      () { ORCA_DATAFILE_LAST_INDEX +  3 }
-sub I_REOPEN             () { ORCA_DATAFILE_LAST_INDEX +  4 }
-sub I_DATE_SOURCE        () { ORCA_DATAFILE_LAST_INDEX +  5 }
-sub I_DATE_FORMAT        () { ORCA_DATAFILE_LAST_INDEX +  6 }
-sub I_WARN_EMAIL         () { ORCA_DATAFILE_LAST_INDEX +  7 }
+sub I_GROUP_INDEX        () { ORCA_DATAFILE_LAST_INDEX +  1 }
+sub I_INTERVAL           () { ORCA_DATAFILE_LAST_INDEX +  2 }
+sub I_LATE_INTERVAL      () { ORCA_DATAFILE_LAST_INDEX +  3 }
+sub I_READ_INTERVAL      () { ORCA_DATAFILE_LAST_INDEX +  4 }
+sub I_REOPEN             () { ORCA_DATAFILE_LAST_INDEX +  5 }
+sub I_DATE_SOURCE        () { ORCA_DATAFILE_LAST_INDEX +  6 }
+sub I_DATE_PARSE         () { ORCA_DATAFILE_LAST_INDEX +  7 }
 sub I_MY_RRD_LIST        () { ORCA_DATAFILE_LAST_INDEX +  8 }
 sub I_ALL_RRD_REF        () { ORCA_DATAFILE_LAST_INDEX +  9 }
 sub I_GROUP_KEYS         () { ORCA_DATAFILE_LAST_INDEX + 10 }
@@ -67,60 +69,36 @@
 sub I_IS_CURRENT_DAY     () { ORCA_DATAFILE_LAST_INDEX + 18 }
 
 sub new {
-  unless (@_ == 9) {
-    confess "$0: Orca::SourceFile::new passed $incorrect_number_of_args";
+  unless (@_ == 3) {
+    confess "$0: Orca::SourceFile::new passed $INCORRECT_NUMBER_OF_ARGS";
   }
 
-  my ($class,
-      $fid,
-      $interval,
-      $late_interval,
-      $reopen,
-      $column_description,
-      $date_source,
-      $date_format,
-      $warn_email) = @_;
+  my ($class, $group_index, $fid) = @_;
 
   my $self = $class->SUPER::new($fid);
 
+  my $config_group = $config_groups[$group_index];
+
   # Set the last value to preexpand the array.
   $self->[I_IS_CURRENT_DAY]     = undef;
-  $self->[I_INTERVAL]           = $interval;
-  $self->[I_LATE_INTERVAL]      = int(&$late_interval($interval) + 0.5);
-  $self->[I_REOPEN]             = $reopen;
-  $self->[I_DATE_SOURCE]        = $date_source;
-  $self->[I_DATE_FORMAT]        = $date_format;
-  $self->[I_WARN_EMAIL]         = $warn_email;
+  $self->[I_GROUP_INDEX]        = $group_index;
+  $self->[I_INTERVAL]           = $config_group->{interval};
+  $self->[I_LATE_INTERVAL]      = $config_group->{late_interval};
+  $self->[I_READ_INTERVAL]      = $config_group->{read_interval};
+  $self->[I_REOPEN]             = $config_group->{reopen};
+  $self->[I_DATE_SOURCE]        = $config_group->{date_source};
+  $self->[I_DATE_PARSE]         = $config_group->{date_parse};
   $self->[I_MY_RRD_LIST]        = [];
   $self->[I_ALL_RRD_REF]        = undef;
   $self->[I_GROUP_KEYS]         = {};
   $self->[I_CHOOSE_DATA_SUB]    = undef;
 
-  $self->[I_COLUMN_DESCRIPTION] = $column_description;
+  $self->[I_COLUMN_DESCRIPTION] = $config_group->{column_description};
   $self->[I_LAST_DATA_TIME]     = -1;
   $self->[I_LAST_READ_TIME]     = -1;
   $self->[I_FIRST_LINE]         =  0;
   $self->[I_DATE_COLUMN_INDEX]  = undef;
 
-  # There are three intervals associated with each file.  The first is
-  # the data update interval.  This is the same interval used to
-  # generate the RRDs.  The second interval is the interval before the
-  # file is considered late and is larger than the data update
-  # interval.  This interval is calculated by using the mathematical
-  # expression given in the `late_interval' configuration option.  If
-  # `late_interval' is not defined, then it gets defaulted to the data
-  # update interval.  The last interval is the interval to use to tell
-  # the program when to attempt to read the file next.  Because it can
-  # take some time for the source files to be updated, we don't want
-  # to read the file immediately after the data update interval is
-  # done.  For this reason, choose a read interval that is somewhere
-  # in between the data source interval and the late interval.  Use
-  # the multiplicative average of the data update interval and the
-  # late interval since the resulting value is closer to the data
-  # update interval.  Ie: (20 + 5)/2 = 12.5.  Sqrt(20*5) = 10.
-  my $read_interval = sqrt($self->[I_INTERVAL]*$self->[I_LATE_INTERVAL]);
-  $self->[I_READ_INTERVAL] = int($read_interval + 0.5);
-
   # Load in any state information for this file.
   my $filename = $sfile_fids[$fid];
   my @column_description;
@@ -147,7 +125,7 @@
 #  } else {
 #  }
 #  # If the source data file does not exist in the state database, then
-#  # create a new default entry.  If the file does not exist, then reset to 
+#  # create a new default entry.  If the file does not exist, then reset to
 #  # If the source file's mtime is the same as stored in the saved
 #  # state file, then load all the information from it, otherwise do
 #  # not keep any of it and load the file freshly.
@@ -200,10 +178,10 @@
 sub add_groups {
   my $self = shift;
 
-  foreach my $group_name (@_) {
-    $self->[I_GROUP_KEYS]{$group_name} = 1;
+  foreach my $group_index (@_) {
+    $self->[I_GROUP_KEYS]{$group_index} = 1;
     foreach my $description (@{$self->[I_COLUMN_DESCRIPTION]}) {
-      $group_column_names{$group_name}{$description} = 1;
+      $group_column_names[$group_index]{$description} = 1;
     }
   }
 }
@@ -273,20 +251,23 @@
 sub add_plots {
   # Make sure that the user has called the add_groups method and
   # inserted at least one key.
-  unless (keys %group_column_names) {
-    confess "$0: Orca::SourceFile::add_groups must be called before add_plots.\n";
+  unless (@group_column_names) {
+    confess "$0: Orca::SourceFile::add_groups must be called before ",
+            "add_plots.\n";
   }
 
   unless (@_ == 5) {
-    confess "$0: Orca::SourceFile::add_plots passed wrong number of arguments.\n";
+    confess "$0: Orca::SourceFile::add_plots $INCORRECT_NUMBER_OF_ARGS";
   }
 
   my ($self,
-      $group_name,
+      $group_index,
       $subgroup_name,
       $rrd_data_files_ref,
       $image_files_ref) = @_;
 
+  my $group_name = $config_groups_names[$group_index];
+
   # See if we have already done all the work for a plot with this group_name,
   # subgroup_name, and column description.  Use an MD5 hash instead of a very
   # long key.  Store into a hash the column names found in this file for this
@@ -335,9 +316,9 @@
 
     my $plot = $config_plots[$i];
 
-    # Skip this plot if the group_name do not match.  Increment the
-    # index of the next plot to handle.
-    if ($plot->{source} ne $group_name) {
+    # Skip this plot if the source group indexes does not match.
+    # Increment the index of the next plot to handle.
+    if ($plot->{source_index} != $group_index) {
       if ($oldest_regexp_index == $i) {
         $handle_regexps = 0;
         ++$oldest_regexp_index;
@@ -411,7 +392,22 @@
 
         # Copy any items over that haven't been created for this new
         # data source.  Make sure that any new elements added to
-        # pcl_plot_append_elements show up here.
+        # pcl_plot_append_elements show up here.  The first data_min,
+        # data_max, data_type, and summary_format are always set and
+        # if any later ones are not set, then use the previously set
+        # one.
+        unless (defined $plot->{data_min}[$new_data_index]) {
+          $plot->{data_min}[$new_data_index] =
+            $plot->{data_min}[$new_data_index-1];
+        }
+        unless (defined $plot->{data_max}[$new_data_index]) {
+          $plot->{data_max}[$new_data_index] =
+            $plot->{data_max}[$new_data_index-1];
+        }
+        unless (defined $plot->{data_type}[$new_data_index]) {
+          $plot->{data_type}[$new_data_index] =
+            $plot->{data_type}[$new_data_index-1];
+        }
         unless (defined $plot->{color}[$new_data_index]) {
           $plot->{color}[$new_data_index] = get_color($new_data_index);
         }
@@ -421,6 +417,10 @@
         unless (defined $plot->{line_type}[$new_data_index]) {
           $plot->{line_type}[$new_data_index] = $plot->{line_type}[0];
         }
+        unless (defined $plot->{summary_format}[$new_data_index]) {
+          $plot->{summary_format}[$new_data_index] =
+            $plot->{summary_format}[$new_data_index-1];
+        }
 
         # Replace the regular expression in any legend elements.
         my $legend = $plot->{legend}[$new_data_index];
@@ -542,7 +542,7 @@
         if (defined ($pos = $column_description{$element})) {
           $datas[$j][$k]  = "\$_[$pos]";
           $match_one_data = 1;
-        } elsif (defined $group_column_names{$group_name}{$element}) {
+        } elsif (defined $group_column_names[$group_index]{$element}) {
           my $m = $old_i + 1;
           if ($required) {
             warn "$0: $element in `data @{$plot->{data}[$j]}' in plot #$m ",
@@ -637,43 +637,55 @@
     my @my_short_rrds;
     my @name_with_subgroup;
     my @name_without_subgroup;
-    my $previous_group    = '';
-    my $previous_subgroup = '';
+    my $previous_data_type     = '';
+    my $previous_group_index   = -1;
+    my $previous_subgroup_name = '';
     for (my $j=0; $j<@substituted_data_expressions; ++$j) {
 
+      # Include in the original data expression the data_type that RRD
+      # will apply to the input data.
+      my $data_type                   = lc($plot->{data_type}[$j]);
       my $original_data_expression    = join('_', @{$plot->{data}[$j]});
       my $substituted_data_expression = $substituted_data_expressions[$j];
 
-      my $name_with_subgroup = "${group_name}_${subgroup_name}_${original_data_expression}";
-      push(@name_with_subgroup, $name_with_subgroup);
-      push(@name_without_subgroup, "${group_name}_${original_data_expression}");
+      my $name_with_subgroup = "${group_name}_${subgroup_name}_${data_type}_${original_data_expression}";
+      push(@name_with_subgroup,    $name_with_subgroup);
+      push(@name_without_subgroup, "${group_name}_${data_type}_${original_data_expression}");
 
-      # Create a short name that may exclude the group and subgroup if the
-      # previous data had the same group and subgroup.
+      # If the current data expression is very similar to the previous
+      # one, then do not include the group, subgroup and data_type.
       my $short_name_with_subgroup;
-      if ($group_name eq $previous_group) {
-        if ($subgroup_name eq $previous_subgroup) {
-          $short_name_with_subgroup = "__$original_data_expression";
-        } else {
-          $short_name_with_subgroup = "_${subgroup_name}_${original_data_expression}";
-          $previous_subgroup        = $subgroup_name;
-        }
+      if ($group_index == $previous_group_index) {
+        $short_name_with_subgroup  = '_';
+      } else {
+        $short_name_with_subgroup  = "${group_name}_";
+        $previous_group_index      = $group_index;
+      }
+      if ($subgroup_name eq $previous_subgroup_name) {
+        $short_name_with_subgroup .= '_';
       } else {
-        $previous_group           = $group_name;
-        $previous_subgroup        = $subgroup_name;
-        $short_name_with_subgroup = $name_with_subgroup;
+        $short_name_with_subgroup .= "${subgroup_name}_";
+        $previous_subgroup_name    = $subgroup_name;
       }
+      if ($data_type eq $previous_data_type) {
+        $short_name_with_subgroup .= '_';
+      } else {
+        $short_name_with_subgroup .= "${data_type}_";
+        $previous_data_type        = $data_type;
+      }
+      $short_name_with_subgroup   .= $original_data_expression;
 
-      # Create a new RRD only if it doesn't already exist and if a valid
-      # get data subroutine is created.  Keep the choose_data_sub for this
-      # file.
+      # Create a new RRD only if it doesn't already exist and if a
+      # valid get data subroutine is created.  Keep the
+      # choose_data_sub for this file.
       if (defined $substituted_data_expression) {
         $choose_data_expr .= "    '$name_with_subgroup', $substituted_data_expression,\n";
         unless (defined $rrd_data_files_ref->{$name_with_subgroup}) {
-          my $rrd_file = Orca::RRDFile->new($group_name,
+          my $rrd_file = Orca::RRDFile->new($group_index,
                                             $subgroup_name,
-                                            $name_with_subgroup,
-                                            $plot);
+                                            "${data_type}_${original_data_expression}",
+                                            $plot,
+                                            $j);
           $rrd_data_files_ref->{$name_with_subgroup} = $rrd_file;
         }
         $self->[I_ALL_RRD_REF]            = $rrd_data_files_ref;
@@ -686,10 +698,10 @@
     # Generate a new plot for these data.
     my $image;
     my $all_names_with_subgroup = join(',', @name_with_subgroup);
-    if (defined ($image = $image_files_ref->{hash}{$all_names_with_subgroup})) {
+    if (defined ($image = $image_files_ref->{hash}{$all_names_with_subgroup})){
       $image->add_rrds(@my_rrds);
     } else {
-      $image = Orca::ImageFile->new($group_name,
+      $image = Orca::ImageFile->new($group_index,
                                     $subgroup_name,
                                     join(',', @my_short_rrds),
                                     join(',', @name_without_subgroup),
@@ -741,7 +753,7 @@
   my $load_data   = $file_status != 0;
   if ($file_status == -1) {
     my $message = "file `$sfile_fids[$fid]' did exist and is now gone.";
-    ::email_message($self->[I_WARN_EMAIL], $message);
+    email_message($config_global{warn_email}, $message);
     warn "$0: warning: $message\n";
     unless ($fd) {
       $self->[I_LAST_READ_TIME] = -1;
@@ -761,7 +773,7 @@
       ($old_is_current_day == $current_day)) {
     my $message = "file `$sfile_fids[$fid]' was current and now is not.";
     warn "$0: warning: $message\n";
-    ::email_message($self->[I_WARN_EMAIL], $message);
+    email_message($config_global{warn_email}, $message);
   }
 
   # If we don't have to load the data from this file yet, then test to
@@ -799,12 +811,22 @@
     <$fd> if $self->[I_FIRST_LINE];
   }
 
-  # Load in all of the data possible and send it to each plot.
   my $date_column_index = $self->[I_DATE_COLUMN_INDEX];
   my $use_file_mtime    = $self->[I_DATE_SOURCE][0] eq 'file_mtime';
   my $number_added      = 0;
   my $close_once_done   = 0;
   my $number_columns    = @{$self->[I_COLUMN_DESCRIPTION]};
+
+  # Get the filename if the measurement time is loaded from the file
+  # instead of from the last modified time and the time should be
+  # parsed using the date_parse subroutine.
+  my $date_parse = $self->[I_DATE_PARSE];
+  my $filename;
+  if (!$use_file_mtime and $date_parse) {
+    $filename = $sfile_fids[$self->fid];
+  }
+
+  # Load in all of the data possible and send it to each plot.
   while (defined(my $line = <$fd>)) {
     # Skip the line if the word timestamp appears in it.  This is a
     # temporary fix for orcallator.se to place a new information line
@@ -817,11 +839,19 @@
     # define the column names, 2) the number of columns loaded is not
     # equal to the number of columns in the column description.
     if ($self->[I_FIRST_LINE] and @line != $number_columns) {
-      warn "$0: number of columns in line $. of `$sfile_fids[$fid]' does not match column description.\n";
+      warn "$0: number of columns in line $. of `$sfile_fids[$fid]' does not ",
+           "match column description.\n";
       next;
     }
 
-    my $time = $use_file_mtime ? $self->file_mtime : $line[$date_column_index];
+    my $time;
+    if ($use_file_mtime) {
+      $time = $self->file_mtime;
+    } elsif ($filename) {
+      $time = &$date_parse($filename, $line[$date_column_index]);
+    } else {
+      $time = $line[$date_column_index];
+    }
     $last_data_time = $time if $time > $last_data_time;
 
     # If the file status from the source data file is greater than
@@ -842,7 +872,9 @@
         }
       } else {
         $close_once_done = 1;
-        warn "$0: internal error: expecting RRD name `$rrd_key' but no data loaded from `" . $self->filename . "' at time ", scalar localtime($time), " ($time).\n";
+        warn "$0: internal error: expecting RRD name `$rrd_key' but no data ",
+             "loaded from `", $self->filename, "' at time ",
+             scalar localtime($time), " ($time).\n";
       }
     }
     ++$number_added if $add;

Modified: trunk/orca/lib/Orca/Utils.pm
==============================================================================
--- trunk/orca/lib/Orca/Utils.pm	(original)
+++ trunk/orca/lib/Orca/Utils.pm	Sat Jul 13 21:25:46 2002
@@ -1,24 +1,50 @@
 # Orca::Utils: Small utility subroutines.
 #
-# Copyright (C) 1998, 1999 Blair Zajac and Yahoo!, Inc.
+# Copyright (C) 1998-2001 Blair Zajac and Yahoo!, Inc.
 
 package Orca::Utils;
 
 use strict;
 use Carp;
 use Exporter;
-use Orca::Constants     qw($incorrect_number_of_args);
+use Digest::MD5         qw(md5_base64);
+use Orca::Constants     qw($INCORRECT_NUMBER_OF_ARGS);
+use Orca::Config        qw(%config_global);
 use Orca::SourceFileIDs qw(new_fids);
 use vars qw(@EXPORT_OK @ISA $VERSION);
 
- at EXPORT_OK = qw(gcd perl_glob recursive_mkdir unique);
+ at EXPORT_OK = qw(email_message
+                gcd name_to_fsname
+                perl_glob
+                recursive_mkdir
+                unique);
 @ISA       = qw(Exporter);
 $VERSION   = substr q$Revision: 0.01 $, 10;
 
+# Email the list of people a message.
+sub email_message {
+  my ($people, $subject) = @_;
+
+  return unless $people;
+
+  if (open(SENDMAIL, "|/usr/lib/sendmail -oi -t")) {
+    print SENDMAIL <<"EOF";
+To: $people
+Subject: Orca: $subject
+
+Orca: $subject
+EOF
+    close(SENDMAIL) or
+      warn "$0: warning: sendmail did not close: $!\n";
+  } else {
+    warn "$0: warning: cannot fork for sendmail: $!\n";
+  }
+}
+
 # Return the greatest common divisor.
 sub gcd {
   unless (@_ == 2) {
-    confess "$0: Orca::Utils::gcd $incorrect_number_of_args";
+    confess "$0: Orca::Utils::gcd $INCORRECT_NUMBER_OF_ARGS";
   }
   my ($m, $n) = @_;
   if ($n > $m) {
@@ -33,6 +59,77 @@
   $n;
 }
 
+# Replace special characters from names, remove redundant characters,
+# and shorten the names so the maximum path name is not exceeded.  If
+# the name is still too long such that the maximum filename path
+# length ($config_global{max_filename_length}) may be exceeded by
+# appending -daily.html or other names to the name, then compute a MD5
+# hash of the name, trim the name the name to max_filename_length
+# minus at least 23 plus the postfix length characters to leave space
+# for a 22 byte base64 MD5 digest, plus a separating '-', and plus the
+# postfix.
+sub name_to_fsname {
+  unless (@_ == 2) {
+    confess "$0: Orca::Utils::name_to_fsname $INCORRECT_NUMBER_OF_ARGS";
+  }
+
+  my ($name, $postfix_length) = @_;
+
+  $name =~ s/:/_/g;
+  $name =~ s:/:_per_:g;
+  $name =~ s:\s+:_:g;
+  $name =~ s:%:_pct_:g;
+  $name =~ s:#:_num_:g;
+  $name =~ s:\*:_X_:g;
+
+  # Trim anything containing orcallator and orca to o.
+  $name =~ s:orcallator:o:g;
+  $name =~ s:orca:o:g;
+
+  # Remove trailing _'s.
+  $name =~ s:_+$::;
+  $name =~ s:_+,:,:g;
+
+  # Replace multiple _'s with one _, except when they follow a , which
+  # happens when the same group and subgroup appear for a new data
+  # source.
+  $name =~ s:,_{2,}:\200:g;
+  $name =~ s:_{2,}:_:g;
+  $name =~ s:\200:,__:g;
+
+  my $max_filename_length = $config_global{max_filename_length};
+  if (length($name)+$postfix_length > $max_filename_length) {
+
+    my $md5         = md5_base64($name);
+    my $trim_length = $max_filename_length - 23 - $postfix_length;
+    $name           = substr($name, 0, $trim_length) . "-$md5";
+
+    # Be careful to convert any /, \ or + characters to _.  The /
+    # character definitely needs to be modified since / is a valid
+    # base64 character and can't be used since we don't want a
+    # directory.
+    $name =~ s:[/\\\+]:_:g;
+  }
+
+  $name;
+}
+
+sub old_name_to_fsname {
+  my $name = shift;
+  $name =~ s/:/_/g;
+  $name =~ s:/:_per_:g;
+  $name =~ s:\s+:_:g;
+  $name =~ s:%:_percent_:g;
+  $name =~ s:#:_number_:g;
+  $name =~ s:\*:_X_:g;
+  $name =~ s:([_,]){2,}:$1:g;
+
+  # Remove trailing _'s.
+  $name =~ s:_+$::;
+  $name =~ s:_+,:,:g;
+  $name;
+}
+
 # Find all files matching a particular Perl regular expression and
 # return file ids.
 sub perl_glob {

Modified: trunk/orca/lib/Orca/SourceFileIDs.pm
==============================================================================
--- trunk/orca/lib/Orca/SourceFileIDs.pm	(original)
+++ trunk/orca/lib/Orca/SourceFileIDs.pm	Sat Jul 13 21:25:46 2002
@@ -2,7 +2,7 @@
 # identifiers.  The primary purpose of this module is to keep only two
 # copies of all the filenames used by Orca.
 #
-# Copyright (C) 1999 Blair Zajac and Yahoo!, Inc.
+# Copyright (C) 1998-2001 Blair Zajac and Yahoo!, Inc.
 
 package Orca::SourceFileIDs;
 

Modified: trunk/orca/lib/Orca/ImageFile.pm
==============================================================================
--- trunk/orca/lib/Orca/ImageFile.pm	(original)
+++ trunk/orca/lib/Orca/ImageFile.pm	Sat Jul 13 21:25:46 2002
@@ -1,6 +1,6 @@
 # Orca::ImageFile: Manage the creation of PNG or GIF plot files.
 #
-# Copyright (C) 1998, 1999 Blair Zajac and Yahoo!, Inc.
+# Copyright (C) 1998-2001 Blair Zajac and Yahoo!, Inc.
 
 package Orca::ImageFile;
 
@@ -9,15 +9,16 @@
 use RRDs;
 use Orca::Constants qw($opt_generate_gifs
                        $opt_verbose
-                       DAY_SECONDS
                        $IMAGE_SUFFIX
                        @IMAGE_PLOT_TYPES
                        @IMAGE_PDP_COUNTS
-                       @IMAGE_DAYS_BACK);
-use Orca::Config    qw(%config_options
-                       %config_groups
+                       @IMAGE_TIME_SPAN
+                       $MAX_PLOT_TYPE_LENGTH
+                       $INCORRECT_NUMBER_OF_ARGS);
+use Orca::Config    qw(%config_global
+                       @config_groups
                        @config_plots);
-use Orca::Utils     qw(recursive_mkdir);
+use Orca::Utils     qw(name_to_fsname recursive_mkdir);
 
 use vars            qw($VERSION);
 
@@ -27,7 +28,7 @@
 # Define these constant subroutines as indexes into the array.  If
 # the order of these indexes change, make sure to rearrange the
 # constructor in new.
-sub I_GROUP_NAME       () {  0 }
+sub I_GROUP_INDEX      () {  0 }
 sub I_SUBGROUP_NAME    () {  1 }
 sub I_NO_SUBGROUP_NAME () {  2 }
 sub I_NAME             () {  3 }
@@ -44,11 +45,11 @@
 
 sub new {
   unless (@_ == 8) {
-    confess "$0: Orca::ImageFile::new passed incorrect number of arguments.\n";
+    confess "$0: Orca::ImageFile::new $INCORRECT_NUMBER_OF_ARGS";
   }
 
   my ($class,
-      $group_name,
+      $group_index,
       $subgroup_name,
       $name,
       $no_subgroup_name,
@@ -64,24 +65,27 @@
   }
 
   # Remove any special characters from the unique name and do some
-  # replacements.
-  $name = &::escape_name($name);
+  # replacements.  Leave space at the end of the name to append a
+  # string of the form '-daily.png' and optionally '.meta' if the
+  # configuration file specifies that images should be expired.
+  my $max_length = $MAX_PLOT_TYPE_LENGTH + 2 + length($IMAGE_SUFFIX);
+  if ($config_global{expire_images}) {
+  $max_length += 5;
+  }
+  $name = name_to_fsname($name, $max_length);
 
   # Create the paths to the html directory and subdirectories.
-  my $html_dir     = $config_options{html_dir};
-  if ($config_groups{$group_name}{sub_dir}) {
-    $html_dir .= "/$subgroup_name";
-    # Create the html_dir directories if necessary.
-    unless (-d $html_dir) {
-      warn "$0: making directory `$html_dir'.\n";
-      recursive_mkdir($html_dir);
-    }
+  my $html_dir     = "$config_global{html_dir}/$subgroup_name";
+  # Create the html_dir directories if necessary.
+  unless (-d $html_dir) {
+    warn "$0: making directory `$html_dir'.\n";
+    recursive_mkdir($html_dir);
   }
   my $image_basename = "$html_dir/$name";
 
   # Create the new object.
   my $self = bless [
-    $group_name,
+    $group_index,
     $subgroup_name,
     $no_subgroup_name,
     $name,
@@ -95,7 +99,7 @@
   ], $class;
 
   my $plot_end_time = $self->plot_end_time;
-  my $interval      = int($config_groups{$group_name}{interval}+0.5);
+  my $interval      = int($config_groups[$group_index]{interval}+0.5);
   for (my $i=0; $i<@IMAGE_PLOT_TYPES; ++$i) {
     # Load the data that helps this class determine if a particular
     # image file, such as the daily image, is current or needs to be
@@ -120,7 +124,7 @@
     # Generate the unique plot title cotaining the period title for this
     # plot.
     $self->[I_PLOT_LEGEND_BASE+$i] =
-      &::Capatialize($plot_type) .
+      &::capatialize($plot_type) .
       ' ' .
       ::replace_subgroup_name($plot_ref->{title}, $subgroup_name);
   }
@@ -171,10 +175,11 @@
   my @legends;
   my $max_legend_length = 0;
   for (my $i=0; $i<$data_sources; ++$i) {
-    my $legend         = ::replace_subgroup_name($plot_ref->{legend}[$i], $subgroup_name);
+    my $legend         = ::replace_subgroup_name($plot_ref->{legend}[$i],
+                                                 $subgroup_name);
     my $line_type      = $plot_ref->{line_type}[$i];
     my $color          = $plot_ref->{color}[$i];
-    push(@options, "$line_type:average$i#$color:$legend");
+    push(@options,       "$line_type:average$i#$color:$legend");
     $legend            =~ s:%:\200:g;
     $legend            =~ s:\200:%%:g;
     my $legend_length  = length($legend);
@@ -188,12 +193,13 @@
   # Generate the legends containing the current, average, minimum, and
   # maximum values on the plot.
   for (my $i=0; $i<$data_sources; ++$i) {
-    my $legend = $legends[$i];
-    $legend   .= ' ' x ($max_legend_length - length($legend));
-    push(@options, "GPRINT:average$i:LAST:$legend  Current\\: %9.3lf %S",
-                   "GPRINT:average$i:AVERAGE:Average\\: %9.3lf %S",
-                   "GPRINT:average$i:MIN:Min\\: %9.3lf %S",
-                   "GPRINT:average$i:MAX:Max\\: %9.3lf %S\\l"
+    my $legend          = $legends[$i];
+    $legend            .= ' ' x ($max_legend_length - length($legend));
+    my $summary_format  = $plot_ref->{summary_format}[$i];
+    push(@options, "GPRINT:average$i:LAST:$legend  Current\\: $summary_format",
+                   "GPRINT:average$i:AVERAGE:Average\\: $summary_format",
+                   "GPRINT:average$i:MIN:Min\\: $summary_format",
+                   "GPRINT:average$i:MAX:Max\\: $summary_format\\l"
         );
   }
 
@@ -233,8 +239,8 @@
   $_[0]->[I_NAME];
 }
 
-sub group_name {
-  $_[0]->[I_GROUP_NAME];
+sub group_index {
+  $_[0]->[I_GROUP_INDEX];
 }
 
 sub subgroup_name {
@@ -283,7 +289,7 @@
   my ($self, $i) = @_;
 
   my $plot_type       = $IMAGE_PLOT_TYPES[$i];
-  my $image_days_back = $IMAGE_DAYS_BACK[$i];
+  my $image_time_span = $IMAGE_TIME_SPAN[$i];
 
   # Get the time stamp of the last data point entered into the RRDs
   # that are used to generate this image.
@@ -311,7 +317,7 @@
       $image_filename,
       @{$self->[I_GRAPH_OPTIONS]},
       '-t', $self->[I_PLOT_LEGEND_BASE+$i],
-      '-s', ($plot_end_time-$image_days_back*DAY_SECONDS),
+      '-s', ($plot_end_time-$image_time_span),
       '-e', $plot_end_time,
       '-w', $plot_ref->{plot_width},
       '-h', $plot_ref->{plot_height},
@@ -329,9 +335,8 @@
 
     # Expire the image at the correct time using a META file if
     # requested.
-    if ($config_options{expire_images}) {
+    if ($config_global{expire_images}) {
       if (open(META, "> $image_filename.meta")) {
-        my $time = 
         print META "Expires: ",
                    _expire_string($plot_end_time + $plot_age + 30),
                    "\n";
@@ -349,7 +354,7 @@
 sub _expire_string {
   my @gmtime  = gmtime($_[0]);
   my ($wday)  = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat')[$gmtime[6]];
-  my ($month) = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep', 
+  my ($month) = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep',
                  'Oct','Nov','Dec')[$gmtime[4]];
   my ($mday, $year, $hour, $min, $sec) = @gmtime[3,5,2,1,0];
   if ($mday<10) {$mday = "0$mday";}

Modified: trunk/orca/lib/download.cfg
==============================================================================
--- trunk/orca/lib/download.cfg	(original)
+++ trunk/orca/lib/download.cfg	Sat Jul 13 21:25:46 2002
@@ -6,25 +6,21 @@
 files 24hour_mean {
 watch_files		24hour_mean
 column_description	date 24hour_mean
-date_format		%m/%d/%y
 }
 
 files 24hour_sd {
 watch_files		24hour_sd
 column_description	date 24hour_sd
-date_format		%m/%d/%y
 }
 
 files core_mean {
 watch_files		core_mean
 column_description	date core_mean
-date_format		%m/%d/%y
 }
 
 files core_sd {
 watch_files		core_sd
 column_description	date core_sd
-date_format		%m/%d/%y
 }
 
 

Modified: trunk/orca/lib/time_gets.cfg
==============================================================================
--- trunk/orca/lib/time_gets.cfg	(original)
+++ trunk/orca/lib/time_gets.cfg	Sat Jul 13 21:25:47 2002
@@ -26,7 +26,6 @@
 find_files		/home/bzajac/time_gets/(.*)/data.\d{8}
 column_description	first_line
 date_source		column_name timestamp
-date_format		%s
 interval		300
 reopen			1
 }

Modified: trunk/orca/FAQ
==============================================================================
--- trunk/orca/FAQ	(original)
+++ trunk/orca/FAQ	Sat Jul 13 21:25:47 2002
@@ -1,7 +1,402 @@
-Orcallator:
- 1) Why are my Ethernet bits/second measurements all 0?
+This is a FAQ (Frequently Asked Questions) for Orca and the tools that
+gather data for it.
 
-    On 2.5.1 or older Solaris operating system releases, the kernel does
-    not measure the bits/second going through a particular device.  I
-    believe some later kernel and device driver patches may fix this,
-    but Solaris 2.6 and greater definitely does measure this.
+Please email submissions to the FAQ to orca-users at yahoogroups.com.
+
+Version: 1.06 May 10, 2001
+
+General
+-------
+
+  1.1) What is the m, k, u, or some other character following the
+       numbers in the Y axis scale?
+  1.2) Why is my Y axis scale have such large numbers?
+  1.3) Why are there random characters at the end of my HTML and GIF
+       or PNG images names, i.e.
+       o_host3_disk_runp_c0t6d0...disk_runp_c-4QyP2ziXlrwXj8eG_n_A.html?
+
+Warning Messages
+----------------
+
+  2.1) Number of columns in line '1,2,3.....' of
+      ../orcallator/.../percol-2000-09-26 does not match column
+      description.
+  2.2) Warning: file `../orcallator/.../temp-percol-2001-02-22' was
+       current and now is not.
+
+Solaris/Orcallator.se
+---------------------
+
+  3.1) What do I do about the error "/opt/RICHPse/bin/se: Unsupported
+       platform: sparcv9 SunOS 5.8"?
+  3.2) Why does orcallator.se die, in particular when I log out of the
+       system that I started it on?
+  3.3) Why is the page scan rate is always zero even though sar says
+       it is not?
+  3.4) Why are all the NFS server statistics zero?
+  3.5) Why are my Ethernet bits/second measurements all zero?
+  3.6) Why do I get the error "Fatal: member: txunderruns vanished!:
+       Near line 201"?
+  3.7) Why do I get the error "Fatal: member: txunderruns0 vanished!:
+       Near line 255"?
+  3.8) Why do I get the error "Fatal: member: framming vanished!: Near
+       line 160"?
+  3.9) Why do I get the error "Fatal: member: drop vanished!: Near
+       line 285"?
+ 3.10) Why do I get the error "Fatal: member: XXXXX vanished!: Near
+       line YYY"?
+ 3.11) Why don't I get plots for my Veritas filesystems?
+ 3.12) Why don't I get plots for my RSM filesystems?
+ 3.13) Why don't I get any Interface Bits Per Second data for my qe
+       board?
+ 3.14) Orcallator.se core dumps.
+
+General
+-------
+
+  1.1) What is the m, k, u, or some other character following the
+       numbers in the Y axis scale?
+
+       This is SI magnitude symbol to scale the number by.  Here is a
+       table of symbols and scaling factors.
+
+         a  10e-18 Ato
+         f  10e-15 Femto
+         p  10e-12 Pico
+         n  10e-9  Nano
+         u  10e-6  Micro
+         m  10e-3  Milli
+         k  10e3   Kilo
+         M  10e6   Mega
+         G  10e9   Giga
+         T  10e12  Terra
+         P  10e15  Peta
+         E  10e18  Exa
+
+       So if you see "250 m" in the Y axis, this means 0.25.
+
+       The page
+
+         http://www.physlink.com/reference_dprefixes.cfm
+
+       is also a good reference for this information.
+
+  1.2) Why is my Y axis scale have such large numbers?
+
+       See question 1) above.  Most likely there is a scaling letter
+       after your number that means the true value is several orders
+       of magnitude smaller than you think it is.
+
+  1.3) Why are there random characters at the end of my HTML and GIF
+       or PNG images names, i.e.
+       o_host3_disk_runp_c0t6d0...disk_runp_c-4QyP2ziXlrwXj8eG_n_A.html?
+
+       The way Orca generates HTML and image filenames uses all of the
+       input data sources.  With plots that contain a large amount of
+       different data, the filename can exceed the maximum filename
+       length for the operating system and Orca will not be able to
+       create the file.
+
+       The solution is to limit the filename length to less than 255
+       characters.  This could be performed by simply trimming the
+       filename down to less than 255 characters, but then the
+       filename may not be unique and two distinct HTML files and/or
+       images may end up being written to the same file.  The solution
+       used by Orca is to calculate the MD5 hash of the full length
+       filename, trim the filename down and insert the MD5 into the
+       short filename, which will guarantee uniqueness.
+
+Warning Messages
+----------------
+
+  2.1) Number of columns in line '1,2,3.....' of
+      ../orcallator/...../percol-2000-09-26 does not match column
+      description.
+
+      When Orca sees a line in an input data file that does not have
+      the same number of columns as defined at the top of the file,
+      then Orca will complain and ignore the line.
+
+  2.2) Warning: file `../orcallator/.../temp-percol-2001-02-22' was
+       current and now is not.
+
+       First, Orca considers a file to be current if the file's last
+       modified time is within `late_interval' seconds of the current
+       time.  In other words, Orca checks if a process is modifying
+       the file to keep it current.  The `late_interval' value is
+       determined by the configuration file or set to the `interval'
+       value if the configuration file does not set `late_interval'.
+
+       Orca stat()s the file when it first looks for files using the
+       `find_files' and determines that the file is current.  Any time
+       after that Orca reads the file, it stat()s the file again and
+       determines if it is current.  If there was a previous stat()
+       and the file was current followed by another stat() and the
+       file is not current, then the message is printed.
+
+       The appearance of this message means that the process that has
+       been updating the file has stopped updating it and this may be
+       worth looking into.
+
+       This message is also seen when the data gathering program,
+       e.g. orcallator.se, opens a new log file at the end of a day
+       and the old log file is no longer updated.  Orca tries to
+       manage this situation when a file is no longer updated at the
+       end of a day.
+
+       If the actual measurement interval is not consistent with
+       Orca's configuration file "interval" 300 seconds, then Orca's
+       "interval" should be modified to match the actual measurement
+       interval.  If you need to do this, then delete the RRD files
+       because they will keep the old "interval" and the input data
+       will need to be reloaded into new RRD files.
+
+       Increasing the "late_interval" may also remove this error.
+
+Solaris/Orcallator.se
+---------------------
+
+  3.1) What do I do about the error "/opt/RICHPse/bin/se: Unsupported
+       platform: sparcv9 SunOS 5.8"?
+
+       There are two solutions.  SE 3.2 is now available and you can
+       upgrade to this version.  It is available at:
+
+         http://www.setoolkit.com/
+
+       If you are using an SE version less than 3.2, then do this:
+
+         cd /opt/RICHPse/bin
+         ln se.sparc.5.7   se.sparc.5.8
+         ln se.sparcv9.5.7 se.sparcv9.5.8
+
+  3.2) Why does my background orcallator.se process die, in particular
+       when I log out of the system that I started it on?
+
+       This sounds like orcallator.se is started under the Bourne
+       shell, which kills background processes unless the process is
+       started with nohup:
+
+         nohup se orcallator.se &
+
+  3.3) Why is the page scan rate is always zero even though sar says
+       it is not?
+
+       It has been observed that on Solaris 2.5.1 the page scan rate
+       is always zero.  This occurs with orcallator.se version 1.23 or
+       older.  The problem is that on older versions of SE the
+       p_vmstat.scan variable is an integer and orcallator.se was
+       assuming a double.  The fix is to upgrade to orcallator.se 1.24
+       or newer.
+
+  3.4) Why are all the NFS server statistics zero?
+
+       On Solaris 2.6 there is a bug in the SE toolkit that prevents
+       orcallator.se from getting the NFS server statistics.  To fix
+       this, edit your RICHPse/include/kstat.se file and change #ifdef
+       to #if near the top of the file where it says
+
+         #ifdef MINOR_VERSION >= 70
+         # define rfs_counter_t uint64_t
+         #else
+
+       to
+
+         #if MINOR_VERSION >= 70
+         # define rfs_counter_t uint64_t
+         #else
+
+  3.5) Why are my Ethernet bits/second measurements all zero?
+
+       On 2.5.1 or older Solaris operating system releases, the kernel
+       does not measure the bits/second going through a particular
+       device.  I believe some later kernel and device driver patches
+       may fix this, but Solaris 2.6 and greater definitely does
+       measure this.
+
+  3.6) Why do I get the error "Fatal: member: txunderruns vanished!:
+       Near line 201"?
+
+       This problem occurs with SE 2.5.0.2 and FDDI 5.0
+       interfaces.  There are three possible fixes:
+         1) Upgrade to SE 3.0.
+         2) Visit the SE 2.5.0.2 download page and get the FDDI patch.
+         3) Add the latest patch to FDDI which should reinstate the
+            metric that went missing.
+
+  3.7) Why do I get the error "Fatal: member: txunderruns0 vanished!:
+       Near line 255"?
+
+       This problem occurs with Solaris 2.5 and hme interfaces.  There
+       are three possible fixes:
+
+         1) Upgrade to a later Solaris release.
+         2) Get the hme patch for Solaris 2.5.
+         3) As a temporary work-around, change the member "defer" to
+            "missing1" in the ks_hme_network structure in
+            /opt/RICHPse/include/kstat.se like this:
+
+            #ifdef MINOR_VERSION >= 51
+            ulong defer;
+            #else
+            ulong missing1;
+            #endif
+
+            The next build of SE 3.0 will figure this out
+            automatically.
+
+  3.8) Why do I get the error "Fatal: member: framming vanished!: Near
+       line 160"?
+
+       This problem occurs with Solaris 2.5.1 and le interfaces.  The
+       le patch for Solaris 2.5.1 corrects the spelling from framming
+       to framing.  SE 3.0 tries to detect this patch, but if you
+       don't have the patch directory in /var/sadm/patch it can't tell
+       that the patch is installed.  There are three fixes.
+
+         1) Upgrade to Solaris 2.6.
+         2) Reinstall the le patch for Solaris 2.5.1.
+         3) Create the directory /var/sadm/patch/103903-03 by hand.
+         4) As a temporary work-around, run scripts using se
+            -DLE_PATCH script.se to force the update or edit
+            start_orcallator.se and enable the appropriate SE_PATCHES
+            variable.
+
+  3.9) Why do I get the error "Fatal: member: drop vanished!: Near
+       line 285"?
+
+       This has been observed on Solaris 2.6 using SE version 3.0.
+       Upgrade to the latest version of SE.
+
+ 3.10) Why do I get the error "Fatal: member: XXXXX vanished!: Near
+       line YYY"?
+
+       This happens when Sun changes some of the kernel names for
+       particular variables that the SE package is expecting to find.
+       For example, one error was that
+
+       SE has some conditional compile flags that tell it to look for
+       the new name.  Try adding these to the command line options for
+       SE or editing start_orcallator.sh to enable some of the
+       defines.
+
+         1) -DLE_PATCH=1
+         2) -DHME_PATCH=1
+         3) -DHME_PATCH_IFSPEED=1
+         4) -DMULTICAST_PATCH=1
+         5) -DROBUST_LISTENQ=1
+
+       If a particular define does not fix the problem, then don't run
+       SE with it.
+
+ 3.11) Why don't I get plots for my Veritas filesystems?
+
+       Version 1.13 or later of orcallator.se should be able to
+       generate filesystem statistics for Veritas filesystems.  The
+       first thing to try is to upgrade to the latest SE and
+       orcallator.se release.
+
+ 3.12) Why don't I get plots for my RSM filesystems?
+
+       I don't think orcallator.se records data from RSM disks.
+
+       However, to make sure, can you look through the first line of
+       the output orcallator files and see if the RSM filesystems
+       are listed there?  Look for the disk_runp_ string.  If you see
+       the filesystems there, then the Orca configuration file needs
+       to be updated to plot this data.  In this case, email me the
+       names of the filesystems as listed in the output file and the
+       Orca configuration file can be updated to plot the data.
+
+       Otherwise, orcallator.se or the underlying SE header files will
+       need to be modified to find RSM filesystems.  Since I don't
+       have access to a system with RSM on it, this is something
+       that somebody else will need to take on.  Hint, hint...
+
+ 3.13) Why don't I get any Interface Bits Per Second data for my qe
+       board?
+
+       Most likely you are either running Solaris 7 or older or
+       Solaris 8 with SE version 3.1 or older.  You must run Solaris 8
+       to get qe bits per second data.  Apply the following patches to
+       include/kstat.se and include/netif.se:
+
+         *** kstat.se.orig       Fri Feb  9 01:44:14 2001
+         -- kstat.se    Fri Feb  9 14:31:46 2001
+         ***************
+         *** 646,651 ****
+         --- 646,661 ----
+               ulong_t no_tbufs;
+               ulong_t no_rbufs;
+               ulong_t rx_late_collisions;
+         + #if MINOR_VERSION >= 70
+         +     ulong_t  rbytes;
+         +     ulong_t  obytes;
+         +     ulong_t  multircv;
+         +     ulong_t  multixmt;
+         +     ulong_t  brdcstrcv;
+         +     ulong_t  brdcstxmt;
+         +     ulong_t  norcvbuf;
+         +     ulong_t  noxmtbuf;
+         + #endif
+
+           };
+
+         *** netif.se.orig       Fri Feb  9 01:45:06 2001
+         --- netif.se    Fri Feb  9 14:31:10 2001
+         ***************
+         *** 229,236 ****
+         --- 229,241 ----
+                 nocanput       = if_qe.nocanput;
+                 defer          = if_qe.excess_defer;
+                 nocarrier      = if_qe.nocarrier;
+         + #if MINOR_VERSION >= 70
+         +       ooctets        = if_qe.obytes + if_qe.multixmt + if_qe.brdcstxmt;
+         +       ioctets        = if_qe.rbytes + if_qe.multircv + if_qe.brdcstrcv;
+         + #else
+                 ooctets        = 0;
+                 ioctets        = 0;
+         + #endif
+                 break;
+               case NETIF_BF:
+                 kstat$bf.number$ = number$ - (if_max[NETIF_QE] + 1);
+
+ 3.14) Orcallator.se core dumps.
+
+       Some of the SE include files can cause core dumps if there are
+       oddities on the system.  Apply the following patches:
+
+         --- diskinfo.se.orig       Fri Jan 12 11:20:09 2001
+         +++ diskinfo.se Tue Feb 27 19:37:28 2001
+         @@ -197,7 +197,12 @@
+              points_at[n] = '\0';
+
+              // chop off the :a at the end
+         -    strcpy(strrchr(points_at, ':'), "");
+         +    while (--n >= 0) {
+         +      if (points_at[n] == ':') {
+         +        points_at[n] = '\0';
+         +        break;
+         +      }
+         +    }
+
+              // hack off ../../devices from the start
+              sscanf(points_at, "../../devices%s", &points_at);
+
+
+         --- mnt_class.se.orig   Fri Jan 12 11:20:09 2001
+         +++ mnt_class.se        Tue Feb 27 19:53:34 2001
+         @@ -96,7 +96,12 @@
+                number$ = -1;
+                return;
+              }
+         -    strcpy(strchr(buf, '\n'), "");
+         +    for (i=0; i<sizeof(buf); ++i) {
+         +      if (buf[i] == '\n') {
+         +        buf[i] = '\0';
+         +        break;
+         +      }
+         +    }
+              i = 0;
+              for(p=strtok(buf, "\t"); p != nil; p=strtok(nil, "\t")) {
+                switch(i) {

Modified: trunk/orca/CHANGES
==============================================================================
--- trunk/orca/CHANGES	(original)
+++ trunk/orca/CHANGES	Sat Jul 13 21:25:47 2002
@@ -1,478 +1,891 @@
+Thu May 10 17:24:54 PDT 2001
+
+	* Release Orca version 0.27b1.
+
+Thu May 10 16:05:29 PDT 2001
+
+	* CHANGES: Make have proper whitespaces.
+	* NEWS: Ditto.
+	* FAQ: Ditto.
+	* src/orca.pl.in: Spell check.
+	* orcallator/orcallator.se: Upgrade to orcallator.se 1.28b3.
+	  Recoded measure_disk() to access the RAWDISK interface to
+	  sys_kstat device information to allow the activity on Sun's
+	  A1000 and Clariion Raid controller drives to be seen.
+	  Apparently the pseudo drivers do not update the kstat
+	  interface.  It is also inverts the fix provided by version
+	  1.23 to avoid over-counting md devices.  By suppressing
+	  stats from slices and metadevices and instead reporting on
+	  full devices such as c0t0d0 or sd0.  Note: This may have
+	  introduced an interaction with the live_rules.se class
+	  monitoring of drive performance.  Prevent floppy disks and
+	  tape drives from RAWDISK.  Added wio% to measure wait time
+	  since the idle calculation is wrong without this.  Prevent
+	  filesystems mounted under /snapshots from being seen.  Patch
+	  contributed by Alan LeGrand <alegrand at wallace.com>.
+	* INSTALL: Modify any broken URLs to installation instructions
+	  or to downloadable files.
+	* README: Change the email address blair at akamai.com to
+	  blair at gps.caltech.edu.
+	* lib/Orca/HTMLFile.pm: Ditto.
+	* src/orca.pl.in: Ditto.
+	* lib/homesteaders.cfg: Ditto.
+	* orcallator/orcallator.se: Ditto.
+
+Thu Mar 29 15:27:02 PST 2001
+
+	* src/orca.pl.in: Move &email_message from src/orca.pl.in to
+	  lib/Orca/Utils.pm since it is an utility function.
+	* lib/Orca/Utils.pm: Ditto.
+
+Thu Mar 29 15:18:20 PST 2001
+
+	* src/orca.pl.in: Add clearer instructions on how to disable
+	  Orca from sending email to the warn_email addresses.
+
+Wed Mar 28 22:28:41 PST 2001
+
+	* lib/Orca/ImageFile.pm: Remove an unnecessary assignment to a
+	  variable from the result of a print statement.
+
+Wed Mar 28 21:34:43 PST 2001
+
+	* src/orca.pl.in: Rename the make_*_plot parameters to
+	  generate_*_plot.
+	* lib/Orca/Config.pm: Ditto.
+	* orcallator/orcallator.cfg.in: Ditto.
+	* NEWS: Ditto.
+
+Tue Mar 27 15:19:11 PST 2001
+
+	* orcallator/orcallator_column.pl: Now handle when input file
+	  column names change or the number of columns increase or
+	  decrease.
+
+Tue Mar 27 11:26:39 PST 2001
+
+	* orcallator/orcallator.cfg.in: Update orcallator.cfg.in to
+	  fix a bug in plotting the CPU usage plots where the idle%
+	  time was calculated by subtracting the user percent time
+	  usr% and the system percent time sys% from 100%.  This did
+	  not take into account the wait on IO time wio% that the
+	  system measures and hence the idle% was overestimated.  Now
+	  plot the correct idle% and the wio%.
+
+Tue Mar 27 11:24:36 PST 2001
+
+	* orcallator/orcallator.se: Upgrade to orcallator.se 1.27.
+	  Print the portion of time running in idle mode with some
+	  process waiting for block I/O as wio% and otherwise
+	  completely idle time as idle%.
+
+Thu Mar 15 15:31:29 PST 2001
+
+	* Include and require Digest::MD5 2.13.
+
+Wed Mar 14 20:29:58 PST 2001
+
+	* Include and require Storable 1.0.11.
+
+Fri Mar  2 16:35:20 PST 2001
+
+	* Now the same data expression can be used in plots with
+	  different RRD data types (GAUGE, COUNTER, etc.).
+
+Wed Feb 28 10:30:19 PST 2001
+
+	* Remove the "sub_dir" configuration file parameter and now
+	  always create sub directories for RRD, image and HTML
+	  files.  This removes the problem when a simple Orca
+	  configuration file was used and Orca did not create
+	  subdirectories and then additional groups where added to the
+	  configuration file Orca would begin to use subdirectories
+	  and the existing RRD, image and HTML files would be in the
+	  wrong location.  In this case, Orca would reload all of the
+	  input data.
+	* The created HTML files now all include the group name to
+	  avoid collisions between the same subgroup name in different
+	  groups.
+	* The Orca generated RRD filenames had the subgroup name in it
+	  which is the same as the directory it is placed in.  Remove
+	  the subgroup name from the filename to save memory.  Also,
+	  place the group name in the directory's name to prevent
+	  collisons between name named subgroups in different groups.
+
+Tue Feb 27 12:15:15 PST 2001
+
+	* src/orca.pl.in: Fix a bug where Orca's documentation states
+	  that the configuration file can specify different data_types
+	  for each data in a plot but the code did not.  Make the
+	  modifications to support this feature.
+
+Mon Feb 26 22:16:17 PST 2001
+
+	* Add a new command line option named -no-images which
+	  suppresses image generation.  Remove the command line option
+	  -r which told Orca to only update the RRD files and not
+	  generate HTML and image files.  To replace -r functionality,
+	  use both -no-images and -no-html command line options.
+	* Add a new command line option -daemon that puts Orca in the
+	  background or daemonizes it.  It is recommended that when
+	  this command line option is used that -logfile is used.
+	  Patch supplied by Bruce Johnson
+	  <Bruce.Johnson at PictureVision.com>.
+
+Mon Feb 26 22:19:56 PST 2001
+
+	* Add a new command line option -logfile that specifies a
+	  filename that STDOUT and STDERR are redirected to so that
+	  all messages, warnings and errors are printed to the file.
+	  Now when a SIGPIPE is caught, messages will continue to be
+	  printed unless -logfile was not given to Orca.  Patch
+	  supplied by Bruce Johnson <Bruce.Johnson at PictureVision.com>.
+
+Mon Feb 26 13:28:06 PST 2001
+
+	* Include and require Storable 1.0.10.
+
+Sun Feb 25 19:34:32 PST 2001
+
+	* lib/Orca/Config.pm: When loading a configuration file, now
+	  do a complete check of it for errors before quitting,
+	  instead of quitting after a single error.
+
+Sat Feb 24 13:28:45 PST 2001
+
+	* Fix a bug where Orca's documentation states that the
+	  configuration file can specify different data_min and
+	  data_max for each data in a plot but the code did not.  Make
+	  the modifications to support this feature.
+
+Fri Feb 23 22:32:43 PST 2001
+
+	* orcallator/orcallator.cfg.in: Greatly simplify
+	  orcallator.cfg.in to use Orca's regular expression matching
+	  features to make the Interface Bits Per Second plots instead
+	  of listing each possible interface.
+	* Include and require RRDtool 1.0.33.
+
+Mon Feb 19 19:50:19 PST 2001
+
+	* Include and require RRDtool 1.0.30.
+
+Sat Feb 10 13:14:49 PST 2001
+
+	* orcallator/orcallator.cfg.in: Add input and output bits per
+	  second plots to orcallator.cfg.in for ge0, qe0, qe1, qe2,
+	  qe3 and vge0 interfaces.
+
+Thu Feb  8 15:55:29 PST 2001
+
+	* By default, now create an hourly plot that shows the last
+	  1.5 hours of data.  Add a global "make_hourly_plot"
+	  configuration file parameter that turns this plot
+	  off.  Hourly plot creation is disabled in orcallator.cfg.in
+	  since orcallator.se by default measures the system every 5
+	  minutes and the plots look blocky.
+
+Wed Feb  7 16:43:26 PST 2001
+
+	* The previous fix for the
+	    `Use on uninitialized value in array element at (eval X)
+	    line 1, <DATA> line Y'
+	  warning did not work on Perl 5.004_05.  Modify the fix so
+	  that it will work on this older version of Perl.
+
+Mon Feb  5 17:27:02 PST 2001
+
+	* orcallator/orcallator.se: Update to orcallator.se 1.26.
+	  Make sure to check the return from stat() on the web server
+	  access log in case the file is missing.  Use fstat() instead
+	  of stat() when a file descriptor is available.
+
+Mon Feb  5 14:48:32 PST 2001
+
+	* src/orca.pl.in: If Orca's output was being piped to a
+	  process, such as less, and the process was killed or exited
+	  before Orca did, then Orca would not remove the lock
+	  directory.  Orca now catches SIGPIPEs and exits cleanly.  If
+	  Orca catches any signal other than SIGPIPE, it will print to
+	  STDOUT and STDERR some final messages, otherwise it will not
+	  print anything, since STDOUT and STDERR may have been
+	  attached to a process that exited.
+
+Mon Feb  5 11:59:48 PST 2001
+
+	* src/orca.pl.in: Fix the warning message in src/orca.pl.in
+	    `Use on uninitialized value in array element at (eval X)
+	    line 1, <DATA> line Y'
+	  when Orca was run with Perl 5.6.0.  The problem was that the
+	  filename_compare subroutine was eval'ed in Orca::Config
+	  while the sort was being performed in the main package and
+	  the $a and $b that the compare subroutine expected were not
+	  being set.  This problem is probably responsible for
+	  problems where there are missing data from the plots.  Since
+	  the filename sort tells Orca the order in which to load data
+	  into the RRD files and the sort will have newer data files
+	  listed before older data files, once newer data is entered
+	  into an RRD file you cannot add older data resulting in
+	  missing data in the output plots.  The solution to this is
+	  to remove the RRD files and rerun Orca with all of the input
+	  data files.
+
+Sat Feb  3 12:23:33 PST 2001
+
+	* lib/Orca/Config.pm: Add a new configuration file option
+	  named "require" that allows the configuration file to
+	  specify the minimum required version of Orca.
+
+Wed Jan 31 15:40:05 PST 2001
+
+	* Add a new configuration file option for plots named
+	  summary_format which specifies the format for the summary
+	  values as passed to the RRDtool GPRINT function.  The same
+	  format is used for each number within a single summary line,
+	  but you can specify multiple summary_format options if there
+	  are multiple plots on the graph.  The default value, which
+	  has not changed from previous Orca versions, is '%9.3lf
+	  %S'.  Patch from Alex Howansky <alex at wankwood.com>.
+
+	* Add a new command line option -no-html to instruct Orca to
+	  skip generating HTML files.  Patch from Alex Howansky
+	  <alex at wankwood.com>.
+
+Wed Jan 31 14:08:24 PST 2001
+
+	* Update all of the www.egroups.com URLs and email addresses
+	  to reflect that Egroups was purchased by Yahoo!.
+
+Mon Nov  6 16:38:58 PST 2000
+
+	* Include the orcaservices package in the contrib directory
+	  which was written by Carlos Canau <Carlos.Canau at KPNQwest.pt>
+	  and documented by Jose Carlos <jcp at KPNQwest.pt>.  This
+	  package allows monitoring of many different types of Unix
+	  services, such as DNS, SMTP, POP, etc.
+
+Thu Nov  2 11:20:15 PST 2000
+
+	* Include and require Digest::MD5 2.12.
+
+Wed Nov  1 16:06:13 PST 2000
+
+	* Add a contrib directory for contributed tools.  Add the
+	  first tool which is rotates Orca's plots so that daily plots
+	  can be archived.  This script is named rotate_orca_graphs.
+
+Thu Oct 26 13:37:38 PDT 2000
+
+	* Add new global configuration file parameters,
+	  "make_daily_plot", "make_weekly_plot", "make_monthly_plot",
+	  "make_quarterly_plot", and "make_yearly_plot", that when
+	  given an argument of 0, do not create the specified plot.
+
+Mon Oct 23 16:02:45 PDT 2000
+
+	* Include and require RRDtool 1.0.28.
+
+Wed Sep 13 13:28:29 PDT 2000
+
+	* Include and require RRDtool 1.0.27.
+
+Sun Sep 10 12:01:14 PDT 2000
+
+	* Include and require RRDtool 1.0.26.
+
+Sun Aug 27 21:58:28 PDT 2000
+
+	* Include and require RRDtool 1.0.25.
+
+	* Include Digest::MD5 2.11.
+
+Mon Jul  3 14:32:57 PDT 2000
+
+	* Include and require RRDtool 1.0.24.
+
+Mon Jul  3 11:16:04 PDT 2000
+
+	* Change all mailing list and HTML references from onelist.com
+	  to egroups.com.
+
+Thu Jun  1 12:38:18 PDT 2000
+
+	* In start_orcallator.se start se with nohup.
+
+Sat May  6 13:47:05 PDT 2000
+
+	* Include and require RRDtool 1.0.21.
+
+Mon Apr 17 10:43:14 PDT 2000
+
+	* Remove the date_format configuration option, as it was never
+	  supported.
+
+	* To support converting arbitrary strings in the input source
+	  data files that somehow represent time into an Unix epoch
+	  time usable by Orca, introduce a new group configuration
+	  option named date_parse, which is an arbitrary Perl
+	  subroutine that is given two arguments, the first being the
+	  name of the file where the data is loaded and the second the
+	  string from the `date_source' column that contains some time
+	  information.  The subroutine should return the Unix epoch
+	  time.  If this option is not specified, then Orca assumes
+	  that the string holds the Unix epoch time.
+
+	  This Perl subroutine is only used if the file's date source
+	  is not specified to be the file's last modified time as
+	  indicated to Orca by use of the B<date_source> file_mtime
+	  configuration file option.
+
+Mon Apr 17 10:43:13 PDT 2000
+
+	* Replace the small color scheme with a longer list designed
+	  by Guy Dallaire <gdallair-nospam at criq.qc.ca>.
+
+Thu Apr 13 16:09:07 PDT 2000
+
+	* Include and require RRDtool 1.0.16.
+
+Mon Apr  3 16:40:18 PDT 2000
+
+	* Include and require Storable 0.6.11.
+
+Sun Apr  2 10:53:31 PDT 2000
+
+	* Include and require RRDtool 1.0.14.
+
+Thu Mar 30 18:20:34 PST 2000
+
+	* Update to orcallator.se 1.25.  Fix a typo where nil was
+	  misspelled as nik.
+
+Thu Mar 30 13:37:10 PST 2000
+
+	* Allow the "late_interval" configuration parameter to appear
+	  in a configuration file group.  If it does not appear in a
+	  group listing, then use the global "late_interval" value.
+
+Wed Mar 29 21:11:38 PST 2000
+
+	* Include and require Storable 0.6.10 which fixes a compile
+	  problem of against certain Perl's.
+
+Sat Mar 25 12:26:52 PST 2000
+
+	* Upgrade to orcallator.se 1.24.  When orcallator.se was
+	  running on a system with an older version of SE the
+	  p_vmstat.scan variable is an integer and the sprintf to
+	  %8.3f fails, resulting in a perceived scan rate of 0 pages
+	  per second.  Now always add 0.0 to p_vmstat.scan to get a
+	  double.
+
+Sat Mar 11 11:16:49 PST 2000
+
+	* Change the version string from 0.26beta1 to 0.27.
+
+Fri Mar 10 19:00:00 PST 2000
+
+	* Release version 0.26 of Orca.
+
 Thu Mar  9 12:23:24 PST 2000
 
-	Remove from the INSTALL file the instructions to increase the
-	file descriptor limit to 256.  This should no longer be
-	necessary with the improvements to the code.
+	* Remove from the INSTALL file the instructions to increase
+	  the file descriptor limit to 256.  This should no longer be
+	  necessary with the improvements to the code.
 
 Thu Mar  9 12:20:39 PST 2000
 
-	Reduce the number of open files for the open file descriptor
-	cache from roughly 200 to 100.  Change the code so that if a
-	open of a file or pipe fails, then close two open file
-	descriptors and try again.  It used to be that an attempt
-	would be made if only a pipe failed.
+	* Reduce the number of open files for the open file descriptor
+	  cache from roughly 200 to 100.  Change the code so that if a
+	  open of a file or pipe fails, then close two open file
+	  descriptors and try again.  It used to be that an attempt
+	  would be made if only a pipe failed.
 
 Wed Mar  8 12:02:07 PST 2000
 
-	Due to some changes at onelist.com, the name of this mailing
-	must change.  The -help at the end of orca-help is being
-	reserved for the mailing list named "orca".  As such, I'm
-	renaming this list to orca-users at onelist.com.  All references
-	to the old name in the package were similarly changed.
+	* Due to some changes at onelist.com, the name of this mailing
+	  must change.  The -help at the end of orca-help is being
+	  reserved for the mailing list named "orca".  As such, I'm
+	  renaming this list to orca-users at onelist.com.  All
+	  references to the old name in the package were similarly
+	  changed.
 
 Sun Mar  5 20:27:38 PST 2000
 
-	Include and require Storable 0.6.9.
+	* Include and require Storable 0.6.9.
 
 Wed Mar  1 14:40:26 PST 2000
 
-	Require the latest versions of all the modules Orca uses.
+	* Require the latest versions of all the modules Orca uses.
 
 Wed Mar  1 13:33:00 PST 2000
 
-	Only build RRDtool if it is needed.
+	* Only build RRDtool if it is needed.
 
 Tue Feb 29 17:43:15 PST 2000
 
-	To prevent Orca from performing all the gunzip, uncompress,
-	and bunzip2 system calls to get the first line of the source
-	file, store the first line in the state file and use it when
-	constructing the Orca::SourceFile object.
+	* To prevent Orca from performing all the gunzip, uncompress,
+	  and bunzip2 system calls to get the first line of the source
+	  file, store the first line in the state file and use it when
+	  constructing the Orca::SourceFile object.
 
 Tue Feb 29 12:16:22 PST 2000
 
-	Update orcallator.cfg.in to plot the NFS server calls per
-	second and also the v{2,3}{reads,writes}.
+	* Update orcallator.cfg.in to plot the NFS server calls per
+	  second and also the v{2,3}{reads,writes}.
 
 Tue Feb 29 12:02:45 PST 2000
 
-	Update the POD documentation for data_type by copying the
-	exact text from the rrdcreate.pod file.
+	* Update the POD documentation for data_type by copying the
+	  exact text from the rrdcreate.pod file.
 
 Sat Feb 26 13:29:16 PST 2000
 
-	If Orca::OpenFileHash::open tries to open a pipe for
-	compressed input and it cannot be opened, then shrink the
-	maximum number of open file descriptors and close enough
-	descriptors to attempt the pipe again.
+	* If Orca::OpenFileHash::open tries to open a pipe for
+	  compressed input and it cannot be opened, then shrink the
+	  maximum number of open file descriptors and close enough
+	  descriptors to attempt the pipe again.
 
 Fri Feb 25 17:15:37 PST 2000
 
-	Upgrade to orcallator.se 1.23.  When orcallator was running on
-	a system with DiskSuite, the same physical disk was listed
-	multiple times when it appeared in the same metadevice.  The
-	solution to the problem is not to build the c0t0d0 name but
-	use the long disk name provided by the long_name string.
-	Patch contributed by Paul Haldane
-	<Paul.Haldane at newcastle.ac.uk>.
-
-	To facilitate Orca loading in a huge amount of data in one
-	pass, add a new group configuration file parameter that tells
-	Orca how to sort the filenames and when data loaded from them
-	can be flushed to disk.  The new parameters name is
-	"filename_compare" and takes a Perl subroutine that behaves
-	like a subroutine given to sort.  Data is flushed to disk when
-	the subroutine returns a number greater than 1.
+	* Upgrade to orcallator.se 1.23.  When orcallator was running
+	  on a system with DiskSuite, the same physical disk was
+	  listed multiple times when it appeared in several
+	  metadevices.  The solution to the problem is not to build
+	  the c0t0d0 name but use the long disk name provided by the
+	  long_name string.  Patch contributed by Paul Haldane
+	  <Paul.Haldane at newcastle.ac.uk>.
+
+	* To facilitate Orca loading in a huge amount of data in one
+	  pass, add a new group configuration file parameter that
+	  tells Orca how to sort the filenames and when data loaded
+	  from them can be flushed to disk.  The new parameters name
+	  is "filename_compare" and takes a Perl subroutine that
+	  behaves like a subroutine given to sort.  Data is flushed to
+	  disk when the subroutine returns a number greater than 1.
 
 Fri Feb 25 16:49:44 PST 2000
 
-	Save the state more often so that if Orca quits in the middle,
-	it does not have to reload all the data from the files again,
-	even if the data has already been loaded into the RRD files.
+	* Save the state more often so that if Orca quits in the
+	  middle, it does not have to reload all the data from the
+	  files again, even if the data has already been loaded into
+	  the RRD files.
 
 Fri Feb 25 16:35:29 PST 2000
 
-	Have configure determine the best ps commmand to run to get
-	information on the current running Orca process.
+	* Have configure determine the best ps commmand to run to get
+	  information on the current running Orca process.
 
-	Finish splitting up the monolithic orca.pl.in into separate
-	modules.
+	* Finish splitting up the monolithic orca.pl.in into separate
+	  modules.
 
 Fri Feb 25 12:44:43 PST 2000
 
-	start_orcallator.sh refers to percollator.  Change it to refer
-	to orcallator.
+	* start_orcallator.sh refers to percollator.  Change it to refer
+	  to orcallator.
 
-	If two different groups had the same subgroup, then Orca would
-	list both group's subgroup file IDs for both subgroups.  Fix
-	this bug.
+	* If two different groups had the same subgroup, then Orca
+	  would list both group's subgroup file IDs for both
+	  subgroups.  Fix this bug.
 
-	Rename Orca::FileIDs to Orca::SourceFileIDs.
+	* Rename Orca::FileIDs to Orca::SourceFileIDs.
 
 Fri Feb 18 13:00:19 PST 2000
 
-	Apply a patch to Orca::ImageFile so that the legends are
-	properly created with the newer RRDtool.
+	* Apply a patch to Orca::ImageFile so that the legends are
+	  properly created with the newer RRDtool.
 
 Fri Feb 18 12:19:14 PST 2000
 
-	Include and require RRDtool 1.0.13.
+	* Include and require RRDtool 1.0.13.
 
 Thu Feb 17 13:13:39 PST 2000
 
-	Include orcallator.se 1.22, which includes the following
-	changes: Include code to record NFS v2 and v3 server
-	statistics.  The new statistics are: nfss_calls, the number of
-	NFS calls to the NFS server, nfss_bad, the number of bad NFS
-	calls per second, and v{2,3}{reads,writes}, which are
-	nfss_calls broken down into NFS version 2 and NFS version 3
-	calls.  The sum of v{2,3}{reads, writes} will be less than
-	nfss_calls as the other types of NFS calls, such as getattr
-	and lookup, are not included.  Contributed by Paul Haldane
-	<Paul.Haldane at newcastle.ac.uk>.  This code is enabled by the
-	standard -DWATCH_OS or individually by -DWATCH_NFS_SERVER.
-	The define -DWATCH_NFS has been supperseded by
-	-DWATCH_NFS_CLIENT, but to keep backwards compatibility,
-	-DWATCH_NFS_CLIENT will be defined if -DWATCH_NFS is defined.
-
-        Include orcallator.se 1.21, which includes the following
-        changes: Prevent core dumps on extremely long access log
-        lines.
+	* Include orcallator.se 1.22, which includes the following
+	  changes: Include code to record NFS v2 and v3 server
+	  statistics.  The new statistics are: nfss_calls, the number
+	  of NFS calls to the NFS server, nfss_bad, the number of bad
+	  NFS calls per second, and v{2,3}{reads,writes}, which are
+	  nfss_calls broken down into NFS version 2 and NFS version 3
+	  calls.  The sum of v{2,3}{reads, writes} will be less than
+	  nfss_calls as the other types of NFS calls, such as getattr
+	  and lookup, are not included.  Contributed by Paul Haldane
+	  <Paul.Haldane at newcastle.ac.uk>.  This code is enabled by the
+	  standard -DWATCH_OS or individually by
+	  -DWATCH_NFS_SERVER.  The define -DWATCH_NFS has been
+	  superseded by -DWATCH_NFS_CLIENT, but to keep backwards
+	  compatibility, -DWATCH_NFS_CLIENT will be defined if
+	  -DWATCH_NFS is defined.
+
+	* Include orcallator.se 1.21, which includes the following
+	  changes: Prevent core dumps on extremely long access log
+	  lines.
 
 Wed Oct 20 17:39:19 PDT 1999
 
-	Release Orca 0.25.
+	* Release Orca 0.25.
 
 Wed Oct 20 17:37:01 PDT 1999
 
-	Fix that annoying warning from pod2html when orca.html is
-	generated.
+	* Fix that annoying warning from pod2html when orca.html is
+	  generated.
 
-	Include Storable 0.607 but continue to only require 0.603.
+	* Include Storable 0.607 but continue to only require 0.603.
 
-	Add a mention in the POD that sending a HUP to the Orca
-	process forces it to look for new files in the next loop.
-	This is faster than restarting Orca.
-
-	Change the behavior of warnings when data requested to be
-	plotted in the configuration file does not exist in the source
-	data files.  Any resulting errors from this, such as cannot
-	compile errors, are only sent when the verbose level is above
-	1 or when the plot is required.
-
-	Did some renaming of classes and variables in limited places:
-	Orca::SourceDataFile -> Orca::SourceFile
-	files_key            -> group
-	group                -> subgroup
-	gif                  -> image
-
-	Orcallator.se 1.20 now mentions my new email address of
-	blair at akamai.com instead of the old one.
-
-	Move all references to my and Orca's home page from GeoCities
-	(www.geocities.com/~bzking/) to Caltech
-	(www.gps.caltech.edu/~blair/orca/) everywhere.
-
-	In the default orcallator.cfg, make sure it can find compressed
-	orcallator files in the find_files statement.
-
-	Make sure all Makefile's can rebuild themselves from their
-	Makefile.in and make sure that the Makefile target is built when
-	all is built.
-
-	Put in an optimization where Orca would not repeatedly create
-	a new anonymous subroutine to catch warnings when eval's were
-	being performed.
-
-	Add a new make target, orcallator_run_at_boot, which installs
-	into the proper /etc/*.d/ directories the scripts to start
-	orcallator at boot time and stop orcallator at halt time.
-	Update the INSTALL file to mention this.
-
-	Fix an important bug where Orca would crash if column names
-	mentioned in the configuration file did not exist in the source
-	data files.  This fix was in Orca::SourceFile::add_plots.
+	* Add a mention in the POD that sending a HUP to the Orca
+	  process forces it to look for new files in the next
+	  loop.  This is faster than restarting Orca.
+
+	* Change the behavior of warnings when data requested to be
+	  plotted in the configuration file does not exist in the
+	  source data files.  Any resulting errors from this, such as
+	  cannot compile errors, are only sent when the verbose level
+	  is above 1 or when the plot is required.
+
+	* Did some renaming of classes and variables in limited
+	  places:
+	  Orca::SourceDataFile -> Orca::SourceFile
+	  files_key            -> group
+	  group                -> subgroup
+	  gif                  -> image
+
+	* Orcallator.se 1.20 now mentions my new email address of
+	  blair at akamai.com instead of the old one.
+
+	* Move all references to my and Orca's home page from
+	  GeoCities (www.geocities.com/~bzking/) to Caltech
+	  (www.gps.caltech.edu/~blair/orca/) everywhere.
+
+	* In the default orcallator.cfg, make sure it can find
+	  compressed orcallator files in the find_files statement.
+
+	* Make sure all Makefile's can rebuild themselves from their
+	  Makefile.in and make sure that the Makefile target is built
+	  when all is built.
+
+	* Put in an optimization where Orca would not repeatedly
+	  create a new anonymous subroutine to catch warnings when
+	  eval's were being performed.
+
+	* Add a new make target, orcallator_run_at_boot, which
+	  installs into the proper /etc/*.d/ directories the scripts
+	  to start orcallator at boot time and stop orcallator at halt
+	  time.  Update the INSTALL file to mention this.
+
+	* Fix an important bug where Orca would crash if column names
+	  mentioned in the configuration file did not exist in the
+	  source data files.  This fix was in
+	  Orca::SourceFile::add_plots.
 
 Tue Oct 19 18:25:12 PDT 1999
 
-	Make all plots optional by default.  Remove the optional plot
-	keyword and add required, which makes a plot required.
+	* Make all plots optional by default.  Remove the optional
+	  plot keyword and add required, which makes a plot required.
 
 Fri Oct 15 11:25:53 PDT 1999
 
-	Add a new plot in the default orcallator.cfg, the amount of free
-	physical memory.
+	* Add a new plot in the default orcallator.cfg, the amount of
+	  free physical memory.
 
-	Shorten the legend names in orcallator.cfg so that the complete
-	line fits in the generated image.  Also make the Y legend names
-	more consistent with each other.
+	* Shorten the legend names in orcallator.cfg so that the
+	  complete line fits in the generated image.  Also make the Y
+	  legend names more consistent with each other.
 
 Thu Oct 14 15:52:43 PDT 1999
 
-	Create a orcallator/S99orcallator file that can be used to start
-	orcallator.se at boot time and stop it at halt time.
+	* Create a orcallator/S99orcallator file that can be used to
+	  start orcallator.se at boot time and stop it at halt time.
 
 Thu Oct 14 14:44:00 PDT 1999
 
-	Release Orca 0.24.
+	* Release Orca 0.24.
 
 Thu Oct 14 12:17:29 PDT 1999
 
-	Back down to RRDtool 1.0.7 with only my filename length patch
-	applied per Tobi.
+	* Back down to RRDtool 1.0.7 with only my filename length
+	  patch applied per Tobi.
 
-	Revamp the INSTALL, NEWS, and other files to get a release out.
+	* Revamp the INSTALL, NEWS, and other files to get a release
+	  out.
 
-	Up the version number of the included RRDs package to 1.000072
-	since it contains some patches specifically for Orca.
+	* Up the version number of the included RRDs package to
+	  1.000072 since it contains some patches specifically for
+	  Orca.
 
 Wed Oct 13 12:40:29 PDT 1999
 
-	Orcallator.se 1.19 prevents a division by zero in calculating
-	the mean_disk_busy if the number of disks on the system is 0.
-
-	Move the URL http://www.geocities.com/~bzking/orcallator-docs/
-	to http://www.geocities.com/~bzking/docs/orcallator.html.
-
-	In cases where there are a large number of data sources in a
-	single image, then the list of available colors is expired.
-	Now reuse the colors.
+	* Orcallator.se 1.19 prevents a division by zero in
+	  calculating the mean_disk_busy if the number of disks on the
+	  system is 0.
+
+	* Move the URL
+	  http://www.geocities.com/~bzking/orcallator-docs/ to
+	  http://www.geocities.com/~bzking/docs/orcallator.html.
+
+	* In cases where there are a large number of data sources in a
+	  single image, then the list of available colors is
+	  expired.  Now reuse the colors.
 
-	Make sure plots are displayed in each subgroup's HTML files in
-	the order they appear in the configuration file.
+	* Make sure plots are displayed in each subgroup's HTML files
+	  in the order they appear in the configuration file.
 
 Tue Oct 12 10:27:44 PDT 1999
 
-	Update orcallator.cfg to remove the maximum and average disk busy
-	plot and add a plot that displays the run percent for each disk.
+	* Update orcallator.cfg to remove the maximum and average disk
+	  busy plot and add a plot that displays the run percent for
+	  each disk.
 
-	Orcallator 1.18 now renames disk_runp.c?t?d? to disk_runp_c?t?d?.
+	* Orcallator 1.18 now renames disk_runp.c?t?d? to
+	  disk_runp_c?t?d?.
 
 Mon Oct 11 14:31:38 PDT 1999
 
-	Update orcallator.cfg to plot the disk space and inode usage
-	for all locally mounted filesystems.
+	* Update orcallator.cfg to plot the disk space and inode usage
+	  for all locally mounted filesystems.
 
-	Apply a patch to RRDtool that increases the maximum filename
-	length for generated image files from 255 to 1024.
+	* Apply a patch to RRDtool that increases the maximum filename
+	  length for generated image files from 255 to 1024.
 
-	Rename &strip_key_name to &escape_name.
+	* Rename &strip_key_name to &escape_name.
 
 Fri Oct  8 14:23:37 PDT 1999
 
-	Save even more space in Orca generated HTML and image filenames.
-	On large directories, up to 10% disk space can be saved alone
-	in filenames according to du.  Also, if generated filenames are
-	longer than 235 characters, then compute a MD5 hash of the name,
-	trim the name down to 210 characters, and append the MD5 hash.
+	* Save even more space in Orca generated HTML and image
+	  filenames.  On large directories, up to 10% disk space can
+	  be saved alone in filenames according to du.  Also, if
+	  generated filenames are longer than 235 characters, then
+	  compute a MD5 hash of the name, trim the name down to 210
+	  characters, and append the MD5 hash.
 
-	Orcallator.se 1.17 now skips locally mounted /cdrom filesystems.
+	* Orcallator.se 1.17 now skips locally mounted /cdrom
+	  filesystems.
 
-	Increase the number of default known colors to 11.
+	* Increase the number of default known colors to 11.
 
 Wed Oct  6 17:59:05 PDT 1999
 
-	Orcallator.se 1.16 now compresses its log files after it has
-	completed a day's log using the command in the COMPRESSOR
-	environmental variable.  start_orcallator now passed this
-	environmental variable to orcallator.se.
+	* Orcallator.se 1.16 now compresses its log files after it has
+	  completed a day's log using the command in the COMPRESSOR
+	  environmental variable.  start_orcallator now passed this
+	  environmental variable to orcallator.se.
 
 Wed Oct  6 15:19:09 PDT 1999
 
-	Have configure.in look for bzip2, bunzip2, gzip, gunzip, compress,
-	and uncompress.  Define the COMPRESSOR and UNCOMPRESSOR_PIPE as
-	the best compression tool to use and add these names to the list
-	of names being substituted.  This only gets defined if both a
-	compress and uncompression tool is used.
+	* Have configure.in look for bzip2, bunzip2, gzip, gunzip,
+	  compress, and uncompress.  Define the COMPRESSOR and
+	  UNCOMPRESSOR_PIPE as the best compression tool to use and
+	  add these names to the list of names being substituted.
+	  This only gets defined if both a compress and uncompression
+	  tool is used.
 
-	To keep backwards compatibility in orcallator.se, define WATCH_WEB
-	if WATCH_HTTPD is defined.
+	* To keep backwards compatibility in orcallator.se, define
+	  WATCH_WEB if WATCH_HTTPD is defined.
 
 Tue Oct  5 14:54:59 PDT 1999
 
-	Update orcallator.se to 1.15.  kvm$mpid is a int not a long.
-	This caused problems on Solaris 7 hosts running a 64 bit kernel.
+	* Update orcallator.se to 1.15.  kvm$mpid is a int not a long.
+	  This caused problems on Solaris 7 hosts running a 64 bit
+	  kernel.
 
 Fri Oct  1 12:15:47 PDT 1999
 
-	Update orcallator.se to 1.14.  Rename disk.c?t?d? column names
-	to disk_runp.c?t?d? to better reflect the data being recorded
-	and to allow for more per disk information later.
+	* Update orcallator.se to 1.14.  Rename disk.c?t?d? column
+	  names to disk_runp.c?t?d? to better reflect the data being
+	  recorded and to allow for more per disk information later.
 
-	Install the latest RRDtool patch.
+	* Install the latest RRDtool patch.
 
 Thu Sep 29 19:19:23 PDT 1999
 
-	Add some more space between a plot's legend and the minimum,
-	maximum, etc information for a particular piece of data.
+	* Add some more space between a plot's legend and the minimum,
+	  maximum, etc information for a particular piece of data.
 
-	Allow mathematical expressions in plots where the first data
-	contains a regular expression.
+	* Allow mathematical expressions in plots where the first data
+	  contains a regular expression.
 
 Fri Sep 24 11:50:33 PDT 1999
 
-	Many fixes and improvements to orcallator.se.  Fix a bug in the
-	disk_mean calculation where it was being divided by the wrong
-	disk_count.  Now it should be much larger and in scale with
-	disk_peak.  When WATCH_DISK is defined, now print each disk's
-	run percent.  Add a new define WATCH_MOUNTS, which reports each
-	mount point's disk space and inode capacity, usage, available
-	for non-root users and percent used.  This comes from Duncan
-	Lawie tyger at hoopoes.com.  Add some smarts so that if the number
-	of interfaces, physical disk, or mounted partitions changes,
-	then a new header is printed.  This will prevent column name
-	and data mixups when the system configuration changes.
+	* Many fixes and improvements to orcallator.se.  Fix a bug in
+	  the disk_mean calculation where it was being divided by the
+	  wrong disk_count.  Now it should be much larger and in scale
+	  with disk_peak.  When WATCH_DISK is defined, now print each
+	  disk's run percent.  Add a new define WATCH_MOUNTS, which
+	  reports each mount point's disk space and inode capacity,
+	  usage, available for non-root users and percent used.  This
+	  comes from Duncan Lawie tyger at hoopoes.com.  Add some smarts
+	  so that if the number of interfaces, physical disk, or
+	  mounted partitions changes, then a new header is printed.
+	  This will prevent column name and data mixups when the
+	  system configuration changes.
 
 Mon Sep 20 11:18:21 PDT 1999
 
-	Include Storable 0.605 but continue to only require 0.603.
+	* Include Storable 0.605 but continue to only require 0.603.
 
 Tue Sep 14 15:54:38 PDT 1999
 
-	Add the page scan rate to orcallator.se as column scanrate.
+	* Add the page scan rate to orcallator.se as column scanrate.
 
 Tue Sep  7 12:21:52 PDT 1999
 
-	Update the archive URLs for the orca-* mailing lists.
+	* Update the archive URLs for the orca-* mailing lists.
 
 Thu Sep  2 11:03:19 PDT 1999
 
-	Include and require RRDtool 1.0.7.
+	* Include and require RRDtool 1.0.7.
 
-	Make some more minor changes to have Orca run with Perl 5.004_01.
+	* Make some more minor changes to have Orca run with Perl
+	  5.004_01.
 
 Tue Aug 24 11:32:34 PDT 1999
 
-	Include and require Math::Interpolate 1.05.
+	* Include and require Math::Interpolate 1.05.
 
 Thu Aug 19 14:13:16 PDT 1999
 
-	No longer include Compress::Zlib, which was to be used to read in
-	compressed source data files without spawning a separate process.
-	Now it seems easier to just call gunzip -c.
+	* No longer include Compress::Zlib, which was to be used to
+	  read in compressed source data files without spawning a
+	  separate process.  Now it seems easier to just call gunzip
+	  -c.
 
 Wed Aug 18 11:10:21 PDT 1999
 
-	Read in .gz files using gunzip, .Z files using uncompress,
-	and .bz2 files with bunzip2.
+	* Read in .gz files using gunzip, .Z files using uncompress,
+	  and .bz2 files with bunzip2.
 
-	Clean up some bugs where the RRDs::graph -r option would always
-	be used.
+	* Clean up some bugs where the RRDs::graph -r option would
+	  always be used.
 
-	Plots can now take a logarithmic option which specified that
-	the Y axis will have a logarithmic scale.
+	* Plots can now take a logarithmic option which specified that
+	  the Y axis will have a logarithmic scale.
 
 Tue Aug 17 11:50:34 PDT 1999
 
-	Include and require Math::Interpolate 1.04.
+	* Include and require Math::Interpolate 1.04.
 
-	No longer have Orca::RRDFile be a subclass of Orca::DataFile, since
-	Orca::DataFile now handles FIDs and the FID namespace should not be
-	polluted by the RRD filenames.
+	* No longer have Orca::RRDFile be a subclass of
+	  Orca::DataFile, since Orca::DataFile now handles FIDs and
+	  the FID namespace should not be polluted by the RRD
+	  filenames.
 
 Mon Aug 16 12:11:48 PDT 1999
 
-	Design a new module, Orca::FileIDs, for managing the long lists
-	of long filenames for memory and CPU speed improvements.  Now all
-	classes use File IDentifiers (FIDs) instead of filenames.
+	* Design a new module, Orca::FileIDs, for managing the long
+	  lists of long filenames for memory and CPU speed
+	  improvements.  Now all classes use File IDentifiers (FIDs)
+	  instead of filenames.
 
-	Add locking on a particular configuration file.  Make a directory
-	using the configuration filename.
+	* Add locking on a particular configuration file.  Make a
+	  directory using the configuration filename.
 
-	Include and require RRDtool 1.0.6.
+	* Include and require RRDtool 1.0.6.
 
 Fri Aug 13 17:10:23 PDT 1999
 
-	Install librrd.so on Solaris hosts in $libdir so that
-	orcallator.se can attach to it.
+	* Install librrd.so on Solaris hosts in $libdir so that
+	  orcallator.se can attach to it.
 
 Fri Aug 13 15:35:21 PDT 1999
 
-	Include and require RRDtool 1.0.5.
+	* Include and require RRDtool 1.0.5.
 
 Mon Aug  9 10:32:42 PDT 1999
 
-	Include and require RRDtool 1.0.4.
+	* Include and require RRDtool 1.0.4.
 
 Fri Aug  6 09:29:14 PDT 1999
 
-	Include Digest::MD5 2.09 but continue to only require 2.00.
+	* Include Digest::MD5 2.09 but continue to only require 2.00.
 
 Thu Aug  5 20:58:32 PDT 1999
 
-	Make sure start_orcallator looks to see if SE is defined.  If it
-	is not, then print a message stating where to find the SE toolkit.
+	* Make sure start_orcallator looks to see if SE is defined.
+	  If it is not, then print a message stating where to find the
+	  SE toolkit.
 
 Fri Jul 30 09:12:20 PDT 1999
 
-	Update orcallator.cfg to plot the new process spawn rate.
+	* Update orcallator.cfg to plot the new process spawn rate.
 
-	Include and require RRDtool 1.0.3.
+	* Include and require RRDtool 1.0.3.
 
 Thu Jul 29 10:36:20 PDT 1999
 
-	To fix the problem of too long HTML and image file names,
-	shorten the names as they get passed through strip_key_name.
-	Now orcallator -> o, orca -> o, _times_ -> _X_, _percent_ ->
-	_pct_, _number_ -> _num_.  The upgrade_installation will perform
-	these renames on a list of directories.
+	* To fix the problem of too long HTML and image file names,
+	  shorten the names as they get passed through
+	  strip_key_name.  Now orcallator -> o, orca -> o, _times_ ->
+	  _X_, _percent_ -> _pct_, _number_ -> _num_.  The
+	  upgrade_installation will perform these renames on a list of
+	  directories.
 
-	Since orcallator is only one of many different data gatherers,
-	move it into its own directory.
+	* Since orcallator is only one of many different data
+	  gatherers, move it into its own directory.
 
 Wed Jul 28 10:10:53 PDT 1999
 
-	If WATCH_CPU is defined and if the user can read /dev/kmem then
-	orcallator.se will now measure the process spawn rate over a 5
-	minute interval and also record the maximum rate measured over
-	a 5 second interval.
-
-	Add a href field for a plot in the configuration file.	This,
-	if defined, lets you make a particular target type be a HREF to
-	read something about that target type.
+	* If WATCH_CPU is defined and if the user can read /dev/kmem
+	  then orcallator.se will now measure the process spawn rate
+	  over a 5 minute interval and also record the maximum rate
+	  measured over a 5 second interval.
+
+	* Add a href field for a plot in the configuration file.
+	  This, if defined, lets you make a particular target type be
+	  a HREF to read something about that target type.
 
-	Include Digest::MD5 2.08 but continue to only require 2.00.
+	* Include Digest::MD5 2.08 but continue to only require 2.00.
 
 Fri Jul 23 13:41:36 PDT 1999
 
-	Include and require RRDtool 1.0.1.
+	* Include and require RRDtool 1.0.1.
 
 Thu Jul 22 17:06:45 PDT 1999
 
-	Use a blessed reference to an array for the Orca::DataFile,
-	Orca::HTMLFile, Orca::ImageFile, Orca::OpenFileHash,
-	Orca::RRDFile, and Orca::OpenFileHash classes.
+	* Use a blessed reference to an array for the Orca::DataFile,
+	  Orca::HTMLFile, Orca::ImageFile, Orca::OpenFileHash,
+	  Orca::RRDFile, and Orca::OpenFileHash classes.
 
 Mon Jul 19 12:57:56 PDT 1999
 
-	On a fresh install make sure to mkdir RRD_DIR/orcallator.
+	* On a fresh install make sure to mkdir RRD_DIR/orcallator.
 
-	Change the tag name data_dir to rrd_dir to make it clearer what
-	kind of data is being loaded.
+	* Change the tag name data_dir to rrd_dir to make it clearer
+	  what kind of data is being loaded.
 
-	Integrate building of Compress::Zlib into the Makefile structure.
-	Make use of the Zlib 1.1.3 library included with RRDtool for
-	Compress::Zlib.
+	* Integrate building of Compress::Zlib into the Makefile
+	  structure.  Make use of the Zlib 1.1.3 library included with
+	  RRDtool for Compress::Zlib.
 
 Fri Jul 16 11:12:02 PDT 1999
 
-	Include and require RRDtool 1.0.0 and Compress::Zlib 1.05.
+	* Include and require RRDtool 1.0.0 and Compress::Zlib 1.05.
 
-	Update the colors in orcallator.cfg.  In all plots, make one
-	plot use area.
+	* Update the colors in orcallator.cfg.  In all plots, make one
+	  plot use area.
 
 Thu Jul 15 11:35:52 PDT 1999
 
-	As noted by Bob Hoekstra <Bob_Hoekstra at merck.com>, orcallator.se
-	was outputting the same information for ??load as for ??runq.
-	Orcallator.se no longer generates that data and orcallator.cfg
-	no longer generates plots for it.
+	* As noted by Bob Hoekstra <Bob_Hoekstra at merck.com>,
+	  orcallator.se was outputting the same information for ??load
+	  as for ??runq.  Orcallator.se no longer generates that data
+	  and orcallator.cfg no longer generates plots for it.
 
 Wed Jul 14 11:04:09 PDT 1999
 
-	Switch to use PNGs instead of GIFs.  They take up 1/3 less space
-	than GIFs and at least 10% less time to generate.
+	* Switch to use PNGs instead of GIFs.  They take up 1/3 less
+	  space than GIFs and at least 10% less time to generate.
 
-	Rename all variables and comments containing GIF to image.
+	* Rename all variables and comments containing GIF to image.
 
-	Revamp the INSTALL document to reflect the new * -> _times_
-	change and add some documentation of the file descriptor limit.
+	* Revamp the INSTALL document to reflect the new * -> _times_
+	  change and add some documentation of the file descriptor
+	  limit.
 
-	Uncompress and read .Z and .gz compressed input files on the fly.
+	* Uncompress and read .Z and .gz compressed input files on the
+	* fly.
 
 Wed Jul 14 10:22:13 PDT 1999
 
-	Include and require RRDtool 0.99.52.
+	* Include and require RRDtool 0.99.52.
 
 Tue Jul 13 12:34:29 PDT 1999
 
@@ -486,619 +899,649 @@
 
 	Rename the migrate_to_orcallator script to upgrade_installation.
 
-	Per Vadim Shulkin <vadim.shulkin at csfb.com> request, replace the
-	* in all generated filenames with _times_.  Put this rename in
-	the new upgrade_installation script.
+	* Per Vadim Shulkin <vadim.shulkin at csfb.com> request, replace
+	  the * in all generated filenames with _times_.  Put this
+	  rename in the new upgrade_installation script.
 
 Tue Jul  6 18:14:20 PDT 1999
 
-	Include and require RRDtool 0.99.49.
+	* Include and require RRDtool 0.99.49.
 
 Sun Jul  4 16:57:28 PDT 1999
 
-	Include and require RRDtool 0.99.47.
+	* Include and require RRDtool 0.99.47.
 
 Fri Jul  2 18:16:21 PDT 1999
 
-	Include and require RRDtool 0.99.46.
+	* Include and require RRDtool 0.99.46.
 
 Tue Jun 29 13:18:57 PDT 1999
 
-	Add a new option for each plot named base that allows the base
-	for each plot to be either 1000 or 1024.  This allows for plotting
-	of memory or network type of datas.
-
-	Use the new base option in the number of bytes of available swap
-	space plots.
-
-	Include and require RRDtool 0.99.45.
-
-	Make use of RRDtool's 0.99.45 capability to place the SI number
-	suffix to numbers appearing in the legend using the GPRINT
-	command.
+	* Add a new option for each plot named base that allows the
+	  base for each plot to be either 1000 or 1024.  This allows
+	  for plotting of memory or network type of datas.
+
+	* Use the new base option in the number of bytes of available
+	  swap space plots.
+
+	* Include and require RRDtool 0.99.45.
+
+	* Make use of RRDtool's 0.99.45 capability to place the SI
+	  number suffix to numbers appearing in the legend using the
+	  GPRINT command.
 
 Mon Jun 28 11:16:46 PDT 1999
 
-	Now only print found filenames if the verbose level is above one.
-	Orca was generating too much output.
+	* Now only print found filenames if the verbose level is above
+	  one.  Orca was generating too much output.
 
-	When creating all the HTML files, do not write directly to the
-	new filename, instead write to a temporary filename and when
-	the file is closed, then rename it to the final name.  This lets
-	the user view existing HTML files even when the new HTML files
-	are being updated.
+	* When creating all the HTML files, do not write directly to
+	  the new filename, instead write to a temporary filename and
+	  when the file is closed, then rename it to the final name.
+	  This lets the user view existing HTML files even when the
+	  new HTML files are being updated.
 
-	Include RRDtool 0.99.41 but continue to only require 0.99.29.
+	* Include RRDtool 0.99.41 but continue to only require 0.99.29.
 
 Tue Jun 22 10:54:39 PDT 1999
 
-	Include RRDtool 0.99.40 but continue to only require 0.99.29.
+	* Include RRDtool 0.99.40 but continue to only require
+	  0.99.29.
 
 Thu Jun 10 09:39:36 PDT 1999
 
-	When 80% of a host's processes are web serving processes, plotting
-	the total system and number of httpd's together on the same plot
-	makes sense.  However, for people running a tiny web server with
-	only a few processes, this does not make sense, so a separate
-	plot is created.  Noted by Paul Company <paul.company at plpt.com>.
+	* When 80% of a host's processes are web serving processes,
+	  plotting the total system and number of httpd's together on
+	  the same plot makes sense.  However, for people running a
+	  tiny web server with only a few processes, this does not
+	  make sense, so a separate plot is created.  Noted by Paul
+	  Company <paul.company at plpt.com>.
 
 Tue Jun  8 15:16:43 PDT 1999
 
-	Begin the break up orca.pl into separate files for each module.
+	* Begin the break up orca.pl into separate files for each
+	  module.
 
 Tue Jun  8 10:57:39 PDT 1999
 
-	Make the table of contents in INSTALL consistent with the contents
-	of the file.
+	* Make the table of contents in INSTALL consistent with the
+	  contents of the file.
 
 Mon Jun  7 13:01:05 PDT 1999
 
-	Include RRDtool 0.99.32 but continue to only require 0.99.29.
+	* Include RRDtool 0.99.32 but continue to only require
+	  0.99.29.
 
 Thu Jun  3 13:27:09 PDT 1999
 
-	Fix a bug in Orca::SourceDataFile::add_plots where it was
-	dereferencing an undef.
+	* Fix a bug in Orca::SourceDataFile::add_plots where it was
+	  dereferencing an undef.
 
-	Since orcallator.se may watch many different types of web
-	server logs, move some of the common code into CPP defines.
-	Defines are preferred over functions since the function call
-	overhead in SE is larger than having the code inlined.
-
-	Have orcallator.se watch Yahoo! style web access logs if
-	-DWATCH_YAHOO is passed on the command line.
-
-	If any of the environmental variables used by orcallator.se were
-	defined then the value was used, even if the length was zero.
-	Now the length of the variable must be non-zero for the value
-	to be used, otherwise the default value is used.
+	* Since orcallator.se may watch many different types of web
+	  server logs, move some of the common code into CPP defines.
+	  Defines are preferred over functions since the function call
+	  overhead in SE is larger than having the code inlined.
+
+	* Have orcallator.se watch Yahoo! style web access logs if
+	  -DWATCH_YAHOO is passed on the command line.
+
+	* If any of the environmental variables used by orcallator.se
+	  were defined then the value was used, even if the length was
+	  zero.  Now the length of the variable must be non-zero for
+	  the value to be used, otherwise the default value is used.
 
 Wed Jun  2 12:11:44 PDT 1999
 
-	Optimize orcallator.se slightly when it determines the size bin
-	for a particular file served.
+	* Optimize orcallator.se slightly when it determines the size
+	  bin for a particular file served.
 
-	Change the define WATCH_HTTPD in orcallator.se to WATCH_WEB to
-	be consistent with the other WEB_* defines and environmental
-	variables.
+	* Change the define WATCH_HTTPD in orcallator.se to WATCH_WEB
+	  to be consistent with the other WEB_* defines and
+	  environmental variables.
 
 Tue Jun  1 21:53:15 PDT 1999
 
-	For orcallator.se, if the WEB_SERVER environmental variable
-	is set, then the value of of WEB_SERVER is used to count the
-	number of web server processes.  If WEB_SERVER is not defined
-	it defaults to httpd.
+	* For orcallator.se, if the WEB_SERVER environmental variable
+	  is set, then the value of of WEB_SERVER is used to count the
+	  number of web server processes.  If WEB_SERVER is not
+	  defined it defaults to httpd.
 
 Fri May 28 17:39:36 PDT 1999
 
-	Add to the plot title the type of the plot, i.e. 'Yearly',
-	in every GIF.  Requested by Tom Murray <murray at reston.wcom.net>.
+	* Add to the plot title the type of the plot, i.e. 'Yearly',
+	  in every GIF.  Requested by Tom Murray
+	  <murray at reston.wcom.net>.
 
 Thu May 27 10:53:02 PDT 1999
 
-	Release version 0.23.
+	* Release version 0.23.
 
 Thu May 27 09:24:20 PDT 1999
 
-	Add another optimization that saves the result of computing how
-	old each GIF must be before it is recreated.
+	* Add another optimization that saves the result of computing
+	  how old each GIF must be before it is recreated.
 
-	Fix a bug noted by Peter Radcliffe <pir at pir.net> where I missed
-	changing some PERCOLLATOR_DIR variables to ORCALLATOR_DIR in
-	src/start_orcallator.sh.in and src/orcallator_running.pl.in.
+	* Fix a bug noted by Peter Radcliffe <pir at pir.net> where I
+	  missed changing some PERCOLLATOR_DIR variables to
+	  ORCALLATOR_DIR in src/start_orcallator.sh.in and
+	  src/orcallator_running.pl.in.
 
 Wed May 26 17:54:26 PDT 1999
 
-	Release version 0.22.
+	* Release version 0.22.
 
 Wed May 26 12:10:42 PDT 1999
 
-	Move the portions of the code that generate the RRDs::graph
-	options that do not change between invocations to the
-	_update_graph_options method.  This method gets called when the
-	Orca::GIFFile is constructed and any time add_rrds is called.
-	This speeds Orca up slightly.
-
-	Include RRDtool 0.99.31 but continue to only require 0.99.29.
-
-	Add a new quarterly plot that shows the last 100 days.	This is
-	a nice transition between the monthly and yearly plots.
-
-	Change the number of days shown in the yearly plot from 500 to
-	428, which is one year and two months.	Reducing the number
-	of days from 500 by at least one day will speed up the GIF
-	generation time because by default the plot portion of the GIFs
-	are 500 pixels wide.
-
-	Add two new classes Orca::Config::Plot and
-	Orca::Config::FilesGroup that do not do anything yet but
-	will provide an object-oriented interface to config_plots and
-	config_files.  Currently all the values in @$config_plots and
-	%$config_files are now bless objects instead of unblessed objects.
+	* Move the portions of the code that generate the RRDs::graph
+	  options that do not change between invocations to the
+	  _update_graph_options method.  This method gets called when
+	  the Orca::GIFFile is constructed and any time add_rrds is
+	  called.  This speeds Orca up slightly.
+
+	* Include RRDtool 0.99.31 but continue to only require
+	  0.99.29.
+
+	* Add a new quarterly plot that shows the last 100 days.  This
+	  is a nice transition between the monthly and yearly plots.
+
+	* Change the number of days shown in the yearly plot from 500
+	  to 428, which is one year and two months.  Reducing the
+	  number of days from 500 by at least one day will speed up
+	  the GIF generation time because by default the plot portion
+	  of the GIFs are 500 pixels wide.
+
+	* Add two new classes Orca::Config::Plot and
+	  Orca::Config::FilesGroup that do not do anything yet but
+	  will provide an object-oriented interface to config_plots
+	  and config_files.  Currently all the values in
+	  @$config_plots and %$config_files are now bless objects
+	  instead of unblessed objects.
 
 Thu May 20 10:59:26 PDT 1999
 
-	Put a closing ) in a error message in RRDtool 0.99.29.1.
+	* Put a closing ) in a error message in RRDtool 0.99.29.1.
 
-	Fix a bug in queue_data where it was sending data to rrd_update
-	that was already in the RRD file.
+	* Fix a bug in queue_data where it was sending data to
+	  rrd_update that was already in the RRD file.
 
 Wed May 19 10:43:48 PDT 1999
 
-	Remove the load_state and save_state subroutines and replace
-	them with an object-oriented Orca::State class for saving
-	information between Orca invocations.  Use the Storable class
-	to save information instead of a text based method.
-
-	Restructured the code so each Orca::SourceDataFile has only one
-	anonymous subroutine to read in all the valued from a single
-	line of the source data file.  This sped Orca up slightly.
-
-	Add a -r option to Orca to have it not create any HTML or GIF
-	files and only update the RRD files.
-
-	Fix a bug where if the number of columns changed in from
-	one source file to the next source file in a files group,
-	the column index used to get a particular value is the old
-	index for the old file and not the new index for the new file.
-	This fix involved having the Orca::SourceDataFile object run
-	the anonymous subroutines to pick the correct data from a line
-	instead of Orca::RRDFile.
-
-	Remove some unused methods: Orca::OpenFileHash::list,
-	Orca::OpenFileHash::select, Orca::OpenFileHash::sysread_readline
-	Add some more documentation to orcallator.cfg.
+	* Remove the load_state and save_state subroutines and replace
+	  them with an object-oriented Orca::State class for saving
+	  information between Orca invocations.  Use the Storable
+	  class to save information instead of a text based method.
+
+	* Restructured the code so each Orca::SourceDataFile has only
+	  one anonymous subroutine to read in all the valued from a
+	  single line of the source data file.  This sped Orca up
+	  slightly.
+
+	* Add a -r option to Orca to have it not create any HTML or
+	  GIF files and only update the RRD files.
+
+	* Fix a bug where if the number of columns changed in from
+	  one source file to the next source file in a files group,
+	  the column index used to get a particular value is the old
+	  index for the old file and not the new index for the new
+	  file.  This fix involved having the Orca::SourceDataFile
+	  object run the anonymous subroutines to pick the correct
+	  data from a line instead of Orca::RRDFile.
+
+	* Remove some unused methods: Orca::OpenFileHash::list,
+	  Orca::OpenFileHash::select,
+	  Orca::OpenFileHash::sysread_readline.  Add some more
+	  documentation to orcallator.cfg.
 
-	Skip a line in an input source data file if the word timestamp
-	is found in it.  This is a temporary fix.
+	* Skip a line in an input source data file if the word
+	  timestamp is found in it.  This is a temporary fix.
 
 Mon May 17 16:26:17 PDT 1999
 
-	Release version 0.21.
+	* Release version 0.21.
 
 Mon May 17 15:07:33 PDT 1999
 
-	Correct a bug when a source data file cannot be loaded it should
-	not used to look up a Orca::SourceDataFile object.
+	* Correct a bug when a source data file cannot be loaded it
+	  should not used to look up a Orca::SourceDataFile object.
 
-	Reformat all the comments in orca.pl.
+	* Reformat all the comments in orca.pl.
 
 Thu May 13 10:47:41 PDT 1999
 
-	Orca used to delete RRD files if they had an $ORCA_RRD_VERSION
-	number newer then the required version number.	Now use them.
-	Add code to remember the Orca RRD version number so that the
-	GIF creation code works properly with RRD files with a version
-	different than $ORCA_RRD_VERSION.
-
-	Thanks to a configure file and some data from from Eric Blaise
-	<Eric.Blaise at socgen.com>, Orca can now handle plots containing
-	columns of data that do not exist in all input source data files.
-
-	In add_plots, a linear search was used to convert column
-	description names appearing in data statements to an index into
-	the column_description array.  Now use a hash table look up.
+	* Orca used to delete RRD files if they had an
+	  $ORCA_RRD_VERSION number newer then the required version
+	  number.  Now use them.  Add code to remember the Orca RRD
+	  version number so that the GIF creation code works properly
+	  with RRD files with a version different than
+	  $ORCA_RRD_VERSION.
+
+	* Thanks to a configure file and some data from from Eric
+	  Blaise <Eric.Blaise at socgen.com>, Orca can now handle plots
+	  containing columns of data that do not exist in all input
+	  source data files.
+
+	* In add_plots, a linear search was used to convert column
+	  description names appearing in data statements to an index
+	  into the column_description array.  Now use a hash table
+	  look up.
 
 Wed May 12 09:31:43 PDT 1999
 
-	Orca now cleans up all file paths in the input configuration file.
-	If more than one / are found in a row, they are replaced by one /.
-	The base_dir is only prepended to paths if the path does not
-	match ^\\?\.{0,2}/, which will match on /, ./, ../, and \./.
-
-	The paths used to find input files are now passed through
-	the following regular expressions: s:^\\./:: and s:/\\./:/:g.
-	These remove unnecessary searches through the current directory.
-
-	Perl_glob will only return found files and no other type.
-	It will also not follow any directories named `..'.
-
-	Include RRDtool 0.99.29.1 with Orca.  This includes a Makefile
-	patch and does not include a new version of RRDs.pm or librrd.
-
-	In any Makefile.in's that run config.status, they used to run
-	a make from the top level directory.  Now they only run a make
-	from the directory that required the running of config.status.
+	* Orca now cleans up all file paths in the input configuration
+	  file.  If more than one / are found in a row, they are
+	  replaced by one /.  The base_dir is only prepended to paths
+	  if the path does not match ^\\?\.{0,2}/, which will match on
+	  /, ./, ../, and \./.
+
+	* The paths used to find input files are now passed through
+	  the following regular expressions: s:^\\./:: and
+	  s:/\\./:/:g.  These remove unnecessary searches through the
+	  current directory.
+
+	* Perl_glob will only return found files and no other type.
+	  It will also not follow any directories named `..'.
+
+	* Include RRDtool 0.99.29.1 with Orca.  This includes a
+	  Makefile patch and does not include a new version of RRDs.pm
+	  or librrd.
+
+	* In any Makefile.in's that run config.status, they used to
+	  run a make from the top level directory.  Now they only run
+	  a make from the directory that required the running of
+	  config.status.
 
 Tue May 11 16:24:09 PDT 1999
 
-	In places where deep copies of data structures are made and no
-	s///'s are performed on the text form of data, use dclone that
-	comes with Storable instead of using Data::Dumper and eval.
-
-	Do not prepend base_dir to any paths if they begin with either
-	`/' or `./'.
-
-	Require and include RRDtool 0.99.29 with Orca.
-
-	Orca now includes the four Perl packages it depends upon:
-	Digest::MD5 2.07, Math::Interpolate 1.02, RRDtool 0.99.29,
-	and Storable 0.6 at 3.
+	* In places where deep copies of data structures are made and
+	  no s///'s are performed on the text form of data, use dclone
+	  that comes with Storable instead of using Data::Dumper and
+	  eval.
+
+	* Do not prepend base_dir to any paths if they begin with
+	  either `/' or `./'.
+
+	* Require and include RRDtool 0.99.29 with Orca.
+
+	* Orca now includes the four Perl packages it depends upon:
+	  Digest::MD5 2.07, Math::Interpolate 1.02, RRDtool 0.99.29,
+	  and Storable 0.6 at 3.
 
 Mon May 10 10:46:36 PDT 1999
 
-	Update references to Digest::MD5 version 2.07 and require
-	RRDtool 0.99.28.
+	* Update references to Digest::MD5 version 2.07 and require
+	  RRDtool 0.99.28.
 
 Sat May  8 19:29:14 PDT 1999
 
-	Upgrade the instructions to mention Math::Interpolate 1.02
-	instead of Math::Interpolator 1.01.
+	* Upgrade the instructions to mention Math::Interpolate 1.02
+	  instead of Math::Interpolator 1.01.
 
 Thu May  6 13:58:06 PDT 1999
 
-	Orca does not normally display the daily, weekly, monthly,
-	yearly, and everything plots for all the different measurements
-	if there is only one group.  However, it is nice to see all the
-	different measurement plots in one page for a single group, so if
-	now there is only one group, then an Everything group placed at
-	the top of the main index.html file for daily, weekly, monthly,
-	and yearly overviews.
-
-	Make a comment about using gd1.3 versus gd1.2 in INSTALL when
-	building RRDtool.  Because RRDtool comes with gd1.2 and generates
-	smaller GIFs, a comment is made that there is no reason to move
-	to gd1.3.  The bottom line is that gd1.2 is preferred.
-
-	Check if the state file is empty and do not complain if it is.
-
-	Add installation instructions that to install this version
-	of Orca over an older version, a make migrate command will
-	need to be run to renames all files and directories containing
-	percollator, percol, or perc to orcallator in any of the installed
-	Orca directories.
+	* Orca does not normally display the daily, weekly, monthly,
+	  yearly, and everything plots for all the different
+	  measurements if there is only one group.  However, it is
+	  nice to see all the different measurement plots in one page
+	  for a single group, so if now there is only one group, then
+	  an Everything group placed at the top of the main index.html
+	  file for daily, weekly, monthly, and yearly overviews.
+
+	* Make a comment about using gd1.3 versus gd1.2 in INSTALL
+	  when building RRDtool.  Because RRDtool comes with gd1.2 and
+	  generates smaller GIFs, a comment is made that there is no
+	  reason to move to gd1.3.  The bottom line is that gd1.2 is
+	  preferred.
+
+	* Check if the state file is empty and do not complain if it
+	  is.
+
+	* Add installation instructions that to install this version
+	  of Orca over an older version, a make migrate command will
+	  need to be run to renames all files and directories
+	  containing percollator, percol, or perc to orcallator in any
+	  of the installed Orca directories.
 
-	Update orcallator.cfg to look for filenames like
-	orcallator-1999-05-06 and percol-1999-05-06.
+	* Update orcallator.cfg to look for filenames like
+	  orcallator-1999-05-06 and percol-1999-05-06.
 
 Wed May  5 10:43:23 PDT 1999
 
-	Require RRDtool 0.99.27.
+	* Require RRDtool 0.99.27.
 
 Mon May  3 14:51:06 PDT 1999
 
-	Rename everything percollator, perc and percol to orcallator.
+	* Rename everything percollator, perc and percol to
+	  orcallator.
 
 Fri Apr 30 16:34:20 PDT 1999
 
-	Update to install Perl 5.005_03 instead of 5.005_02.
+	* Update to install Perl 5.005_03 instead of 5.005_02.
 
 Fri Apr 23 09:31:28 PDT 1999
 
-	Require RRDtool 0.99.25.
+	* Require RRDtool 0.99.25.
 
 Thu Apr 22 09:21:15 PDT 1999
 
-	Require RRDtool 0.99.24.
+	* Require RRDtool 0.99.24.
 
 Sat Apr 17 12:06:46 PDT 1999
 
-	Change all URLs from
+	* Change all URLs from
 	    http://www.geocities.com/ResearchTriangle/Thinktank/4996/
-	to
+	  to
 	    http://www.geocities.com/~bzking/
 
 Thu Apr  8 17:03:37 PDT 1999
 
-	Require RRDtool 0.99.23.
+	* Require RRDtool 0.99.23.
 
 Wed Mar 31 19:07:41 PST 1999
 
-	When perl_glob cannot open a directory, return an empty
-	array and warn instead of dying.  Fix from J.R. Tietsort
-	<jrtietsort at micron.com>.
+	* When perl_glob cannot open a directory, return an empty
+	  array and warn instead of dying.  Fix from J.R. Tietsort
+	  <jrtietsort at micron.com>.
 
-	Require RRDtool 0.99.22 which contains a memory leak bug fix.
+	* Require RRDtool 0.99.22 which contains a memory leak bug
+	  fix.
 
 Sat Mar 27 10:07:09 PST 1999
 
-	Update references to Digest::MD5 version 2.06 and require
-	RRDtool 0.99.21.
+	* Update references to Digest::MD5 version 2.06 and require
+	  RRDtool 0.99.21.
 
 Thu Mar 25 15:30:00 PST 1999
 
-	Speed up count_proc() in percollator.se by 20% using a patch
-	supplied by Rich Pettit <rpettit at resolute.com>.
+	* Speed up count_proc() in percollator.se by 20% using a patch
+	  supplied by Rich Pettit <rpettit at resolute.com>.
 
 Sat Mar  6 11:50:57 PST 1999
 
-	Update references to Digest::MD5 version 2.04.
+	* Update references to Digest::MD5 version 2.04.
 
 Thu Mar  4 16:42:03 PST 1999
 
-	Require RRDtool 0.99.19.
+	* Require RRDtool 0.99.19.
 
 Mon Mar  1 11:01:01 PST 1999
 
-	Require RRDtool 0.99.18.
+	* Require RRDtool 0.99.18.
 
 Tue Feb 23 09:19:37 PST 1999
 
-	Require RRDtool 0.99.15.
+	* Require RRDtool 0.99.15.
 
-	Die if a unrecognized command line option is given to Orca.
+	* Die if a unrecognized command line option is given to Orca.
 
-	Do group name substitution on the Y legend in GIFs.
+	* Do group name substitution on the Y legend in GIFs.
 
-	Add another consolidation function, DERIVE, to an error message.
+	* Add another consolidation function, DERIVE, to an error
+	  message.
 
-	Change the user, system and idle colors in the CPU usage plot
-	as requested by Alain Swanson <amswanson at micron.com>.
+	* Change the user, system and idle colors in the CPU usage
+	  plot as requested by Alain Swanson <amswanson at micron.com>.
 
-	Change the printing format of usr% and sys% from %4.0f to %5.1f
-	in percollator.se to work around a printing problem reported by
-	Alain Swanson <amswanson at micron.com>.  In SE 3.1 this will now
-	display an extra non-zero digit of measured precision.
+	* Change the printing format of usr% and sys% from %4.0f to
+	  %5.1f in percollator.se to work around a printing problem
+	  reported by Alain Swanson <amswanson at micron.com>.  In SE 3.1
+	  this will now display an extra non-zero digit of measured
+	  precision.
 
-	Always output the header information in percollator.se, even
-	if Orca cannot handle it yet, since the number of columns may
-	change if new hardware is added to the system.
+	* Always output the header information in percollator.se, even
+	  if Orca cannot handle it yet, since the number of columns
+	  may change if new hardware is added to the system.
 
 Mon Feb 22 10:23:21 PST 1999
 
-	Add GIF width and height tags to img src's using the returned
-	GIF size from RRDs::graph.
+	* Add GIF width and height tags to img src's using the
+	  returned GIF size from RRDs::graph.
 
-	Add a space between the ending " for the img src="" and the
-	following alt="" in the generated HTML.
+	* Add a space between the ending " for the img src="" and the
+	  following alt="" in the generated HTML.
 
-	Require RRDtool 0.99.14.
+	* Require RRDtool 0.99.14.
 
-	Add x86 Ethernet device plotting to percollator.cfg.in.
+	* Add x86 Ethernet device plotting to percollator.cfg.in.
 
-	Remove the LAST RRA from all Orca created RRAs since it is not
-	required to get the current value from an RRA.	The current
-	value is obtained by using the LAST consolidation function on
-	the plotted data.
+	* Remove the LAST RRA from all Orca created RRAs since it is
+	  not required to get the current value from an RRA.  The
+	  current value is obtained by using the LAST consolidation
+	  function on the plotted data.
 
 Sun Feb 21 11:03:39 PST 1999
 
-	Make use of RRDtool 0.99.12's legend formatting.
+	* Make use of RRDtool 0.99.12's legend formatting.
 
 Sat Feb 20 20:13:01 PST 1999
 
-	Require RRDtool 0.99.12.
+	* Require RRDtool 0.99.12.
 
 Fri Feb 19 11:55:50 PST 1999
 
-	Move some </a> tags to the end of the image they were referencing
-	to remove some Netscape glitches.
+	* Move some </a> tags to the end of the image they were
+	  referencing to remove some Netscape glitches.
 
-	Minor spelling fix and addition to CHANGES file.
+	* Minor spelling fix and addition to CHANGES file.
 
-	Version 0.20.
+	* Version 0.20.
 
-	Have the Orca logo be a hyperlink to the Orca home page.
+	* Have the Orca logo be a hyperlink to the Orca home page.
 
-	Version 0.19.
+	* Version 0.19.
 
-	Fix a bug in copying SE 3.1's percollator.se changes where it
-	was not skipping the HTTP/1.x code in the NCSA style access log.
-	Now percollator.se can handle log files with or without the code.
+	* Fix a bug in copying SE 3.1's percollator.se changes where
+	  it was not skipping the HTTP/1.x code in the NCSA style
+	  access log.  Now percollator.se can handle log files with or
+	  without the code.
 
 Thu Feb 18 11:54:03 PST 1999
 
-	percollator.se now logs information on integral multiples of
-	the interval.  This is useful for RRD which expects data to be
-	measured on the interval.
-
-	Fix a bug in percollator.se where it was inflating the httpops5
-	number since it was not calculating the actual time interval
-	and instead assuming a 5 second interval.
-
-	Add Squid log processing to percollator.se courtesy of Adrian
-	Cockcroft of Sun Microsystems.
-
-	Rename the configure --with options.  If you want to watch NCSA
-	style access logs, use --with-ncsa-log.  To watch NCSA style
-	proxy access logs, use --with-proxy-log.  And to watch Squid
-	access log, use --with-squid-log.
+	* percollator.se now logs information on integral multiples of
+	  the interval.  This is useful for RRD which expects data to
+	  be measured on the interval.
+
+	* Fix a bug in percollator.se where it was inflating the
+	  httpops5 number since it was not calculating the actual time
+	  interval and instead assuming a 5 second interval.
+
+	* Add Squid log processing to percollator.se courtesy of
+	  Adrian Cockcroft of Sun Microsystems.
+
+	* Rename the configure --with options.  If you want to watch
+	  NCSA style access logs, use --with-ncsa-log.  To watch NCSA
+	  style proxy access logs, use --with-proxy-log.  And to watch
+	  Squid access log, use --with-squid-log.
 
 Wed Feb 17 17:37:35 PST 1999
 
-	Add rrdtool.gif to the GIF files that Orca creates and include
-	a HREF to rrdtool.gif in every HTML file that Orca generates.
+	* Add rrdtool.gif to the GIF files that Orca creates and
+	  include a HREF to rrdtool.gif in every HTML file that Orca
+	  generates.
 
 Tue Feb 16 10:49:07 PST 1999
 
-	Version 0.18.
+	* Version 0.18.
 
-	Minor fixes.
+	* Minor fixes.
 
-	Version 0.17.
+	* Version 0.17.
 
-	Group names are now sorted depending upon the format of the
-	group names.  For example, this now will list nfs13 after nfs5,
-	even though cmp will sort nfs13 before nfs5.
+	* Group names are now sorted depending upon the format of the
+	  group names.  For example, this now will list nfs13 after
+	  nfs5, even though cmp will sort nfs13 before nfs5.
 
-	Created GIFs now print the current measured value in addition
-	to the average measured value.
+	* Created GIFs now print the current measured value in
+	  addition to the average measured value.
 
-	percollator.cfg.in updated to shorten the http and inode with
-	page steals legends to have shorter legends so that RRDtool will
-	plot the whole comment along with the average and last value in
-	the GIF.
+	* percollator.cfg.in updated to shorten the http and inode
+	  with page steals legends to have shorter legends so that
+	  RRDtool will plot the whole comment along with the average
+	  and last value in the GIF.
 
 Mon Feb 15 12:29:18 PST 1999
 
-	Require RRDtool 0.99.11.
+	* Require RRDtool 0.99.11.
 
-	Add versioning information to the DS names created by Orca so new
-	versions of Orca can make older RRD files obsolete.  This feature
-	is now used to make sure that the current measurement using LAST
-	is stored in Orca's RRDs.
+	* Add versioning information to the DS names created by Orca
+	  so new versions of Orca can make older RRD files obsolete.
+	  This feature is now used to make sure that the current
+	  measurement using LAST is stored in Orca's RRDs.
 
 Fri Feb 12 15:10:05 PST 1999
 
-	Require RRDtool 0.99.10.
+	* Require RRDtool 0.99.10.
 
-	When creating a brand new RRD, create new RRAs for the current
-	value measured using the LAST DS type.
+	* When creating a brand new RRD, create new RRAs for the
+	  current value measured using the LAST DS type.
 
 Thu Feb 11 11:48:14 PST 1999
 
-	Require RRDtool 0.99.8.
+	* Require RRDtool 0.99.8.
 
 Thu Feb  4 12:51:54 PST 1999
 
-	Update the installation instructions for SE 3.1 beta.
+	* Update the installation instructions for SE 3.1 beta.
 
 Fri Jan 29 15:38:53 PST 1999
 
-	Require RRDtool 0.99.6.
+	* Require RRDtool 0.99.6.
 
 Thu Jan 28 15:44:07 PST 1999
 
-	If a file uses the first line as a column description and if
-	the following line does not have the same number of columns,
-	then warn and skip that line.
+	* If a file uses the first line as a column description and if
+	  the following line does not have the same number of columns,
+	  then warn and skip that line.
 
-	Require RRDtool 0.99.4.
+	* Require RRDtool 0.99.4.
 
 Tue Jan 26 15:28:26 PST 1999
 
-	Rename Orca::GIFFile::expire_string to
-	Orca::GIFFile::_expire_string.
+	* Rename Orca::GIFFile::expire_string to
+	  Orca::GIFFile::_expire_string.
 
-	Change the default location of the percollator RRDs to be
-	$prefix/var/orca/rrd/percollator instead of $prefix/var/orca/rrd.
+	* Change the default location of the percollator RRDs to be
+	  $prefix/var/orca/rrd/percollator instead of
+	  $prefix/var/orca/rrd.
 
-	Sort the order of RRD files being updated by the RRD's filename.
+	* Sort the order of RRD files being updated by the RRD's
+	  filename.
 
-	Do not make RRD_DIR/percollator
+	* Do not make RRD_DIR/percollator
 
-	Require RRDtool 0.99.2.
+	* Require RRDtool 0.99.2.
 
-	Remove sanity check on group update times that could cause
-	false dies.
+	* Remove sanity check on group update times that could cause
+	  false dies.
 
 Tue Jan 26 10:07:40 PST 1999
 
-	Version 0.16.
+	* Version 0.16.
 
-	Fix a bug in lib/Makefile.in where the variable $(CP) was used
-	but never defined.
+	* Fix a bug in lib/Makefile.in where the variable $(CP) was
+	  used but never defined.
 
-	Fix a bug where watch_data_sources() would do an extra loop each
-	time file updates were looked for.
+	* Fix a bug where watch_data_sources() would do an extra loop
+	  each time file updates were looked for.
 
 Mon Jan 25 15:25:12 PST 1999
 
-	Version 0.15.
+	* Version 0.15.
 
-	Update to use RRDtool 0.99.1.
+	* Update to use RRDtool 0.99.1.
 
-	Rename not_running to percol_running.
+	* Rename not_running to percol_running.
 
-	Update the URL to Tobias Oetiker's RRD web site.
+	* Update the URL to Tobias Oetiker's RRD web site.
 
-	Make sure lib/Makefile does not overwrite old
-	lib/percollator.cfg's when a make install is done.
+	* Make sure lib/Makefile does not overwrite old
+	  lib/percollator.cfg's when a make install is done.
 
 Fri Jan 22 20:17:56 PST 1999
 
-	Create an Orca logo and have the logo appear at the bottom of
-	each HTML file.  The logo is stored as hexadecimal inside the
-	Orca perl script.
+	* Create an Orca logo and have the logo appear at the bottom
+	  of each HTML file.  The logo is stored as hexadecimal inside
+	  the Orca perl script.
 
-	Update percollator.cfg.in to not contain bzajac at geostaff.com
-	any more.  Changed it to root at localhost.
+	* Update percollator.cfg.in to not contain bzajac at geostaff.com
+	  any more.  Changed it to root at localhost.
 
 Thu Jan 21 13:31:50 PST 1999
 
-	Add a configure script to Orca to make installation of Orca and
-	percollator much easier.
+	* Add a configure script to Orca to make installation of Orca
+	  and percollator much easier.
 
-	Add a new file env_percol to set up all the environmental
-	variables so that percollator runs correctly instead of having
-	to edit start_percol, stop_percol, and restart_percol.
+	* Add a new file env_percol to set up all the environmental
+	  variables so that percollator runs correctly instead of
+	  having to edit start_percol, stop_percol, and
+	  restart_percol.
 
 Mon Jan 11 16:58:28 PST 1999
 
-	Require MRTG version 0.04 minimum.  This corresponds to
-	mrtg-19990111.22.
+	* Require MRTG version 0.04 minimum.  This corresponds to
+	  mrtg-19990111.22.
 
 Wed Jan  6 09:47:44 PST 1999
 
-	Version 0.14.
+	* Version 0.14.
 
-	Change the program's name from FMRTG to Orca.
+	* Change the program's name from FMRTG to Orca.
 
-	Change all references of SMRTG to Cricket.
+	* Change all references of SMRTG to Cricket.
 
 Fri Dec 18 13:10:47 PST 1998
 
-	Change all occurances of MRTG in fmrtg to FMRTG.
+	* Change all occurances of MRTG in fmrtg to FMRTG.
 
 Thu Dec 10 16:47:20 PST 1998
 
-	Add percol_column to the list of programs in the percollator
-	directory.  This program makes it easy to read several columns of
-	data from a percollator.se output file instead of trying to look
-	at 1000 character lines that percollator.se generally outputs.
+	* Add percol_column to the list of programs in the percollator
+	  directory.  This program makes it easy to read several
+	  columns of data from a percollator.se output file instead of
+	  trying to look at 1000 character lines that percollator.se
+	  generally outputs.
 
 Thu Dec 10 12:50:19 PST 1998
 
-	Version 0.13.
+	* Version 0.13.
 
-	Found an extra loop in creating the HTML files.  They are now
-	created much faster.
+	* Found an extra loop in creating the HTML files.  They are
+	  now created much faster.
 
-	Add HREFs to the top of the HTML files showing plots from
-	different groups and different data types to make jumping
-	around easier.
+	* Add HREFs to the top of the HTML files showing plots from
+	  different groups and different data types to make jumping
+	  around easier.
 
-	Add more documentation to &create_html_files.
+	* Add more documentation to &create_html_files.
 
-	Add some documentation describing why Digest::MD5 is used.
+	* Add some documentation describing why Digest::MD5 is used.
 
 Wed Dec  9 13:35:07 PST 1998
 
-	Add more documentation to fmrtg and percollator about setting
-	up FMRTG and percollator.se to work together.
+	* Add more documentation to fmrtg and percollator about
+	  setting up FMRTG and percollator.se to work together.
 
 Wed Dec  9 09:55:01 PST 1998
 
-	Version 0.12.
+	* Version 0.12.
 
-	Correct incorrect URL for Digest::MD5 in fmrtg.
+	* Correct incorrect URL for Digest::MD5 in fmrtg.
 
 Tue Dec  8 12:12:07 PST 1998
 
-	Version 0.11.
+	* Version 0.11.
 
-	Update the sample FMRTG configuration files to work properly
-	with the configuration options in FMRTG.
+	* Update the sample FMRTG configuration files to work properly
+	  with the configuration options in FMRTG.
 
-	Switch from MD5 to Digest::MD5, since it is faster.
+	* Switch from MD5 to Digest::MD5, since it is faster.
 
-	Update the documentation to reflect the above changes.
+	* Update the documentation to reflect the above changes.
 
-	Update the code documentation in fmrtg for date_source.
+	* Update the code documentation in fmrtg for date_source.
 
-	Add some more documentation to the percollator/start_percol
-	script.
+	* Add some more documentation to the percollator/start_percol
+	  script.
 
 Fri Dec  4 14:34:13 PST 1998
 
-	Version 0.10.
+	* Version 0.10.

Modified: trunk/orca/NEWS
==============================================================================
--- trunk/orca/NEWS	(original)
+++ trunk/orca/NEWS	Sat Jul 13 21:25:47 2002
@@ -1,3 +1,184 @@
+NEW IN ORCA 0.27b1
+==================
+
+ 1) By default, now create an hourly plot that shows the last 1.5
+    hours of data.  Add a global "generate_hourly_plot" configuration
+    file parameter that when set to 0 turns this plot off.  Hourly
+    plot creation is disabled in orcallator.cfg.in since orcallator.se
+    by default measures the system every 5 minutes and the plots look
+    blocky.
+
+ 2) Fix the warning message in src/orca.pl.in
+
+      Use on uninitialized value in array element at (eval X) line 1,
+      <DATA> line Y
+
+    when Orca was run with Perl 5.6.0.  This bug was in the filename
+    sorting subroutine.
+
+    This problem is probably responsible for problems where there are
+    missing data from generated plots.  Since the filename sorting
+    subroutine tells Orca the order in which to load data into the RRD
+    files and the sorted filename list will have newer data files
+    listed before older data files, once newer data is entered into an
+    RRD file you cannot add older data, resulting in missing data in
+    the output plots.
+
+    If this is a problem, then the solution is to remove the RRD files
+    and rerun Orca with all of the input data files.
+
+ 3) Add a new command line option named -no-images which suppresses
+    image generation.  Remove the command line option -r which told
+    Orca to only update the RRD files and not generate HTML and image
+    files.  To replace -r functionality, use both -no-images and
+    -no-html command line options.
+
+ 4) Add a new command line option -no-html to instruct Orca to skip
+    generating HTML files.  Patch from Alex Howansky
+    <alex at wankwood.com>.
+
+ 5) Add a new command line option -logfile that specifies a filename
+    that STDOUT and STDERR are redirected to so that all messages,
+    warnings and errors are printed to the file.  Now when a SIGPIPE
+    is caught, messages will continue to be printed unless -logfile
+    was not given to Orca.  Patch supplied by Bruce Johnson
+    <Bruce.Johnson at PictureVision.com>.
+
+ 6) Add a new command line option -daemon that puts Orca in the
+    background or daemonizes it.  It is recommended that when this
+    command line option is used that -logfile is used.  Patch supplied
+    by Bruce Johnson <Bruce.Johnson at PictureVision.com>.
+
+ 7) A new contrib directory has been created which is where
+    contributed scripts and programs will be kept.  The first
+    submissions are:
+
+    a) Include the orcaservices package in the contrib directory which
+       was written by Carlos Canau <Carlos.Canau at KPNQwest.pt> and
+       documented by Jose Carlos <jcp at KPNQwest.pt>.  This package
+       allows monitoring of many different types of Unix services,
+       such as DNS, SMTP, POP, etc.
+
+    b) A script to rotate Orca's HTML directory so that the daily
+       plots can be archived.  It is named rotate_orca_graphs.
+
+ 8) Replace the small color scheme used for automatically cycling
+    through plot colors with a longer list designed by Guy Dallaire
+    <gdallair-nospam at criq.qc.ca>.
+
+ 9) To support configurations where it does not make sense to make all
+    of the hourly, daily, weekly, monthly, quarterly, and yearly
+    plots, i.e.  when only one measurement per day is made and having
+    a daily plot would not show anything, Orca now understands the
+    global configuration file options "generate_hourly_plot",
+    "generate_daily_plot", "generate_weekly_plot",
+    "generate_monthly_plot", "generate_quarterly_plot", and
+    "generate_yearly_plot".  When an argument value of 0 is given to
+    the parameter, the plot is not created.  If the particular
+    parameter is not used or the value is not 0, then the plot is
+    created.
+
+10) Add a new configuration file option for plots named
+    "summary_format" which specifies the format for the summary values
+    as passed to the RRDtool GPRINT function.  The same format is used
+    for each number within a single summary line, but you can specify
+    multiple "summary_format"'s options if there are multiple plots on
+    the graph.  The default value, which has not changed from previous
+    Orca versions, is '%9.3lf %S'.  Patch from Alex Howansky
+    <alex at wankwood.com>.
+
+11) Remove the "date_format" configuration option as it was never
+    supported.  This is replaced by a new "date_parse" configuration
+    file parameter which supports converting arbitrary strings in the
+    input source data files that somehow represent time into an Unix
+    epoch time usable by Orca.  The "date_parse" parameter appears in
+    a group field and is an arbitrary Perl subroutine that is given
+    two arguments, the first being the name of the file where the data
+    is loaded and the second the string from the "date_source" column
+    that contains some time information.  The subroutine should return
+    the Unix epoch time.  If this option is not specified, then Orca
+    assumes that the string holds the Unix epoch time.
+
+    This Perl subroutine is only used if the file's date source is not
+    specified to be the file's last modified time as indicated to Orca
+    by use of the "date_source" file_mtime configuration file option.
+
+12) Remove the "sub_dir" configuration file parameter and now always
+    create sub directories for RRD, image and HTML files.  This
+    removes the problem when a simple Orca configuration file was used
+    and Orca did not create subdirectories and then additional groups
+    where added to the configuration file Orca would begin to use
+    subdirectories and the existing RRD, image and HTML files would be
+    in the wrong location.  In this case, Orca would reload all of the
+    input data.
+
+13) Allow the "late_interval" configuration parameter to appear in a
+    configuration file group.  If it does not appear in a group
+    listing, then use the global "late_interval" value.
+
+14) Add a new configuration file option named "require" that allows
+    the configuration file to specify the minimum required version of
+    Orca.
+
+15) Orca now catches SIGPIPEs so the lock directory is properly
+    removed when Orca's STDOUT and/or STDERR is piped to a process,
+    such as less, and the piped to process exits before Orca does.
+
+16) Fix a bug where Orca's documentation stated that the configuration
+    file can specify different data_min, data_max, and data_type's for
+    each data in a plot but the code did not.  Make the modifications
+    in Orca to support this feature.
+
+17) When loading a configuration file, now do a complete check of it
+    for errors before quitting, instead of quitting after a single
+    error.
+
+18) Include and require the following package updates: Digest::MD5
+    2.13, RRDtool 1.0.33 and Storable 1.0.11.
+
+19) The email address blair at akamai.com that I used no longer works, as
+    I have left Akamai.  I can be reached at blair at gps.caltech.edu.
+
+    These following changes are what's new in orcallator.se 1.28 and
+    the orcallator.cfg file since version 1.23 which was included with
+    Orca 0.26.  All of the changes below are taken advantage of in the
+    included orcallator.cfg and start_orcallator files.
+
+20) When orcallator.se was running on a system with an older version
+    of SE the p_vmstat.scan variable is an integer and the sprintf to
+    %8.3f fails, resulting in a perceived scan rate of 0 pages per
+    second.  Now always add 0.0 to p_vmstat.scan to get a double.
+
+21) Fix a typo where nil was misspelled as nik.
+
+22) Make sure to check the return from stat() on the web server access
+    log in case the file is missing.  Use fstat() instead of stat()
+    when a file descriptor is available.
+
+23) Print the portion of time running in idle mode with some process
+    waiting for block I/O as wio% and otherwise completely idle time
+    as idle%.  Update orcallator.cfg.in to fix a bug in plotting the
+    CPU usage plots where the idle% time was calculated by subtracting
+    the user percent time usr% and the system percent time sys% from
+    100%.  This did not take into account the wait on IO time wio%
+    that the system measures and hence the idle% was overestimated.
+    Now plot the correct idle% and the wio%.
+
+24) Recoded measure_disk() to access the RAWDISK interface to
+    sys_kstat device information to allow the activity on Sun's A1000
+    and Clariion Raid controller drives to be seen.  Apparently the
+    pseudo drivers do not update the kstat interface.  It is also
+    inverts the fix provided by version 1.23 to avoid over-counting md
+    devices.  By suppressing stats from slices and metadevices and
+    instead reporting on full devices such as c0t0d0 or sd0.  Note:
+    This may have introduced an interaction with the live_rules.se
+    class monitoring of drive performance.  Prevent floppy disks and
+    tape drives from RAWDISK.  Added wio% to measure wait time since
+    the idle calculation is wrong without this.  Prevent filesystems
+    mounted under /snapshots from being seen.  Patch contributed by
+    Alan LeGrand <alegrand at wallace.com>.
+
+
 NEW IN ORCA 0.26
 ================
 
@@ -10,7 +191,7 @@
     exist and the first line of the file is used to tell Orca what
     columns of data there are.  Now Orca caches this information in
     the state file so that the source data files do no have to be
-    opened everytime Orca starts up.  This has a significant speed
+    opened every time Orca starts up.  This has a significant speed
     improvement when the file is compressed, since a separate process
     is normally spawned to read the file.
 
@@ -67,7 +248,7 @@
     types of NFS calls, such as getattr and lookup, are not included.
     Contributed by Paul Haldane <Paul.Haldane at newcastle.ac.uk>.  This
     code is enabled by the standard -DWATCH_OS or individually by
-    -DWATCH_NFS_SERVER.  The define -DWATCH_NFS has been supperseded
+    -DWATCH_NFS_SERVER.  The define -DWATCH_NFS has been superseded
     by -DWATCH_NFS_CLIENT, but to keep backwards compatibility,
     -DWATCH_NFS_CLIENT will be defined if -DWATCH_NFS is defined.
 
@@ -75,11 +256,12 @@
     physical disk was listed multiple times when it appeared in the
     same metadevice.  The solution to the problem is not to build the
     c0t0d0 name but use the long disk name provided by the long_name
-    string. Patch contributed by Paul Haldane
+    string.  Patch contributed by Paul Haldane
     <Paul.Haldane at newcastle.ac.uk>.
 
 14) Prevent core dumps on extremely long access log lines.
 
+
 NEW IN ORCA 0.25
 ================
 
@@ -105,9 +287,9 @@
  5) The previous default orcallator.cfg would not find compressed
     orcallator files.
 
- 6) Remove the plot configuration option `optional' which made plots
+ 6) Remove the plot configuration option "optional" which made plots
     optional.  Now make plots optional by default and use the keyword
-    `required' to make them required.  If a plot is required, then it
+    "required" to make them required.  If a plot is required, then it
     will always display, even if there is no data loaded for it.
 
  7) Change the behavior of warnings when data requested to be plotted
@@ -119,6 +301,7 @@
  8) Include Storable 0.6.7 but continue to only require Storable
     0.6.3.
 
+
 NEW IN ORCA 0.24
 ================
 
@@ -164,7 +347,7 @@
     view existing pages until the new page is completely finished.
 
 11) All generated HTML and image filenames are now created using a
-   different set of mappings.  Now
+    different set of mappings.  Now
       orcallator -> o
       orca       -> o
       _times_    -> _X_
@@ -258,6 +441,7 @@
 24) Restructure the code to handle different web server access log
     formats easier.
 
+
 NEW IN ORCA 0.23
 ================
 
@@ -265,6 +449,7 @@
     which where using old PERCOLLATOR_DIR variables instead of the new
     ORCALLATOR_DIR.
 
+
 NEW IN ORCA 0.22
 ================
 
@@ -292,14 +477,15 @@
  6) Added some more documentation to orcallator.cfg.
 
  7) Make Orca slightly faster.
- 
+
+
 NEW IN ORCA 0.21
 ================
 
  1) Every file containing the words percollator, percol and perc has
     been renamed to contain the word orcallator.  A new make target
     named migrate will change all filenames in an installed Orca
-    directory to the new names.  This `make migrate' should only be
+    directory to the new names.  This "make migrate" should only be
     run after killing any running percollator.se's and Orca processes
     and before installing this version of Orca.
 
@@ -346,9 +532,9 @@
     regular expressions.
 
 14) Change all references from
-    http://www.geocities.com/ResearchTriangle/Thinktank/4996/
+      http://www.geocities.com/ResearchTriangle/Thinktank/4996/
     to
-    http://www.geocities.com/~bzking/
+      http://www.geocities.com/~bzking/
 
 15) Speed up Orca by using Storable to do deep clones of objects
     instead of using Data::Dumper and eval.

Modified: trunk/orca/packages/Makefile.in
==============================================================================
--- trunk/orca/packages/Makefile.in	(original)
+++ trunk/orca/packages/Makefile.in	Sat Jul 13 21:25:47 2002
@@ -5,6 +5,7 @@
 
 compress_zlib_dir		= @COMPRESS_ZLIB_DIR@
 data_dumper_dir			= @DATA_DUMPER_DIR@
+date_parse_dir			= @DATE_PARSE_DIR@
 digest_md5_dir			= @DIGEST_MD5_DIR@
 math_interpolate_dir		= @MATH_INTERPOLATE_DIR@
 rrdtool_dir			= @RRDTOOL_DIR@
@@ -12,46 +13,51 @@
 
 MAKE_COMPRESS_ZLIB		= @MAKE_COMPRESS_ZLIB@
 MAKE_DATA_DUMPER		= @MAKE_DATA_DUMPER@
+MAKE_DATE_PARSE			= @MAKE_DATE_PARSE@
 MAKE_DIGEST_MD5			= @MAKE_DIGEST_MD5@
 MAKE_MATH_INTERPOLATE		= @MAKE_MATH_INTERPOLATE@
 MAKE_RRDTOOL			= @MAKE_RRDTOOL@
 MAKE_STORABLE			= @MAKE_STORABLE@
-MAKE_TARGETS			= $(MAKE_COMPRESS_ZLIB) $(MAKE_DATA_DUMPER) $(MAKE_DIGEST_MD5) $(MAKE_MATH_INTERPOLATE) $(MAKE_RRDTOOL) $(MAKE_STORABLE)
+MAKE_TARGETS			= $(MAKE_COMPRESS_ZLIB) $(MAKE_DATA_DUMPER) $(MAKE_DATE_PARSE) $(MAKE_DIGEST_MD5) $(MAKE_MATH_INTERPOLATE) $(MAKE_RRDTOOL) $(MAKE_STORABLE)
 
 TEST_COMPRESS_ZLIB		= @TEST_COMPRESS_ZLIB@
 TEST_DATA_DUMPER		= @TEST_DATA_DUMPER@
+TEST_DATE_PARSE			= @TEST_DATE_PARSE@
 TEST_DIGEST_MD5			= @TEST_DIGEST_MD5@
 TEST_MATH_INTERPOLATE		= @TEST_MATH_INTERPOLATE@
 TEST_RRDTOOL			= @TEST_RRDTOOL@
 TEST_STORABLE			= @TEST_STORABLE@
-TEST_TARGETS			= $(TEST_COMPRESS_ZLIB) $(TEST_DATA_DUMPER) $(TEST_DIGEST_MD5) $(TEST_MATH_INTERPOLATE) $(TEST_RRDTOOL) $(TEST_STORABLE)
+TEST_TARGETS			= $(TEST_COMPRESS_ZLIB) $(TEST_DATA_DUMPER) $(TEST_DATE_PARSE) $(TEST_DIGEST_MD5) $(TEST_MATH_INTERPOLATE) $(TEST_RRDTOOL) $(TEST_STORABLE)
 
 INSTALL_PERL_COMPRESS_ZLIB	= @INSTALL_PERL_COMPRESS_ZLIB@
 INSTALL_PERL_DATA_DUMPER	= @INSTALL_PERL_DATA_DUMPER@
+INSTALL_PERL_DATE_PARSE		= @INSTALL_PERL_DATE_PARSE@
 INSTALL_PERL_DIGEST_MD5		= @INSTALL_PERL_DIGEST_MD5@
 INSTALL_PERL_MATH_INTERPOLATE	= @INSTALL_PERL_MATH_INTERPOLATE@
 INSTALL_PERL_RRDTOOL		= @INSTALL_PERL_RRDTOOL@
 INSTALL_PERL_STORABLE		= @INSTALL_PERL_STORABLE@
-INSTALL_PERL_TARGETS		= $(INSTALL_PERL_COMPRESS_ZLIB) $(INSTALL_PERL_DATA_DUMPER) $(INSTALL_PERL_DIGEST_MD5) $(INSTALL_PERL_MATH_INTERPOLATE) $(INSTALL_PERL_RRDTOOL) $(INSTALL_PERL_STORABLE)
+INSTALL_PERL_TARGETS		= $(INSTALL_PERL_COMPRESS_ZLIB) $(INSTALL_PERL_DATA_DUMPER) $(INSTALL_PERL_DATE_PARSE) $(INSTALL_PERL_DIGEST_MD5) $(INSTALL_PERL_MATH_INTERPOLATE) $(INSTALL_PERL_RRDTOOL) $(INSTALL_PERL_STORABLE)
 
 INSTALL_LIB_RRDTOOL		= @INSTALL_LIB_RRDTOOL@
 INSTALL_LIB_TARGETS		= $(INSTALL_LIB_RRDTOOL)
 
 CLEAN_COMPRESS_ZLIB		= @CLEAN_COMPRESS_ZLIB@
 CLEAN_DATA_DUMPER		= @CLEAN_DATA_DUMPER@
+CLEAN_DATE_PARSE		= @CLEAN_DATE_PARSE@
 CLEAN_DIGEST_MD5		= @CLEAN_DIGEST_MD5@
 CLEAN_MATH_INTERPOLATE		= @CLEAN_MATH_INTERPOLATE@
 CLEAN_RRDTOOL			= @CLEAN_RRDTOOL@
 CLEAN_STORABLE			= @CLEAN_STORABLE@
-CLEAN_TARGETS			= $(CLEAN_COMPRESS_ZLIB) $(CLEAN_DIGEST_MD5) $(CLEAN_MATH_INTERPOLATE) $(CLEAN_RRDTOOL) $(CLEAN_STORABLE)
+CLEAN_TARGETS			= $(CLEAN_COMPRESS_ZLIB) $(CLEAN_DATA_DUMPER) $(CLEAN_DATE_PARSE) $(CLEAN_DIGEST_MD5) $(CLEAN_MATH_INTERPOLATE) $(CLEAN_RRDTOOL) $(CLEAN_STORABLE)
 
 DISTCLEAN_COMPRESS_ZLIB		= @DISTCLEAN_COMPRESS_ZLIB@
 DISTCLEAN_DATA_DUMPER		= @DISTCLEAN_DATA_DUMPER@
+DISTCLEAN_DATE_PARSE		= @DISTCLEAN_DATE_PARSE@
 DISTCLEAN_DIGEST_MD5		= @DISTCLEAN_DIGEST_MD5@
 DISTCLEAN_MATH_INTERPOLATE	= @DISTCLEAN_MATH_INTERPOLATE@
 DISTCLEAN_RRDTOOL		= @DISTCLEAN_RRDTOOL@
 DISTCLEAN_STORABLE		= @DISTCLEAN_STORABLE@
-DISTCLEAN_TARGETS		= $(DISTCLEAN_COMPRESS_ZLIB) $(DISTCLEAN_DATA_DUMPER) $(DISTCLEAN_DIGEST_MD5) $(DISTCLEAN_MATH_INTERPOLATE) $(DISTCLEAN_RRDTOOL) $(DISTCLEAN_STORABLE)
+DISTCLEAN_TARGETS		= $(DISTCLEAN_COMPRESS_ZLIB) $(DISTCLEAN_DATA_DUMPER) $(DISTCLEAN_DATE_PARSE) $(DISTCLEAN_DIGEST_MD5) $(DISTCLEAN_MATH_INTERPOLATE) $(DISTCLEAN_RRDTOOL) $(DISTCLEAN_STORABLE)
 
 all:	Makefile $(MAKE_TARGETS)
 
@@ -67,6 +73,12 @@
 $(data_dumper_dir)/Makefile: $(data_dumper_dir)/Makefile.PL $(PERL)
 	cd $(data_dumper_dir) && $(PERL) Makefile.PL
 
+make_date_parse: $(date_parse_dir)/Makefile
+	cd $(date_parse_dir) && $(MAKE) OPTIMIZE="$(CFLAGS)"
+
+$(date_parse_dir)/Makefile: $(date_parse_dir)/Makefile.PL $(PERL)
+	cd $(date_parse_dir) && $(PERL) Makefile.PL
+
 make_digest_md5: $(digest_md5_dir)/Makefile
 	cd $(digest_md5_dir) && $(MAKE) OPTIMIZE="$(CFLAGS)"
 
@@ -85,8 +97,11 @@
 make_rrdtool_zlib: $(rrdtool_dir)/Makefile $(PERL)
 	cd $(rrdtool_dir) && $(MAKE) CFLAGS="$(CFLAGS)" zlib-1.1.3/librrd_z.a
 
-$(rrdtool_dir)/Makefile: $(rrdtool_dir)/Makefile.in
-	cd .. && ./configure @CONFIGURE_COMMAND_LINE@
+$(rrdtool_dir)/Makefile: $(rrdtool_dir)/config.status $(rrdtool_dir)/Makefile.in
+	cd $(rrdtool_dir) && CONFIG_FILES=Makefile ./config.status
+
+$(rrdtool_dir)/config.status:
+	cd $(rrdtool_dir) && ./configure @RRD_CONFIGURE_COMMAND_LINE@
 
 make_storable: $(storable_dir)/Makefile
 	cd $(storable_dir) && $(MAKE) OPTIMIZE="$(CFLAGS)"
@@ -104,6 +119,9 @@
 test_data_dumper: $(data_dumper_dir)/Makefile
 	cd $(data_dumper_dir) && $(MAKE) OPTIMIZE="$(CFLAGS)" test
 
+test_date_parse: $(date_parse_dir)/Makefile
+	cd $(date_parse_dir) && $(MAKE) OPTIMIZE="$(CFLAGS)" test
+
 test_digest_md5: $(digest_md5_dir)/Makefile
 	cd $(digest_md5_dir) && $(MAKE) OPTIMIZE="$(CFLAGS)" test
 
@@ -129,6 +147,9 @@
 install_perl_data_dumper: $(data_dumper_dir)/Makefile
 	cd $(data_dumper_dir) && $(MAKE) OPTIMIZE="$(CFLAGS)" install
 
+install_perl_date_parse: $(date_parse_dir)/Makefile
+	cd $(date_parse_dir) && $(MAKE) OPTIMIZE="$(CFLAGS)" install
+
 install_perl_digest_md5: $(digest_md5_dir)/Makefile
 	cd $(digest_md5_dir) && $(MAKE) OPTIMIZE="$(CFLAGS)" install
 
@@ -148,7 +169,19 @@
 		echo 'cd $(compress_zlib_dir) && $(MAKE) clean';	\
 		(cd $(compress_zlib_dir) && $(MAKE) clean);		\
 	fi
-	
+
+clean_data_dumper:
+	@if test -r $(data_dumper_dir)/Makefile; then 			\
+		echo 'cd $(data_dumper_dir) && $(MAKE) clean';		\
+		(cd $(data_dumper_dir) && $(MAKE) clean);		\
+	fi
+
+clean_date_parse:
+	@if test -r $(date_parse_dir)/Makefile; then 			\
+		echo 'cd $(date_parse_dir) && $(MAKE) clean';		\
+		(cd $(date_parse_dir) && $(MAKE) clean);		\
+	fi
+
 clean_digest_md5:
 	@if test -r $(digest_md5_dir)/Makefile; then 			\
 		echo 'cd $(digest_md5_dir) && $(MAKE) clean';		\
@@ -175,6 +208,10 @@
 
 distclean_compress_zlib:	clean_compress_zlib
 
+distclean_data_dumper:		clean_data_dumper
+
+distclean_date_parse:		clean_date_parse
+
 distclean_digest_md5:		clean_digest_md5
 
 distclean_math_interpolate:	clean_math_interpolate
@@ -186,4 +223,3 @@
 
 Makefile: Makefile.in
 	cd .. && CONFIG_FILES=packages/Makefile ./config.status
-	$(MAKE)

Modified: trunk/orca/packages/Digest-MD5-2.13/MD5.pm
==============================================================================
--- trunk/orca/packages/Digest-MD5-2.13/MD5.pm	(original)
+++ trunk/orca/packages/Digest-MD5-2.13/MD5.pm	Sat Jul 13 21:25:47 2002
@@ -3,7 +3,7 @@
 use strict;
 use vars qw($VERSION @ISA @EXPORT_OK);
 
-$VERSION = '2.09';  # $Date: 1999/08/05 23:24:05 $
+$VERSION = '2.13';  # $Date: 2001/03/14 05:50:15 $
 
 require Exporter;
 *import = \&Exporter::import;
@@ -11,9 +11,20 @@
 
 require DynaLoader;
 @ISA=qw(DynaLoader);
-Digest::MD5->bootstrap($VERSION);
 
-*reset = \&new;
+eval {
+    Digest::MD5->bootstrap($VERSION);
+};
+if ($@) {
+    # Try to load the pure perl version
+    require Digest::Perl::MD5;
+
+    Digest::Perl::MD5->import(qw(md5 md5_hex md5_base64));
+    push(@ISA, "Digest::Perl::MD5");  # make OO interface work
+}
+else {
+    *reset = \&new;
+}
 
 1;
 __END__
@@ -30,7 +41,6 @@
  $digest = md5($data);
  $digest = md5_hex($data);
  $digest = md5_base64($data);
-    
 
  # OO style
  use Digest::MD5;
@@ -111,6 +121,9 @@
 message we calculate the digest for.  The return value is the $md5
 object itself.
 
+In most cases you want to make sure that the $io_handle is set up to
+be in binmode().
+
 =item $md5->digest
 
 Return the binary digest for the message.
@@ -202,7 +215,7 @@
 This library is free software; you can redistribute it and/or
 modify it under the same terms as Perl itself.
 
- Copyright 1998-1999 Gisle Aas.
+ Copyright 1998-2000 Gisle Aas.
  Copyright 1995-1996 Neil Winton.
  Copyright 1991-1992 RSA Data Security, Inc.
 
@@ -246,6 +259,6 @@
 The original MD5 interface was written by Neil Winton
 (C<N.Winton at axion.bt.co.uk>).
 
-This release was made by Gisle Aas <gisle at aas.no>
+This release was made by Gisle Aas <gisle at ActiveState.com>
 
 =cut

Modified: trunk/orca/packages/Digest-MD5-2.13/t/files.t
==============================================================================
--- trunk/orca/packages/Digest-MD5-2.13/t/files.t	(original)
+++ trunk/orca/packages/Digest-MD5-2.13/t/files.t	Sat Jul 13 21:25:48 2002
@@ -7,10 +7,10 @@
 # This is the output of: 'md5sum Changes README MD5.pm MD5.xs rfc1321.txt'
 #
 my $EXPECT = <<EOT;
-b9071b32f32f43369a924eccf577d9c3  Changes
-95b8301e390d5a12ea5a544e9dfa89a0  README
-59a47ddf31ab471af4e4ab644fde3338  MD5.pm
-709a74b880357389287af3c9936f97a4  MD5.xs
+832bac36f489f93a3d6dadd20d55b105  Changes
+e2447354c8b24340bc49e38f8d00bf3b  README
+dcc1f89cf6144d81e5f9d291d9849ef1  MD5.pm
+61debd0ec12e131e1ba220e2f3ad2d26  MD5.xs
 754b9db19f79dbc4992f7166eb0f37ce  rfc1321.txt
 EOT
 

Deleted: trunk/orca/packages/Digest-MD5-2.13/t/digest.t

Deleted: trunk/orca/packages/Digest-MD5-2.13/t/rfc2202.t

Deleted: trunk/orca/packages/Digest-MD5-2.13/t/md5.t

Modified: trunk/orca/packages/Digest-MD5-2.13/MANIFEST
==============================================================================
--- trunk/orca/packages/Digest-MD5-2.13/MANIFEST	(original)
+++ trunk/orca/packages/Digest-MD5-2.13/MANIFEST	Sat Jul 13 21:25:48 2002
@@ -1,41 +1,13 @@
 README			Guess what?
 MANIFEST		This file
-MD2/MD2.pm		Digest::MD2 Perl Module
-MD2/MD2.xs		MD2 XS implementation
-MD2/Makefile.PL		Perl Makefile builder
-MD2/rfc1319.txt		The MD2 Message-Digest Algorithm
-MD2/t/badfile.t         Try addfile() on unopened file
-MD2/t/md2.t		Test if Digest::MD2 works
-MD2/typemap		Supplementary typemap
 MD5.pm			Digest::MD5 Perl Module
 hints/dec_osf.pl	Workaround for DEC compiler bug
 hints/irix_6.pl		Workaround for IRIX compiler bug
-lib/MD5.pm		MD5 backwards compatibility stuff
-lib/Digest.pm		Loading frontend
-lib/Digest/HMAC.pm      HMAC implementation
-lib/Digest/HMAC_MD5.pm  HMAC using MD5
-lib/Digest/HMAC_SHA1.pm HMAC using SHA-1
 MD5.xs			MD5 Perl 'XS' source file
 typemap			Supplementary typemap
 Makefile.PL		Perl Makefile builder
-SHA1/Makefile.PL	Perl Makefile builder
-SHA1/SHA1.pm		Digest::SHA1 module
-SHA1/SHA1.xs		SHA-1 XS implementation
-SHA1/fip180-1.gif       SHA-1 specification illustration
-SHA1/fip180-1.html      SHA-1 specification
-SHA1/lib/SHA.pm		SHA backwards compatibility stuff
-SHA1/t/badfile.t        Try addfile() on unopened file
-SHA1/t/sha.t		Uwe's old test
-SHA1/t/sha1.t		Test if Digest::SHA1 works
-SHA1/typemap		Supplementary typemap
 rfc1321.txt		The MD5 Message-Digest Algorithm
-rfc2104.txt		HMAC: Keyed-Hashing for Message Authentication
 t/badfile.t             Try addfile() on unopened file
-t/digest.t		Test Digest.pm loader
 t/files.t		Check a few files.
-t/md5.t			Test suite using standard Perl conventions
 t/md5-aaa.t		Exercise padding code
-t/rfc2202.t		Test Cases for HMAC-MD5 and HMAC-SHA-1
 Changes			Version history
-examples/mddriver.pl	Example driver script after mddriver.c in RFC 1321
-examples/twdigest.pl	Example code to format a digest like Tripwire

Modified: trunk/orca/packages/Digest-MD5-2.13/Changes
==============================================================================
--- trunk/orca/packages/Digest-MD5-2.13/Changes	(original)
+++ trunk/orca/packages/Digest-MD5-2.13/Changes	Sat Jul 13 21:25:48 2002
@@ -1,3 +1,42 @@
+2001-03-13   Gisle Aas <gisle at ActiveState.com>
+
+   Release 2.13
+
+   Moved all other Digest:: modules out of the Digest-MD5 dist.
+
+
+
+2000-09-18   Gisle Aas <gisle at ActiveState.com>
+
+   Release 2.12
+
+   Avoid pointer cast warning for machines with bigger ints
+   than pointers.  Patch by Robin Barker <rmb1 at cise.npl.co.uk>.
+
+
+
+2000-08-19   Gisle Aas <gisle at ActiveState.com>
+
+   Release 2.11
+   
+   The fallback code introduced in 2.10 did only work for
+   perl-5.6.0.  It should now for for perl5.004 and 5.005
+   as well.  Patch by Ville Skyttä <ville at office.popsystems.com>.
+
+
+
+2000-08-18   Gisle Aas <gisle at ActiveState.com>
+
+   Release 2.10
+
+   Digest::MD5 will now try to fallback to the pure perl
+   implementation of Digest::Perl::MD5 if bootstrap fails.
+
+   Added a bit internal paranoia about casting the IV
+   in the Digest::MD5 object to the MD5_CTX* pointer.
+
+
+
 1999-08-06   Gisle Aas <gisle at aas.no>
 
    Release 2.09

Modified: trunk/orca/packages/Digest-MD5-2.13/README
==============================================================================
--- trunk/orca/packages/Digest-MD5-2.13/README	(original)
+++ trunk/orca/packages/Digest-MD5-2.13/README	Sat Jul 13 21:25:48 2002
@@ -1,25 +1,12 @@
-Digest::*
----------
+The Digest::MD5 module allows you to use the RSA Data Security
+Inc. MD5 Message Digest algorithm from within Perl programs.  The
+algorithm takes as input a message of arbitrary length and produces as
+output a 128-bit "fingerprint" or "message digest" of the input.
+MD5 is described in RFC 1321.
 
-This package contains Perl extension interfaces for the following
-message digest algorithms:
+You will need perl version 5.004 or better to install this module.
 
-  - RSA Data Security Inc. MD5   (RFC 1321)
-  - RSA Data Security Inc. MD2   (RFC 1319)
-  - NIST SHA-1                   (FIPS PUB 180-1)
-
-Modules to calculate HMAC (RFC 2104) digests are also provided.
-
-To build the extensions, unpack this distribution somewhere, create
-the Makefile by running 'perl Makefile.PL' and do a 'make', 'make
-test', and if successful 'make install'.
-
-You will need perl version 5.004 or better to install these modules.
-Further documentation is embedded in the individual modules.
-
-Copyright 1998-1999 Gisle Aas.
-Copyright 1998 Graham Barr.
-Copyright 1997 Uwe Hollerbach.
+Copyright 1998-2001 Gisle Aas.
 Copyright 1995-1996 Neil Winton.
 Copyright 1990-1992 RSA Data Security, Inc.
 

Modified: trunk/orca/packages/Digest-MD5-2.13/MD5.xs
==============================================================================
--- trunk/orca/packages/Digest-MD5-2.13/MD5.xs	(original)
+++ trunk/orca/packages/Digest-MD5-2.13/MD5.xs	Sat Jul 13 21:25:48 2002
@@ -1,10 +1,10 @@
-/* $Id: MD5.xs,v 1.24 1999/07/28 10:38:50 gisle Exp $ */
+/* $Id: MD5.xs,v 1.26 2000/09/18 14:27:44 gisle Exp $ */
 
 /* 
  * This library is free software; you can redistribute it and/or
  * modify it under the same terms as Perl itself.
  * 
- *  Copyright 1998 Gisle Aas.
+ *  Copyright 1998-2000 Gisle Aas.
  *  Copyright 1995-1996 Neil Winton.
  *  Copyright 1991-1992 RSA Data Security, Inc.
  *
@@ -92,10 +92,12 @@
                         ((U32)(*(s+3)) << 24))
 #endif
 
+#define MD5_CTX_SIGNATURE 200003165
 
 /* This stucture keeps the current state of algorithm.
  */
 typedef struct {
+  U32 signature;   /* safer cast in get_md5_ctx() */
   U32 A, B, C, D;  /* current digest */
   U32 bytes_low;   /* counts bytes in message */
   U32 bytes_high;  /* turn it into a 64-bit counter */
@@ -415,11 +417,21 @@
 #endif
 }
 
+#ifndef INT2PTR
+#define INT2PTR(any,d)	(any)(d)
+#endif
 
 static MD5_CTX* get_md5_ctx(SV* sv)
 {
-    if (sv_derived_from(sv, "Digest::MD5"))
-	return (MD5_CTX*)SvIV(SvRV(sv));
+    if (SvROK(sv)) {
+	sv = SvRV(sv);
+	if (SvIOK(sv)) {
+	    MD5_CTX* ctx = INT2PTR(MD5_CTX*, SvIV(sv));
+	    if (ctx && ctx->signature == MD5_CTX_SIGNATURE) {
+		return ctx;
+            }
+        }
+    }
     croak("Not a reference to a Digest::MD5 object");
     return (MD5_CTX*)0; /* some compilers insist on a return value */
 }
@@ -515,6 +527,7 @@
 	    STRLEN my_na;
 	    char *sclass = SvPV(xclass, my_na);
 	    New(55, context, 1, MD5_CTX);
+	    context->signature = MD5_CTX_SIGNATURE;
 	    ST(0) = sv_newmortal();
 	    sv_setref_pv(ST(0), sclass, (void*)context);
 	    SvREADONLY_on(SvRV(ST(0)));

Deleted: trunk/orca/packages/Digest-MD5-2.13/rfc2104.txt

Added: trunk/orca/packages/Time-HiRes-01.20/HiRes.xs
==============================================================================
--- trunk/orca/packages/Time-HiRes-01.20/HiRes.xs	(original)
+++ trunk/orca/packages/Time-HiRes-01.20/HiRes.xs	Sat Jul 13 21:25:49 2002
@@ -0,0 +1,297 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#ifdef WIN32
+#include <time.h>
+#else
+#include <sys/time.h>
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#if !defined(HAS_GETTIMEOFDAY) && defined(WIN32)
+#define HAS_GETTIMEOFDAY
+
+/* shows up in winsock.h?
+struct timeval {
+ long tv_sec;
+ long tv_usec;
+}
+*/
+
+int
+gettimeofday (struct timeval *tp, int nothing)
+{
+ SYSTEMTIME st;
+ time_t tt;
+ struct tm tmtm;
+ /* mktime converts local to UTC */
+ GetLocalTime (&st);
+ tmtm.tm_sec = st.wSecond;
+ tmtm.tm_min = st.wMinute;
+ tmtm.tm_hour = st.wHour;
+ tmtm.tm_mday = st.wDay;
+ tmtm.tm_mon = st.wMonth - 1;
+ tmtm.tm_year = st.wYear - 1900;
+ tmtm.tm_isdst = -1;
+ tt = mktime (&tmtm);
+ tp->tv_sec = tt;
+ tp->tv_usec = st.wMilliseconds * 1000;
+ return 0;
+}
+#endif
+
+#if !defined(HAS_GETTIMEOFDAY) && defined(VMS)
+#define HAS_GETTIMEOFDAY
+
+#include <time.h> /* gettimeofday */
+#include <stdlib.h> /* qdiv */
+#include <starlet.h> /* sys$gettim */
+#include <descrip.h>
+
+/*
+        VMS binary time is expressed in 100 nano-seconds since
+        system base time which is 17-NOV-1858 00:00:00.00
+*/
+
+#define DIV_100NS_TO_SECS  10000000L
+#define DIV_100NS_TO_USECS 10L
+
+/* 
+        gettimeofday is supposed to return times since the epoch
+        so need to determine this in terms of VMS base time
+*/
+static $DESCRIPTOR(dscepoch,"01-JAN-1970 00:00:00.00");
+
+static __int64 base_adjust=0;
+
+int
+gettimeofday (struct timeval *tp, void *tpz)
+{
+ long ret;
+ __int64 quad;
+ __qdiv_t ans1,ans2;
+
+/*
+        In case of error, tv_usec = 0 and tv_sec = VMS condition code.
+        The return from function is also set to -1.
+        This is not exactly as per the manual page.
+*/
+
+ tp->tv_usec = 0;
+
+ if (base_adjust==0) { /* Need to determine epoch adjustment */
+        ret=sys$bintim(&dscepoch,&base_adjust);
+        if (1 != (ret &&1)) {
+                tp->tv_sec = ret;
+                return -1;
+        }
+ }
+
+ ret=sys$gettim(&quad); /* Get VMS system time */
+ if ((1 && ret) == 1) {
+        quad -= base_adjust; /* convert to epoch offset */
+        ans1=qdiv(quad,DIV_100NS_TO_SECS);
+        ans2=qdiv(ans1.rem,DIV_100NS_TO_USECS);
+        tp->tv_sec = ans1.quot; /* Whole seconds */
+        tp->tv_usec = ans2.quot; /* Micro-seconds */
+ } else {
+        tp->tv_sec = ret;
+        return -1;
+ }
+ return 0;
+}
+#endif
+
+#if !defined(HAS_USLEEP) && defined(HAS_SELECT)
+#ifndef SELECT_IS_BROKEN
+#define HAS_USLEEP
+#define usleep hrt_usleep  /* could conflict with ncurses for static build */
+
+void
+hrt_usleep(unsigned long usec)
+{
+    struct timeval tv;
+    tv.tv_sec = 0;
+    tv.tv_usec = usec;
+    select(0, (Select_fd_set_t)NULL, (Select_fd_set_t)NULL,
+		(Select_fd_set_t)NULL, &tv);
+}
+#endif
+#endif
+
+#if !defined(HAS_USLEEP) && defined(WIN32)
+#define HAS_USLEEP
+#define usleep hrt_usleep  /* could conflict with ncurses for static build */
+
+void
+hrt_usleep(unsigned long usec)
+{
+    long msec;
+    msec = usec / 1000;
+    Sleep (msec);
+}
+#endif
+
+
+#if !defined(HAS_UALARM) && defined(HAS_SETITIMER)
+#define HAS_UALARM
+#define ualarm hrt_ualarm  /* could conflict with ncurses for static build */
+
+int
+hrt_ualarm(int usec, int interval)
+{
+   struct itimerval itv;
+   itv.it_value.tv_sec = usec / 1000000;
+   itv.it_value.tv_usec = usec % 1000000;
+   itv.it_interval.tv_sec = interval / 1000000;
+   itv.it_interval.tv_usec = interval % 1000000;
+   return setitimer(ITIMER_REAL, &itv, 0);
+}
+#endif
+
+#ifdef ATLEASTFIVEOHOHFIVE
+#ifdef HAS_GETTIMEOFDAY
+
+static void
+myU2time(UV *ret)
+{
+  struct timeval Tp;
+  int status;
+  status = gettimeofday (&Tp, NULL);
+  ret[0] = Tp.tv_sec;
+  ret[1] = Tp.tv_usec;
+}
+
+static double
+myNVtime()
+{
+  struct timeval Tp;
+  int status;
+  status = gettimeofday (&Tp, NULL);
+  return Tp.tv_sec + (Tp.tv_usec / 1000000.);
+}
+
+#endif
+#endif
+
+MODULE = Time::HiRes            PACKAGE = Time::HiRes
+
+PROTOTYPES: ENABLE
+
+BOOT:
+#ifdef ATLEASTFIVEOHOHFIVE
+#ifdef HAS_GETTIMEOFDAY
+  hv_store(PL_modglobal, "Time::NVtime", 12, newSViv((IV) myNVtime), 0);
+  hv_store(PL_modglobal, "Time::U2time", 12, newSViv((IV) myU2time), 0);
+#endif
+#endif
+
+#ifdef HAS_USLEEP
+
+void
+usleep(useconds)
+        int useconds 
+
+void
+sleep(fseconds)
+        double fseconds 
+	CODE:
+	int useconds = fseconds * 1000000;
+	usleep (useconds);
+
+#endif
+
+#ifdef HAS_UALARM
+
+int
+ualarm(useconds,interval=0)
+	int useconds
+	int interval
+
+int
+alarm(fseconds,finterval=0)
+	double fseconds
+	double finterval
+	PREINIT:
+	int useconds, uinterval;
+	CODE:
+	useconds = fseconds * 1000000;
+	uinterval = finterval * 1000000;
+	RETVAL = ualarm (useconds, uinterval);
+
+#endif
+
+#ifdef HAS_GETTIMEOFDAY
+
+void
+gettimeofday()
+        PREINIT:
+        struct timeval Tp;
+        PPCODE:
+	int status;
+        status = gettimeofday (&Tp, NULL);
+        if (GIMME == G_ARRAY) {
+	     EXTEND(sp, 2);
+             PUSHs(sv_2mortal(newSViv(Tp.tv_sec)));
+             PUSHs(sv_2mortal(newSViv(Tp.tv_usec)));
+        } else {
+             EXTEND(sp, 1);
+             PUSHs(sv_2mortal(newSVnv(Tp.tv_sec + (Tp.tv_usec / 1000000.0))));
+        }
+
+double
+time()
+        PREINIT:
+        struct timeval Tp;
+        CODE:
+	int status;
+        status = gettimeofday (&Tp, NULL);
+        RETVAL = Tp.tv_sec + (Tp.tv_usec / 1000000.);
+	OUTPUT:
+	RETVAL
+
+#endif
+
+# $Id: HiRes.xs,v 1.11 1999/03/16 02:27:38 wegscd Exp wegscd $
+
+# $Log: HiRes.xs,v $
+# Revision 1.11  1999/03/16 02:27:38  wegscd
+# Add U2time, NVtime. Fix symbols for static link.
+#
+# Revision 1.10  1998/09/30 02:36:25  wegscd
+# Add VMS changes.
+#
+# Revision 1.9  1998/07/07 02:42:06  wegscd
+# Win32 usleep()
+#
+# Revision 1.8  1998/07/02 01:47:26  wegscd
+# Add Win32 code for gettimeofday.
+#
+# Revision 1.7  1997/11/13 02:08:12  wegscd
+# Add missing EXTEND in gettimeofday() scalar code.
+#
+# Revision 1.6  1997/11/11 02:32:35  wegscd
+# Do something useful when calling gettimeofday() in a scalar context.
+# The patch is courtesy of Gisle Aas.
+#
+# Revision 1.5  1997/11/06 03:10:47  wegscd
+# Fake ualarm() if we have setitimer.
+#
+# Revision 1.4  1997/11/05 05:41:23  wegscd
+# Turn prototypes ON (suggested by Gisle Aas)
+#
+# Revision 1.3  1997/10/13 20:56:15  wegscd
+# Add PROTOTYPES: DISABLE
+#
+# Revision 1.2  1997/05/23 01:01:38  wegscd
+# Conditional compilation, depending on what the OS gives us.
+#
+# Revision 1.1  1996/09/03 18:26:35  wegscd
+# Initial revision
+#
+#

Added: trunk/orca/packages/Time-HiRes-01.20/t/01test.t
==============================================================================
--- trunk/orca/packages/Time-HiRes-01.20/t/01test.t	(original)
+++ trunk/orca/packages/Time-HiRes-01.20/t/01test.t	Sat Jul 13 21:25:49 2002
@@ -0,0 +1,140 @@
+# Before `make install' is performed this script should be runnable with
+# `make test'. After `make install' it should work as `perl test.pl'
+
+######################### We start with some black magic to print on failure.
+
+# Change 1..1 below to 1..last_test_to_print .
+# (It may become useful if the test is moved to ./t subdirectory.)
+
+BEGIN { $| = 1; print "1..14\n"; }
+END {print "not ok 1\n" unless $loaded;}
+use Time::HiRes qw(tv_interval);
+$loaded = 1;
+print "ok 1\n";
+
+######################### End of black magic.
+
+# Insert your test code below (better if it prints "ok 13"
+# (correspondingly "not ok 13") depending on the success of chunk 13
+# of the test code):
+
+use strict;
+
+my $have_gettimeofday	= defined &Time::HiRes::gettimeofday;
+my $have_usleep		= defined &Time::HiRes::usleep;
+my $have_ualarm		= defined &Time::HiRes::ualarm;
+
+import Time::HiRes 'gettimeofday'	if $have_gettimeofday;
+import Time::HiRes 'usleep'		if $have_usleep;
+import Time::HiRes 'ualarm'		if $have_ualarm;
+
+sub skip {
+    map { print "ok $_ (skipped)\n" } @_;
+}
+
+sub ok {
+    my ($n, $result, @info) = @_;
+    if ($result) {
+    	print "ok $n\n";
+    }
+    else {
+	print "not ok $n\n";
+    	print "# @info\n" if @info;
+    }
+}
+
+if (!$have_gettimeofday) {
+    skip 2..6;
+}
+else {
+    my @one = gettimeofday();
+    ok 2, @one == 2, 'gettimeofday returned ', 0+ at one, ' args';
+    ok 3, $one[0] > 850_000_000, "@one too small";
+
+    sleep 1;
+
+    my @two = gettimeofday();
+    ok 4, ($two[0] > $one[0] || ($two[0] == $one[0] && $two[1] > $one[1])),
+    	    "@two is not greater than @one";
+
+    my $f = Time::HiRes::time;
+    ok 5, $f > 850_000_000, "$f too small";
+    ok 6, $f - $two[0] < 2, "$f - @two >= 2";
+}
+
+if (!$have_usleep) {
+    skip 7..8;
+}
+else {
+    my $one = time;
+    usleep(10_000);
+    my $two = time;
+    usleep(10_000);
+    my $three = time;
+    ok 7, $one == $two || $two == $three, "slept too long, $one $two $three";
+
+    if (!$have_gettimeofday) {
+    	skip 8;
+    }
+    else {
+    	my $f = Time::HiRes::time;
+	usleep(500_000);
+        my $f2 = Time::HiRes::time;
+	my $d = $f2 - $f;
+	ok 8, $d > 0.4 && $d < 0.8, "slept $d secs $f to $f2";
+    }
+}
+
+# Two-arg tv_interval() is always available.
+{
+    my $f = tv_interval [5, 100_000], [10, 500_000];
+    ok 9, $f == 5.4, $f;
+}
+
+if (!$have_gettimeofday) {
+    skip 10;
+}
+else {
+    my $r = [gettimeofday()];
+    my $f = tv_interval $r;
+    ok 10, $f < 2, $f;
+}
+
+if (!$have_usleep) {
+    skip 11;
+}
+else {
+    my $r = [gettimeofday()];
+    #jTime::HiRes::sleep 0.5;
+    Time::HiRes::sleep( 0.5 );
+    my $f = tv_interval $r;
+    ok 11, $f > 0.4 && $f < 0.8, "slept $f secs";
+}
+
+if (!$have_ualarm) {
+    skip 12..13;
+}
+else {
+    my $tick = 0;
+    local $SIG{ALRM} = sub { $tick++ };
+
+    my $one = time; $tick = 0; ualarm(10_000); sleep until $tick;
+    my $two = time; $tick = 0; ualarm(10_000); sleep until $tick;
+    my $three = time;
+    ok 12, $one == $two || $two == $three, "slept too long, $one $two $three";
+
+    $tick = 0;
+    ualarm(10_000, 10_000);
+    sleep until $tick >= 3;
+    ok 13, 1;
+    ualarm(0);
+}
+
+# new test: did we even get close?
+
+{
+ my $t = time();
+ my $tf = Time::HiRes::time();
+ ok 14, ($tf >= $t) && (($tf - $t) <= 1),
+  "time $t differs from Time::HiRes::time $tf";
+}

Added: trunk/orca/packages/Time-HiRes-01.20/t/02export.t
==============================================================================
--- trunk/orca/packages/Time-HiRes-01.20/t/02export.t	(original)
+++ trunk/orca/packages/Time-HiRes-01.20/t/02export.t	Sat Jul 13 21:25:49 2002
@@ -0,0 +1,58 @@
+# Before `make install' is performed this script should be runnable with
+# `make test'. After `make install' it should work as `perl test.pl'
+
+######################### We start with some black magic to print on failure.
+
+BEGIN {
+    require Time::HiRes;
+    unless (defined &Time::HiRes::gettimeofday
+	    && defined &Time::HiRes::ualarm
+	    && defined &Time::HiRes::usleep) {
+    	print "1..0\n";
+	exit;
+    }
+}
+
+# Change 1..1 below to 1..last_test_to_print .
+# (It may become useful if the test is moved to ./t subdirectory.)
+
+BEGIN { $| = 1; print "1..4\n"; }
+END {print "not ok 1\n" unless $loaded;}
+
+$Exporter::Verbose=1;
+use Time::HiRes qw (time alarm sleep);
+$loaded = 1;
+print "ok 1\n";
+
+######################### End of black magic.
+
+# Insert your test code below (better if it prints "ok 13"
+# (correspondingly "not ok 13") depending on the success of chunk 13
+# of the test code):
+
+print "time...";
+$f = time; 
+print "$f\nok 2\n";
+
+print "sleep...";
+$r = [Time::HiRes::gettimeofday];
+sleep (0.5);
+print Time::HiRes::tv_interval($r), "\nok 3\n";
+
+$r = [Time::HiRes::gettimeofday];
+$i = 5;
+$SIG{ALRM} = "tick";
+while ($i)
+ {
+  alarm(2.5);
+  select (undef, undef, undef, 10);
+  print "Select returned! ", Time::HiRes::tv_interval ($r), "\n";
+ }
+
+sub tick
+ {
+  print "Tick! ", Time::HiRes::tv_interval ($r), "\n";
+  $i--;
+ }
+$SIG{ALRM} = 'DEFAULT';
+print "ok 4\n";

Added: trunk/orca/packages/Time-HiRes-01.20/TODO
==============================================================================
--- trunk/orca/packages/Time-HiRes-01.20/TODO	(original)
+++ trunk/orca/packages/Time-HiRes-01.20/TODO	Sat Jul 13 21:25:49 2002
@@ -0,0 +1,3 @@
+Version 1.16
+
+... nothing right now ...

Added: trunk/orca/packages/Time-HiRes-01.20/HiRes.pm
==============================================================================
--- trunk/orca/packages/Time-HiRes-01.20/HiRes.pm	(original)
+++ trunk/orca/packages/Time-HiRes-01.20/HiRes.pm	Sat Jul 13 21:25:49 2002
@@ -0,0 +1,255 @@
+package Time::HiRes;
+
+use strict;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK @EXPORT_FAIL);
+
+require Exporter;
+require DynaLoader;
+
+ at ISA = qw(Exporter DynaLoader);
+
+ at EXPORT = qw( );
+ at EXPORT_OK = qw (usleep sleep ualarm alarm gettimeofday time tv_interval);
+
+$VERSION = do{my at r=q$Revision: 1.20 $=~/\d+/g;sprintf '%02d.'.'%02d'x$#r, at r};
+
+bootstrap Time::HiRes $VERSION;
+
+ at EXPORT_FAIL = grep { ! defined &$_ } @EXPORT_OK;
+
+# Preloaded methods go here.
+
+sub tv_interval {
+    # probably could have been done in C
+    my ($a, $b) = @_;
+    $b = [gettimeofday()] unless defined($b);
+    (${$b}[0] - ${$a}[0]) + ((${$b}[1] - ${$a}[1]) / 1_000_000);
+}
+
+# I'm only supplying this because the version of it in 5.003's Export.pm
+# is buggy (it doesn't shift off the class name).
+
+sub export_fail {
+    my $self = shift;
+    @_;
+}
+
+# Autoload methods go after =cut, and are processed by the autosplit program.
+
+1;
+__END__
+
+=head1 NAME
+
+Time::HiRes - High resolution ualarm, usleep, and gettimeofday
+
+=head1 SYNOPSIS
+
+  use Time::HiRes qw( usleep ualarm gettimeofday tv_interval );
+
+  usleep ($microseconds);
+
+  ualarm ($microseconds);
+  ualarm ($microseconds, $interval_microseconds);
+
+  $t0 = [gettimeofday];
+  ($seconds, $microseconds) = gettimeofday;
+
+  $elapsed = tv_interval ( $t0, [$seconds, $microseconds]);
+  $elapsed = tv_interval ( $t0, [gettimeofday]);
+  $elapsed = tv_interval ( $t0 );
+
+  use Time::HiRes qw ( time alarm sleep );
+  $now_fractions = time;
+  sleep ($floating_seconds);
+  alarm ($floating_seconds);
+  alarm ($floating_seconds, $floating_interval);
+
+=head1 DESCRIPTION
+
+The C<Time::HiRes> module implements a Perl interface to the usleep, ualarm,
+and gettimeofday system calls. See the EXAMPLES section below and the test
+scripts for usage; see your system documentation for the description of
+the underlying gettimeofday, usleep, and ualarm calls.
+
+If your system lacks gettimeofday(2) you don't get gettimeofday() or the
+one-arg form of tv_interval().  If you don't have usleep(3) or select(2)
+you don't get usleep() or sleep().  If your system don't have ualarm(3)
+or setitimer(2) you don't
+get ualarm() or alarm().  If you try to import an unimplemented function
+in the C<use> statement it will fail at compile time.
+
+The following functions can be imported from this module.  No
+functions are exported by default.
+
+=over 4
+
+=item gettimeofday ()
+
+In array context it returns a 2 element array with the seconds and
+microseconds since the epoch.  In scalar context it returns floating
+seconds like Time::HiRes::time() (see below).
+
+=item usleep ( $useconds )
+
+Issues a usleep for the number of microseconds specified. See also 
+Time::HiRes::sleep() below.
+
+=item ualarm ( $useconds [, $interval_useconds ] )
+
+Issues a ualarm call; interval_useconds is optional and will be 0 if 
+unspecified, resulting in alarm-like behaviour.
+
+=item tv_interval ( $ref_to_gettimeofday [, $ref_to_later_gettimeofday] )
+
+Returns the floating seconds between the two times, which should have been 
+returned by gettimeofday(). If the second argument is omitted, then the
+current time is used.
+
+=item time ()
+
+Returns a floating seconds since the epoch. This function can be imported,
+resulting in a nice drop-in replacement for the C<time> provided with perl,
+see the EXAMPLES below.
+
+=item sleep ( $floating_seconds )
+
+Converts $floating_seconds to microseconds and issues a usleep for the 
+result.  This function can be imported, resulting in a nice drop-in 
+replacement for the C<sleep> provided with perl, see the EXAMPLES below.
+
+=item alarm ( $floating_seconds [, $interval_floating_seconds ] )
+
+Converts $floating_seconds and $interval_floating_seconds and issues a
+ualarm for the results.  The $interval_floating_seconds argument is optional and will 
+be 0 if unspecified, resulting in alarm-like behaviour.  This function can 
+be imported, resulting in a nice drop-in 
+replacement for the C<alarm> provided with perl, see the EXAMPLES below.
+
+=back
+
+=head1 EXAMPLES
+
+  use Time::HiRes qw(usleep ualarm gettimeofday tv_interval);
+
+  $microseconds = 750_000;
+  usleep $microseconds;
+
+  # signal alarm in 2.5s & every .1s thereafter
+  ualarm 2_500_000, 100_000;	
+
+  # get seconds and microseconds since the epoch
+  ($s, $usec) = gettimeofday;
+
+  # measure elapsed time 
+  # (could also do by subtracting 2 gettimeofday return values)
+  $t0 = [gettimeofday];
+  # do bunch of stuff here
+  $t1 = [gettimeofday];
+  # do more stuff here
+  $t0_t1 = tv_interval $t0, $t1;
+  
+  $elapsed = tv_interval ($t0, [gettimeofday]);
+  $elapsed = tv_interval ($t0);	# equivalent code
+
+  #
+  # replacements for time, alarm and sleep that know about
+  # floating seconds
+  #
+  use Time::HiRes;
+  $now_fractions = Time::HiRes::time;
+  Time::HiRes::sleep (2.5);
+  Time::HiRes::alarm (10.6666666);
+ 
+  use Time::HiRes qw ( time alarm sleep );
+  $now_fractions = time;
+  sleep (2.5);
+  alarm (10.6666666);
+
+=head1 C API
+
+In addition to the perl API described above, a C API is available for
+extension writers.  The following C functions are available in the
+modglobal hash:
+
+  name             C prototype
+  ---------------  ----------------------
+  Time::NVtime     double (*)()
+  Time::U2time     void (*)(UV ret[2])
+
+Both functions return equivalent information (like C<gettimeofday>)
+but with different representations.  The names C<NVtime> and C<U2time>
+were selected mainly because they are operating system independent.
+(C<gettimeofday> is Un*x-centric.)
+
+Here is an example of using NVtime from C:
+
+  double (*myNVtime)();
+  SV **svp = hv_fetch(PL_modglobal, "Time::NVtime", 12, 0);
+  if (!svp)         croak("Time::HiRes is required");
+  if (!SvIOK(*svp)) croak("Time::NVtime isn't a function pointer");
+  myNVtime = (double(*)()) SvIV(*svp);
+  printf("The current time is: %f\n", (*myNVtime)());
+
+=head1 AUTHORS
+
+D. Wegscheid <wegscd at whirlpool.com>
+R. Schertler <roderick at argon.org>
+J. Hietaniemi <jhi at iki.fi>
+G. Aas <gisle at aas.no>
+
+=head1 REVISION
+
+$Id: HiRes.pm,v 1.20 1999/03/16 02:26:13 wegscd Exp $
+
+$Log: HiRes.pm,v $
+Revision 1.20  1999/03/16 02:26:13  wegscd
+Add documentation for NVTime and U2Time.
+
+Revision 1.19  1998/09/30 02:34:42  wegscd
+No changes, bump version.
+
+Revision 1.18  1998/07/07 02:41:35  wegscd
+No changes, bump version.
+
+Revision 1.17  1998/07/02 01:45:13  wegscd
+Bump version to 1.17
+
+Revision 1.16  1997/11/13 02:06:36  wegscd
+version bump to accomodate HiRes.xs fix.
+
+Revision 1.15  1997/11/11 02:17:59  wegscd
+POD editing, courtesy of Gisle Aas.
+
+Revision 1.14  1997/11/06 03:14:35  wegscd
+Update version # for Makefile.PL and HiRes.xs changes.
+
+Revision 1.13  1997/11/05 05:36:25  wegscd
+change version # for Makefile.pl and HiRes.xs changes.
+
+Revision 1.12  1997/10/13 20:55:33  wegscd
+Force a new version for Makefile.PL changes.
+
+Revision 1.11  1997/09/05 19:59:33  wegscd
+New version to bump version for README and Makefile.PL fixes.
+Fix bad RCS log.
+
+Revision 1.10  1997/05/23 01:11:38  wegscd
+Conditional compilation; EXPORT_FAIL fixes.
+
+Revision 1.2  1996/12/30 13:28:40  wegscd
+Update documentation for what to do when missing ualarm() and friends.
+
+Revision 1.1  1996/10/17 20:53:31  wegscd
+Fix =head1 being next to __END__ so pod2man works
+
+Revision 1.0  1996/09/03 18:25:15  wegscd
+Initial revision
+
+=head1 COPYRIGHT
+
+Copyright (c) 1996-1997 Douglas E. Wegscheid.
+All rights reserved. This program is free software; you can
+redistribute it and/or modify it under the same terms as Perl itself.
+
+=cut

Added: trunk/orca/packages/Time-HiRes-01.20/MANIFEST
==============================================================================
--- trunk/orca/packages/Time-HiRes-01.20/MANIFEST	(original)
+++ trunk/orca/packages/Time-HiRes-01.20/MANIFEST	Sat Jul 13 21:25:49 2002
@@ -0,0 +1,9 @@
+Changes
+MANIFEST
+Makefile.PL
+README
+TODO
+HiRes.pm
+HiRes.xs
+t/01test.t
+t/02export.t

Added: trunk/orca/packages/Time-HiRes-01.20/Makefile.PL
==============================================================================
--- trunk/orca/packages/Time-HiRes-01.20/Makefile.PL	(original)
+++ trunk/orca/packages/Time-HiRes-01.20/Makefile.PL	Sat Jul 13 21:25:49 2002
@@ -0,0 +1,251 @@
+
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+#
+
+require 5.002;
+
+use Config;
+use ExtUtils::MakeMaker;
+
+# comment the following if xsubpp complains about bad usage.
+$XSOPT = '-nolinenumbers'; 
+
+# if you have 5.004_03 (and some slightly older versions?), xsubpp
+# tries to generate line numbers in the C code generated from the .xs.
+# unfortunately, it is a little buggy around #ifdef'd code.
+# my choice is leave it in and have people with old perls complain 
+# about the "Usage" bug, or leave it out and be unable to compile myself
+# without changing it, and then I'd always forget to change it before a 
+# release. Sorry, Edward :)
+
+sub TMPDIR {
+    my $TMPDIR =
+	(grep(defined $_ && -d $_ && -w _,
+	      ((defined $ENV{'TMPDIR'} ? $ENV{'TMPDIR'} : undef),
+	       qw(/var/tmp /usr/tmp /tmp))))[0]
+		   unless defined $TMPDIR;
+    $TMPDIR || die "Cannot find writable temporary directory.\n";
+}
+
+sub try_compile_and_link {
+    my ($c, $cccmd) = @_;
+
+    my ($ok) = 0;
+    my ($tmp) = ($^O eq 'VMS') ? "tmp$$" : TMPDIR . '/' . "tmp$$";
+    local(*TMPC);
+
+    my $obj_ext = $Config{obj_ext} || ".o";
+    unlink("$tmp.c", "$tmp$obj_ext");
+
+    if (open(TMPC, ">$tmp.c")) {
+	print TMPC $c;
+	close(TMPC);
+	my $COREincdir = $Config{'archlibexp'} . '/' . 'CORE';
+	my $ccflags = $Config{'ccflags'} . ' ' . "-I$COREincdir";
+	if ($^O eq 'VMS') {
+            my $perl_core = $Config{'installarchlib'};
+            $perl_core =~ s/\]$/.CORE]/;
+            $cccmd = "$Config{'cc'} /include=(perl_root:[000000],$perl_core) $tmp.c"; 
+        }
+	$cccmd = "$Config{'cc'} -o $tmp $ccflags $tmp.c @$LIBS"
+	 unless (defined $cccmd);
+	system($cccmd);
+	if ($^O eq 'VMS') {
+	    $ok = -s "$tmp$obj_ext" && -x _;
+	    unlink("$tmp.c", "$tmp$obj_ext");
+        }
+        else
+        {
+	    $ok = -s $tmp && -x _;
+	    unlink("$tmp.c", $tmp);
+        }
+    }
+    
+    $ok;
+}
+
+sub has_gettimeofday {
+    # confusing but true (if condition true ==> -DHAS_GETTIMEOFDAY already)
+    return 0 if $Config{'d_gettimeod'} eq 'define';
+    return 1 if try_compile_and_link(<<EOM); 
+#include "EXTERN.h" 
+#include "perl.h" 
+#include "XSUB.h" 
+#ifdef I_SYS_TYPES 
+#   include <sys/types.h>
+#endif
+
+#ifdef I_SYS_TIME
+#   include <sys/time.h>
+#endif
+
+#ifdef I_SYS_SELECT
+#   include <sys/select.h>	/* struct timeval might be hidden in here */
+#endif
+static int foo()
+{
+    struct timeval tv;
+    gettimeofday(&tv, 0);
+}
+int main _((int argc, char** argv, char** env))
+{
+    foo();
+}
+EOM
+    return 0;
+}
+
+sub has_x {
+    my ($x) = @_; 
+
+    return 1 if
+    try_compile_and_link(<<EOM);
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#ifdef I_UNISTD
+#   include <unistd.h>
+#endif
+
+#ifdef I_SYS_TYPES
+#   include <sys/types.h>
+#endif
+
+#ifdef I_SYS_TIME
+#   include <sys/time.h>
+#endif
+
+int main _((int argc, char** argv, char** env))
+{
+	$x;
+}
+EOM
+    return 0;
+}
+
+sub unixinit {
+    $DEFINE = '';
+
+    $LIBS = [''];
+
+    # this might break the link, try it if it can't find some things you 
+    # honestly think should be in there...
+    # $LIBS = ['-lucb -lbsd'];
+
+    # ... but ucb is poison for Solaris, and probably Linux. honest.
+    $LIBS = [''] if $Config{'osname'} eq 'solaris';
+    $LIBS = [''] if $Config{'osname'} eq 'linux';
+    $LIBS = ['-lm'] if $Config{'osname'} =~ /sco/i;
+
+    if ($Config{'d_gettimeod'} eq 'define') {
+	# do nothing special, everything should be fine
+    } elsif (has_gettimeofday) {
+	$DEFINE .= ' -DHAS_GETTIMEOFDAY';
+    } else {
+	die <<EOD
+Your operating system does not seem to have the gettimeofday() function.
+(or, at least, I cannot find it)
+
+There is no way Time::HiRes is going to work.
+
+I am awfully sorry but I cannot go further.
+
+Aborting configuration
+
+EOD
+    }
+
+    print "Looking for usleep()...\n";
+    if (has_x ("usleep (0)")) {
+	$DEFINE .= ' -DHAS_USLEEP';
+	print "You have usleep()\n\n";
+    } else {
+	print "Whoops! No usleep()! Let's see if you have select().\n";
+        if ($Config{'d_select'} eq 'define') {
+	    print "You have select(); we can make a Time::HiRes::usleep()\n\n";
+	} else {
+	    print "No select(); you won't have a Time::HiRes::usleep()\n\n";
+	}
+    }
+
+    print "Looking for ualarm()...\n";
+    if (has_x ("ualarm (0, 0)")) {
+	$DEFINE .= ' -DHAS_UALARM';
+	print "You have ualarm()\n\n";
+    } else {
+	print "Whoops! No ualarm()!\n";
+	if (has_x("setitimer(ITIMER_REAL, 0, 0)")) {
+	    print "You have setitimer(); we can make a Time::HiRes::ualarm()\n\n";
+	    $DEFINE .= ' -DHAS_SETITIMER';
+	} else {
+	     print "We'll manage.\n\n";
+	}
+    }
+    $DEFINE =~ s/^\s+//;
+}
+
+sub doMakefile {
+    print <<EOM if ($$LIBS[0] ne '');
+Looking for libraries...
+Note: it is ok if none of the libraries '@$LIBS' is found.
+
+EOM
+
+    @makefileopts = ();
+
+    if ($] >= 5.005) {
+	push (@makefileopts,
+	    'AUTHOR'    => 'Doug Wegscheid (wegscd at whirlpool.com)',
+	    'ABSTRACT_FROM' => 'HiRes.pm',
+	);
+	$DEFINE .= " -DATLEASTFIVEOHOHFIVE";
+    }
+
+    push (@makefileopts,
+	'NAME'	=> 'Time::HiRes',
+	'VERSION_FROM' => 'HiRes.pm', # finds $VERSION
+	'LIBS'	=> $LIBS,   # e.g., '-lm' 
+	'DEFINE'	=> $DEFINE,     # e.g., '-DHAS_SOMETHING' 
+	'XSOPT'	=> $XSOPT,
+    # do not even think about 'INC' => '-I/usr/ucbinclude', Solaris will avenge.
+	'INC'	=> '',     # e.g., '-I/usr/include/other' 
+	'dist'      => {
+	    'CI'=>'ci -l',
+	    'COMPRESS'=>'gzip -9f', 
+	    'SUFFIX' => 'gz',
+	},
+    );
+
+    WriteMakefile(@makefileopts);
+}
+
+sub main {
+    print <<EOM;
+
+Configuring...
+
+EOM
+
+    if ($^O =~ /Win32/i) {
+      $DEFINE = '-DSELECT_IS_BROKEN';
+      $LIBS = [''];
+    } else {
+      unixinit();
+    }
+    configure;
+    doMakefile;
+    my $make = $Config{'make'} || "make";
+print  <<EOM;
+
+Done configuring
+
+Now you may issue '$make'. Do not forget also '$make test'.
+
+EOM
+}
+
+&main;
+
+# EOF

Added: trunk/orca/packages/Time-HiRes-01.20/Changes
==============================================================================
--- trunk/orca/packages/Time-HiRes-01.20/Changes	(original)
+++ trunk/orca/packages/Time-HiRes-01.20/Changes	Sat Jul 13 21:25:49 2002
@@ -0,0 +1,99 @@
+Revision history for Perl extension Time::HiRes.
+
+1.20  Wed Feb 24 21:30 1999
+	- make our usleep and ualarm substitutes into hrt_usleep 
+	  and hrt_ualarm. This helps static links of Perl with other
+	  packages that also have usleep, etc. From
+	  Ilya Zakharevich <ilya at math.ohio-state.edu>
+	- add C API stuff. From Joshua Pritikin
+	  <joshua.pritikin at db.com>
+	- VMS Makefile.PL fun.  From pvhp at forte.com (Peter Prymmer)
+	- hopefully correct "-lc" fix for SCO.
+	- add PPD stuff
+
+1.19  Tue Sep 29 22:30 1998
+	- put VMS gettimeofday() in. Patch is from Sebastian Bazley
+	  <seb at stian.demon.co.uk>
+	- change GIMME_V to GIMME to help people with older versions of
+	  Perl.
+	- fix Win32 version of gettimeofday(). It didn't affect anything,
+	  but it confuses people reading the code when the return value
+	  is backwards (0 is success).
+	- fix Makefile.PL (more) so that detection of gettimeofday is
+	  more correct.
+
+1.18  Mon Jul 6 22:40 1998
+	- add usleep() for Win32.
+	- fix Makefile.PL to fix reported HP/UX feature where unresolved
+	  externals still cause an executable to be generated (though no
+	  x bit set). Thanks to David Kozinn for report and explanation.
+	  Problems with the fix are mine :)
+
+1.17  Wed Jul 1 20:10 1998
+	- fix setitimer calls so microseconds is not more than 1000000.
+	  Hp/UX 9 doesn't like that. Provided by Roland B Robert, PhD.
+        - make Win32. We only get gettimeofday (the select hack doesn't
+	  seem to work on my Win95 system).
+        - fix test 4 on 01test.t. add test to see if time() and 
+	  Time::HiRes::time() are close.
+
+1.16  Wed Nov 12 21:05 1997
+	- add missing EXTEND in new gettimeofday scalar code.
+
+1.15  Mon Nov 10 21:30 1997
+	- HiRes.pm: update pod. Provided by Gisle Aas.
+	- HiRes.xs: if gettimeofday() called in scalar context, do
+	  something more useful than before. Provided by Gisle Aas.
+	- README: tell of xsubpp '-nolinenumber' woes. thanks to
+	  Edward Henigin <ed at texas.net> for pointing out the problem.
+
+1.14  Wed Nov 5 9:40 1997
+	- Makefile.PL: look for setitimer
+	- HiRes.xs: if missing ualarm, but we have setitimer, make up
+	  our own setitimer. These were provided by Gisle Aas.
+
+1.13  Tue Nov 4 23:30 1997
+	- Makefile.PL: fix autodetect mechanism to do try linking in addition
+	  to just compiling; should fix Linux build problem. Fix was provided
+	  by Gisle Aas.
+
+1.12  Sun Oct 12 12:00:00 1997
+	- Makefile.PL: set XSOPT to '-nolinenumbers' to work around xsubpp bug;
+	  you may need to comment this back out if you have an older xsubpp.
+	- HiRes.xs: set PROTOTYPES: DISABLE
+
+1.11  Fri Sep 05 16:00:00 1997
+	- Makefile.PL:
+	  Had some line commented out that shouldn't have been (testing
+	  remnants)
+	- README:
+	  Previous version was corrupted.
+
+1.10  Thu May 22 20:20:00 1997
+	- HiRes.xs, HiRes.pm, t/*:
+	      -	only compile what we have OS support for (or can 
+		fake with select())
+	      - only test what we compiled 
+	      - gross improvement to the test suite
+	      - fix EXPORT_FAIL. 
+	  This work was all done by Roderick Schertler
+	  <roderick at argon.org>. If you run Linux or
+	  one of the other ualarm-less platoforms, and you like this 
+	  module, let Roderick know; without him, it still wouldn't 
+	  be working on those boxes...
+	- Makefile.PL: figure out what routines the OS has and
+	  only build what we need. These bits were written by Jarkko 
+	  Hietaniemi <jhi at iki.fi>. Again, gratitude is due...
+
+1.02  Mon Dec 30 08:00:00 1996
+	- HiRes.pm: update documentation to say what to do when missing
+	  ualarm() and friends.
+	- README: update to warn that ualarm() and friends need to exist
+
+1.01  Fri Oct 17 08:00:00 1996
+	- Makefile.PL: make XSPROTOARGS => '-noprototyopes'
+	- HiRes.pm: put blank line between __END__ and =head1 so that 
+	  pod2man works.
+
+1.00  Tue Sep 03 13:00:00 1996
+	- original version; created by h2xs 1.16

Added: trunk/orca/packages/Time-HiRes-01.20/README
==============================================================================
--- trunk/orca/packages/Time-HiRes-01.20/README	(original)
+++ trunk/orca/packages/Time-HiRes-01.20/README	Sat Jul 13 21:25:50 2002
@@ -0,0 +1,41 @@
+Time::HiRes module: High resolution time, sleep, and alarm.
+
+Implement usleep, ualarm, and gettimeofday for Perl, as well as wrappers
+to implement time, sleep, and alarm that know about non-integral seconds.
+
+1.20 adds a platform neutral set of C accessible routines if you are running
+5.005+.  All other changes are packaging changes and build fixes(?) for
+statically linked Perl, SCO, and VMS.
+
+1.19 has better VMS support.
+
+1.18 has limited Win32 support (no ualarm). Added usleep for Win32.
+Probably buggy. I'm sure I'll hear.
+
+1.16+ should be closer to building out of the box on Linux. Thanks
+to Gisle Aas for patches, and the ualarm equivalent using setitimer.
+
+If your underlying operating system doesn't implement ualarm(), then a fake
+using setitimer() will be made.  If the OS is missing usleep(), a fake one
+using select() will be made. If a fake can't be made for either ualarm() or
+usleep(), then the corresponding Perl function will not be available.  If the
+OS is missing gettimeofday(), you will get unresolved externals, either at
+link- or run-time.
+
+This is an improvement; the package used to not even build if you were
+missing any of these bits. Roderick Schertler <roderick at argon.org> did all 
+the conditional compilation stuff, look at HiRes.pm and the test suites; 
+it's good educational reading.
+
+Also, older versions of Perl do not support '-nolinenumbers' on the XSUBPP
+command, however, 5.004_03 requires it (on my box, anyway) since the #line
+generating code in XSUBPP appears to have problems with #ifdef'd .xs code. If
+xsubpp complains about usage when you do a make, look at the top of the
+Makefile.PL and comment out the "$XSOPT=" line. Or upgrade to a newer version
+of Perl.
+
+POD documentation is embedded.
+
+Copyright (c) 1996, 1997, 1998 Douglas E. Wegscheid.
+All rights reserved. This program is free software; you can 
+redistribute it and/or modify it under the same terms as Perl itself.

Modified: trunk/orca/packages/rrdtool-1.0.33/configure
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/configure	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/configure	Sat Jul 13 21:25:50 2002
@@ -11,7 +11,12 @@
 ac_help=
 ac_default_prefix=/usr/local
 # Any additions from configure.in:
-ac_default_prefix=/usr/local/rrdtool-1.0.13 
+ac_default_prefix=/usr/local/rrdtool-1.0.33 
+ac_help="$ac_help
+  --with-tcllib=DIR       location of the tclConfig.sh"
+ac_help="$ac_help
+  --with-perl-options=[OPTIONS]  options to pass on command-line when
+                          generating Makefile from Makefile.PL"
 ac_help="$ac_help
   --enable-shared[=PKGS]  build shared libraries [default=no]"
 ac_help="$ac_help
@@ -581,7 +586,7 @@
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:585: checking host system type" >&5
+echo "configure:590: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -602,7 +607,7 @@
 echo "$ac_t""$host" 1>&6
 
 echo $ac_n "checking target system type""... $ac_c" 1>&6
-echo "configure:606: checking target system type" >&5
+echo "configure:611: checking target system type" >&5
 
 target_alias=$target
 case "$target_alias" in
@@ -620,7 +625,7 @@
 echo "$ac_t""$target" 1>&6
 
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:624: checking build system type" >&5
+echo "configure:629: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -655,7 +660,7 @@
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:659: checking for a BSD compatible install" >&5
+echo "configure:664: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -708,7 +713,7 @@
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
-echo "configure:712: checking whether build environment is sane" >&5
+echo "configure:717: checking whether build environment is sane" >&5
 # Just in case
 sleep 1
 echo timestamp > conftestfile
@@ -765,7 +770,7 @@
 test "$program_transform_name" = "" && program_transform_name="s,x,x,"
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:769: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:774: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -794,7 +799,7 @@
 
 PACKAGE=rrdtool
 
-VERSION=1.0.13
+VERSION=1.0.33
 
 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
   { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
@@ -811,7 +816,7 @@
 
 missing_dir=`cd $ac_aux_dir && pwd`
 echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
-echo "configure:815: checking for working aclocal" >&5
+echo "configure:820: checking for working aclocal" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -824,7 +829,7 @@
 fi
 
 echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
-echo "configure:828: checking for working autoconf" >&5
+echo "configure:833: checking for working autoconf" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -837,7 +842,7 @@
 fi
 
 echo $ac_n "checking for working automake""... $ac_c" 1>&6
-echo "configure:841: checking for working automake" >&5
+echo "configure:846: checking for working automake" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -850,7 +855,7 @@
 fi
 
 echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
-echo "configure:854: checking for working autoheader" >&5
+echo "configure:859: checking for working autoheader" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -863,7 +868,7 @@
 fi
 
 echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
-echo "configure:867: checking for working makeinfo" >&5
+echo "configure:872: checking for working makeinfo" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -885,9 +890,10 @@
 
 
 
+
 CGI_LIB_DIR=cgilib-0.4
 GD_LIB_DIR=gd1.3
-PNG_LIB_DIR=libpng-1.0.3
+PNG_LIB_DIR=libpng-1.0.9
 ZLIB_LIB_DIR=zlib-1.1.3
 
 
@@ -899,7 +905,7 @@
 # Extract the first word of "perl", so it can be a program name with args.
 set dummy perl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:903: checking for $ac_word" >&5
+echo "configure:909: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -932,18 +938,73 @@
   echo "$ac_t""no" 1>&6
 fi
 
-if test "x$PERL" = "nox"; then
+if test "x$PERL" = "xno"; then
 	COMP_PERL=
 else
 	COMP_PERL="perl_piped perl_shared"
+	echo $ac_n "checking for shared library extension""... $ac_c" 1>&6
+echo "configure:947: checking for shared library extension" >&5
+	SO_EXT=`$PERL -e 'use Config; if (defined $Config{so} and $Config{so} ne 'a') {print "$Config{so}\n"} else {print "so\n"};'`
+	echo "$ac_t""$SO_EXT" 1>&6
+fi
+
+
+
+withval=""
+# Check whether --with-tcllib or --without-tcllib was given.
+if test "${with_tcllib+set}" = set; then
+  withval="$with_tcllib"
+  :
+fi
+
+found=0
+echo $ac_n "checking for tclConfig.sh in $withval""... $ac_c" 1>&6
+echo "configure:963: checking for tclConfig.sh in $withval" >&5
+if test -f "$withval/tclConfig.sh" ; then
+    	tcl_config=$withval/tclConfig.sh
+        found=1
+        echo "$ac_t""yes" 1>&6
+        break
+else
+        echo "$ac_t""no" 1>&6
+fi
+
+if test $found -eq 0 ; then
+        echo "configure: warning: tclConfig.sh not found - Tcl interface won't be built" 1>&2
+else
+	. $tcl_config
+fi
+
+# Options to pass when configuring perl module
+# Check whether --with-perl-options or --without-perl-options was given.
+if test "${with_perl_options+set}" = set; then
+  withval="$with_perl_options"
+  PERL_MAKE_OPTIONS=$withval
 fi
 
 
 
+
+
+if test x$found = x1 ; then
+  COMP_TCL_TRUE=
+  COMP_TCL_FALSE='#'
+else
+  COMP_TCL_TRUE='#'
+  COMP_TCL_FALSE=
+fi
+
+
+
+
+
+
+
+
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:947: checking for $ac_word" >&5
+echo "configure:1008: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -973,7 +1034,7 @@
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:977: checking for $ac_word" >&5
+echo "configure:1038: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1024,7 +1085,7 @@
       # Extract the first word of "cl", so it can be a program name with args.
 set dummy cl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1028: checking for $ac_word" >&5
+echo "configure:1089: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1056,7 +1117,7 @@
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1060: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1121: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -1067,12 +1128,12 @@
 
 cat > conftest.$ac_ext << EOF
 
-#line 1071 "configure"
+#line 1132 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:1076: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1137: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -1098,12 +1159,12 @@
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1102: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1163: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:1107: checking whether we are using GNU C" >&5
+echo "configure:1168: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1112,7 +1173,7 @@
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1116: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1177: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -1131,7 +1192,7 @@
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:1135: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:1196: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1163,7 +1224,7 @@
 fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1167: checking how to run the C preprocessor" >&5
+echo "configure:1228: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1178,13 +1239,13 @@
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1182 "configure"
+#line 1243 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1188: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1249: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1195,13 +1256,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1199 "configure"
+#line 1260 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1205: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1266: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1212,13 +1273,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 1216 "configure"
+#line 1277 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1222: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1283: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1316,7 +1377,7 @@
 # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1320: checking for $ac_word" >&5
+echo "configure:1381: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1355,7 +1416,7 @@
 if test "$ac_cv_prog_gcc" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
-echo "configure:1359: checking for ld used by GCC" >&5
+echo "configure:1420: checking for ld used by GCC" >&5
   ac_prog=`($CC -print-prog-name=ld) 2>&5`
   case "$ac_prog" in
     # Accept absolute paths.
@@ -1379,10 +1440,10 @@
   esac
 elif test "$with_gnu_ld" = yes; then
   echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
-echo "configure:1383: checking for GNU ld" >&5
+echo "configure:1444: checking for GNU ld" >&5
 else
   echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
-echo "configure:1386: checking for non-GNU ld" >&5
+echo "configure:1447: checking for non-GNU ld" >&5
 fi
 if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1416,9 +1477,8 @@
   echo "$ac_t""no" 1>&6
 fi
 test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
-
 echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
-echo "configure:1422: checking if the linker ($LD) is GNU ld" >&5
+echo "configure:1482: checking if the linker ($LD) is GNU ld" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1434,7 +1494,7 @@
 
 
 echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
-echo "configure:1438: checking for BSD-compatible nm" >&5
+echo "configure:1498: checking for BSD-compatible nm" >&5
 if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1469,9 +1529,8 @@
 NM="$ac_cv_path_NM"
 echo "$ac_t""$NM" 1>&6
 
-
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1475: checking whether ln -s works" >&5
+echo "configure:1534: checking whether ln -s works" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1492,6 +1551,11 @@
 fi
 
 
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
+esac
+
 # Check for any special flags to pass to ltconfig.
 libtool_flags="--cache-file=$cache_file"
 test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
@@ -1512,11 +1576,11 @@
 
 # Some flags need to be propagated to the compiler or linker for good
 # libtool support.
-case "$host" in
+case "$lt_target" in
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 1519 "configure"' > conftest.$ac_ext
-  if { (eval echo configure:1520: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  echo '#line 1583 "configure"' > conftest.$ac_ext
+  if { (eval echo configure:1584: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
     case "`/usr/bin/file conftest.o`" in
     *32-bit*)
       LD="${LD-ld} -32"
@@ -1537,19 +1601,19 @@
   SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
   echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
-echo "configure:1541: checking whether the C compiler needs -belf" >&5
+echo "configure:1605: checking whether the C compiler needs -belf" >&5
 if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1546 "configure"
+#line 1610 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:1553: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   lt_cv_cc_needs_belf=yes
 else
@@ -1627,7 +1691,7 @@
 LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
 DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
 ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
-$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
 || { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
 
 # Reload cache, that may have been modified by ltconfig
@@ -1652,12 +1716,12 @@
 
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1656: checking for ANSI C header files" >&5
+echo "configure:1720: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1661 "configure"
+#line 1725 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -1665,7 +1729,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1669: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1733: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1682,7 +1746,7 @@
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1686 "configure"
+#line 1750 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -1700,7 +1764,7 @@
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1704 "configure"
+#line 1768 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -1721,7 +1785,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 1725 "configure"
+#line 1789 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1732,7 +1796,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:1736: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1800: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -1755,21 +1819,21 @@
 
 fi
 
-for ac_hdr in fcntl.h fp_class.h malloc.h unistd.h math.h sys/time.h sys/times.h sys/param.h sys/resource.h float.h
+for ac_hdr in fcntl.h fp_class.h malloc.h unistd.h ieeefp.h math.h sys/time.h sys/times.h sys/param.h sys/resource.h float.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1763: checking for $ac_hdr" >&5
+echo "configure:1827: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1768 "configure"
+#line 1832 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1773: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1837: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1797,12 +1861,12 @@
 
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:1801: checking for working const" >&5
+echo "configure:1865: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1806 "configure"
+#line 1870 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1851,7 +1915,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:1855: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1919: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -1872,12 +1936,12 @@
 fi
 
 echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1876: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1940: checking whether time.h and sys/time.h may both be included" >&5
 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1881 "configure"
+#line 1945 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/time.h>
@@ -1886,7 +1950,7 @@
 struct tm *tp;
 ; return 0; }
 EOF
-if { (eval echo configure:1890: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1954: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_time=yes
 else
@@ -1907,12 +1971,12 @@
 fi
 
 echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
-echo "configure:1911: checking whether struct tm is in sys/time.h or time.h" >&5
+echo "configure:1975: checking whether struct tm is in sys/time.h or time.h" >&5
 if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1916 "configure"
+#line 1980 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <time.h>
@@ -1920,7 +1984,7 @@
 struct tm *tp; tp->tm_sec;
 ; return 0; }
 EOF
-if { (eval echo configure:1924: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1988: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_tm=time.h
 else
@@ -1941,8 +2005,54 @@
 fi
 
 
+echo $ac_n "checking for acos""... $ac_c" 1>&6
+echo "configure:2010: checking for acos" >&5
+if eval "test \"`echo '$''{'ac_cv_func_acos'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2015 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char acos(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char acos();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_acos) || defined (__stub___acos)
+choke me
+#else
+acos();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2038: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_acos=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_acos=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'acos`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
 echo $ac_n "checking for acos in -lm""... $ac_c" 1>&6
-echo "configure:1946: checking for acos in -lm" >&5
+echo "configure:2056: checking for acos in -lm" >&5
 ac_lib_var=`echo m'_'acos | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1950,7 +2060,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lm  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1954 "configure"
+#line 2064 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1961,7 +2071,7 @@
 acos()
 ; return 0; }
 EOF
-if { (eval echo configure:1965: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2075: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1976,7 +2086,7 @@
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    ac_tr_lib=HAVE_LIB`echo m | sed -e 's/^a-zA-Z0-9_/_/g' \
     -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
@@ -1988,23 +2098,107 @@
   echo "$ac_t""no" 1>&6
 fi
 
+fi
+
+
+for ac_prog in gnroff nroff
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2110: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NROFF'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$NROFF" in
+  /*)
+  ac_cv_path_NROFF="$NROFF" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_NROFF="$NROFF" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_NROFF="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+NROFF="$ac_cv_path_NROFF"
+if test -n "$NROFF"; then
+  echo "$ac_t""$NROFF" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$NROFF" && break
+done
+
+for ac_prog in groff troff
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2150: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_TROFF'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$TROFF" in
+  /*)
+  ac_cv_path_TROFF="$TROFF" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_TROFF="$TROFF" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_TROFF="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+TROFF="$ac_cv_path_TROFF"
+if test -n "$TROFF"; then
+  echo "$ac_t""$TROFF" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$TROFF" && break
+done
+
 
-oCFLAGS=$CFLAGS
-CFLAGS="$CFLAGS -Wall -pedantic"
-echo $ac_n "checking if we can use GCC-specific compiler options""... $ac_c" 1>&6
-echo "configure:1996: checking if we can use GCC-specific compiler options" >&5
+if test "x$GCC" = "xyes"; then
+  oCFLAGS=$CFLAGS
+  CFLAGS="$CFLAGS -Wall -pedantic -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline"
+  echo $ac_n "checking if we can use GCC-specific compiler options""... $ac_c" 1>&6
+echo "configure:2190: checking if we can use GCC-specific compiler options" >&5
 if eval "test \"`echo '$''{'rd_cv_gcc_opt'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2001 "configure"
+#line 2195 "configure"
 #include "confdefs.h"
 
 int main() {
 return 0 
 ; return 0; }
 EOF
-if { (eval echo configure:2008: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2202: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   rd_cv_gcc_opt=yes
 else
@@ -2014,60 +2208,31 @@
   rd_cv_gcc_opt=no 
 fi
 rm -f conftest*
-	       
-       
+               
+        
 fi
 
 echo "$ac_t""$rd_cv_gcc_opt" 1>&6
-if test $rd_cv_gcc_opt = no; then
-	CFLAGS=$oCFLAGS
-fi
-
-
-oCFLAGS=$CFLAGS
-CFLAGS="$CFLAGS -fPIC"
-echo $ac_n "checking if we can use -fPIC as this may help building the perl module""... $ac_c" 1>&6
-echo "configure:2031: checking if we can use -fPIC as this may help building the perl module" >&5
-if eval "test \"`echo '$''{'rd_cv_pic'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-  :
-else
-  cat > conftest.$ac_ext <<EOF
-#line 2039 "configure"
-#include "confdefs.h"
-int main(void){return 0;}
-EOF
-if { (eval echo configure:2043: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
-  rd_cv_pic=yes
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -fr conftest*
-  rd_cv_pic=no
-fi
-rm -fr conftest*
-fi
-
-	       
-       
+  if test $rd_cv_gcc_opt = no; then
+         CFLAGS=$oCFLAGS
+  fi
 fi
 
-echo "$ac_t""$rd_cv_pic" 1>&6
-if test $rd_cv_pic = no; then
-	CFLAGS=$oCFLAGS
-fi
+CFLAGS="$CFLAGS "`grep pic_flag= libtool | sed -e 's/.*pic_flag=//' -e 's/"//g'`
 
+case $target_os in
+*hpux*)
+	CLFAGS=`echo $CFLAGS|sed -e 's/-fPIC/-fpic/g'`
+;;
+esac
 
 echo $ac_n "checking for strftime""... $ac_c" 1>&6
-echo "configure:2066: checking for strftime" >&5
+echo "configure:2231: checking for strftime" >&5
 if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2071 "configure"
+#line 2236 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char strftime(); below.  */
@@ -2090,7 +2255,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2094: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2259: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_strftime=yes"
 else
@@ -2112,7 +2277,7 @@
   echo "$ac_t""no" 1>&6
 # strftime is in -lintl on SCO UNIX.
 echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6
-echo "configure:2116: checking for strftime in -lintl" >&5
+echo "configure:2281: checking for strftime in -lintl" >&5
 ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2120,7 +2285,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lintl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2124 "configure"
+#line 2289 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2131,7 +2296,7 @@
 strftime()
 ; return 0; }
 EOF
-if { (eval echo configure:2135: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2300: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2158,12 +2323,12 @@
 fi
 
 echo $ac_n "checking for vprintf""... $ac_c" 1>&6
-echo "configure:2162: checking for vprintf" >&5
+echo "configure:2327: checking for vprintf" >&5
 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2167 "configure"
+#line 2332 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char vprintf(); below.  */
@@ -2186,7 +2351,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2190: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2355: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_vprintf=yes"
 else
@@ -2210,12 +2375,12 @@
 
 if test "$ac_cv_func_vprintf" != yes; then
 echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
-echo "configure:2214: checking for _doprnt" >&5
+echo "configure:2379: checking for _doprnt" >&5
 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2219 "configure"
+#line 2384 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char _doprnt(); below.  */
@@ -2238,7 +2403,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2242: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2407: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func__doprnt=yes"
 else
@@ -2263,15 +2428,16 @@
 fi
 
 
-for ac_func in snprintf vsnprintf fpclass class fpclassify fp_class isnan finite isinf memmove strchr mktime getrusage gettimeofday
+
+for ac_func in strerror snprintf vsnprintf fpclass class fp_class isnan memmove strchr mktime getrusage gettimeofday
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2270: checking for $ac_func" >&5
+echo "configure:2436: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2275 "configure"
+#line 2441 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2294,7 +2460,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2298: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2464: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2319,126 +2485,424 @@
 done
 
 
-
-echo $ac_n "checking if realloc can deal with NULL""... $ac_c" 1>&6
-echo "configure:2325: checking if realloc can deal with NULL" >&5
-if eval "test \"`echo '$''{'rd_cv_null_realloc'+set}'`\" = set"; then
+for ac_func in fpclassify
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2492: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  if test "$cross_compiling" = yes; then
-  :
-else
   cat > conftest.$ac_ext <<EOF
-#line 2333 "configure"
+#line 2497 "configure"
 #include "confdefs.h"
-#include <stdlib.h>
-	      int main(void){
-              char *x = NULL;
-	      x = realloc (x,10);
-	      if (x==NULL) return 1;
-	      return 0;
-             }
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
 EOF
-if { (eval echo configure:2343: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
-  rd_cv_null_realloc=yes
+if { (eval echo configure:2520: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
-  rm -fr conftest*
-  rd_cv_null_realloc=nope
-fi
-rm -fr conftest*
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
 fi
-
+rm -f conftest*
 fi
 
-echo "$ac_t""$rd_cv_null_realloc" 1>&6
-
-if test x"$rd_cv_null_realloc" = xnope; then
-cat >> confdefs.h <<\EOF
-#define NO_NULL_REALLOC 1
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for fpclassify with <math.h>""... $ac_c" 1>&6
+echo "configure:2542: checking for fpclassify with <math.h>" >&5
+    cat > conftest.$ac_ext <<EOF
+#line 2544 "configure"
+#include "confdefs.h"
+#include <math.h>
+int main() {
+float f = 0.0; fpclassify(f)
+; return 0; }
+EOF
+if { (eval echo configure:2551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6
+      cat >> confdefs.h <<\EOF
+#define HAVE_FPCLASSIFY 1
 EOF
 
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  echo "$ac_t""no" 1>&6
 fi
+rm -f conftest*
+fi
+done
 
-
-
-
-oCFLAGS=$CFLAGS
-unset CFLAGS
-
-echo $ac_n "checking if IEEE math works out of the box""... $ac_c" 1>&6
-echo "configure:2373: checking if IEEE math works out of the box" >&5
-if eval "test \"`echo '$''{'rd_cv_ieee_works'+set}'`\" = set"; then
+for ac_func in finite
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2571: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  if test "$cross_compiling" = yes; then
-  :
-else
   cat > conftest.$ac_ext <<EOF
-#line 2381 "configure"
+#line 2576 "configure"
 #include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
 
+int main() {
 
-#if HAVE_MATH_H
-#  include <math.h>                                                                                                                                        
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2599: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+for ac_func in isfinite
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2623: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2628 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2651: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for isfinite with <math.h>""... $ac_c" 1>&6
+echo "configure:2673: checking for isfinite with <math.h>" >&5
+    cat > conftest.$ac_ext <<EOF
+#line 2675 "configure"
+#include "confdefs.h"
+#include <math.h>
+int main() {
+float f = 0.0; isfinite(f)
+; return 0; }
+EOF
+if { (eval echo configure:2682: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6
+      cat >> confdefs.h <<\EOF
+#define HAVE_ISFINITE 1
+EOF
+
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+fi
+done
+
+fi
+done
+
+for ac_func in isinf
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2705: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2710 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2733: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for isinf with <math.h>""... $ac_c" 1>&6
+echo "configure:2755: checking for isinf with <math.h>" >&5
+    cat > conftest.$ac_ext <<EOF
+#line 2757 "configure"
+#include "confdefs.h"
+#include <math.h>
+int main() {
+float f = 0.0; isinf(f)
+; return 0; }
+EOF
+if { (eval echo configure:2764: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6
+      cat >> confdefs.h <<\EOF
+#define HAVE_ISINF 1
+EOF
+
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+fi
+done
+
+
+
+echo $ac_n "checking if realloc can deal with NULL""... $ac_c" 1>&6
+echo "configure:2784: checking if realloc can deal with NULL" >&5
+if eval "test \"`echo '$''{'rd_cv_null_realloc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2792 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+	      int main(void){
+              char *x = NULL;
+	      x = realloc (x,10);
+	      if (x==NULL) return 1;
+	      return 0;
+             }
+EOF
+if { (eval echo configure:2802: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  rd_cv_null_realloc=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  rd_cv_null_realloc=nope
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$rd_cv_null_realloc" 1>&6
+
+if test x"$rd_cv_null_realloc" = xnope; then
+cat >> confdefs.h <<\EOF
+#define NO_NULL_REALLOC 1
+EOF
+
+fi
+
+
+
+
+_cflags=${CFLAGS}
+echo $ac_n "checking if IEEE math works out of the box""... $ac_c" 1>&6
+echo "configure:2830: checking if IEEE math works out of the box" >&5
+if eval "test \"`echo '$''{'rd_cv_ieee_works'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2838 "configure"
+#include "confdefs.h"
+
+
+#if HAVE_MATH_H
+#  include <math.h>
 #endif
 
 #if HAVE_FLOAT_H
 #  include <float.h>  
 #endif
 
-/* for solaris */
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
 #  define HAVE_ISINF 1
-#  include <ieeefp.h>
 #  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
 #endif
-/* for dec unix */
+
+/* Digital UNIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
 #  define HAVE_ISINF 1
-#  include <fp_class.h>
 #  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
-/* for HP-UX 10.20 */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
-/* for AIX */
+#endif 
+
+/* AIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
 #  define HAVE_ISINF 1
 #  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
 #endif
 
-#if (! defined(HAVE_FINITE) && defined(HAVE_ISNAN) && defined(HAVE_ISINF))
-#  define HAVE_FINITE 1
-#  define finite(a) (! isnan(a) && ! isinf(a))
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
 #endif
 
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
 
 #include <stdio.h>
 int main(void){
-    double nan,inf,c,d;
-     ;
-     /* some math to see if we get a segfault; */
-     nan=0.0/0.0;
-     inf=1.0/0.0;
-     c = 1.0;
-     c = c / 0.0; /* try getting fpe */
-     c = inf + nan;
-     c = inf / nan;
-     if (! isnan(nan)) {printf ("isnan(NaN) ... "); return 1;}
-     if (nan == nan) {printf ("nan != nan ..."); return 1;}
-     if (! isinf(inf)) {printf ("isinf(oo) ... "); return 1;}
-     if (! isinf(-inf)) {printf ("isinf(-oo) ... "); return 1;}
-     if (! inf > 0) {printf ("inf > 0 ... "); return 1;}
-     if (! -inf < 0) {printf ("inf < 0 ... "); return 1;}
-     return 0;
-}
+    double nan,inf,c,zero;
+    ;
+    /* some math to see if we get a floating point exception */
+    zero=sin(0.0); /* don't let the compiler optimize us away */
+    nan=0.0/zero; /* especially here */
+    inf=1.0/zero; /* and here. I want to know if it can do the magic */
+		  /* at run time without sig fpe */
+    c = inf + nan;
+    c = inf / nan;
+    if (! isnan(nan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (nan == nan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(inf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-inf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! inf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -inf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
 EOF
-if { (eval echo configure:2442: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2906: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   rd_cv_ieee_works=yes
 else
@@ -2452,12 +2916,14 @@
 
 fi
 
-echo "$ac_t""$rd_cv_ieee_works" 1>&6
-if test "$rd_cv_ieee_works" != yes ; then
-
-CFLAGS=-ieee
-echo $ac_n "checking if IEEE math works with the -ieee switch""... $ac_c" 1>&6
-echo "configure:2461: checking if IEEE math works with the -ieee switch" >&5
+if test x${rd_cv_ieee_works} = "xyes"; then
+ echo "$ac_t""yes" 1>&6
+ 
+else
+ echo "$ac_t""no" 1>&6
+ CFLAGS="$_cflags -ieee"
+  echo $ac_n "checking if IEEE math works with the -ieee switch""... $ac_c" 1>&6
+echo "configure:2927: checking if IEEE math works with the -ieee switch" >&5
 if eval "test \"`echo '$''{'rd_cv_ieee_switch'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2465,68 +2931,75 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2469 "configure"
+#line 2935 "configure"
 #include "confdefs.h"
 
 
 #if HAVE_MATH_H
-#  include <math.h>                                                                                                                                        
+#  include <math.h>
 #endif
 
 #if HAVE_FLOAT_H
 #  include <float.h>  
 #endif
 
-/* for solaris */
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
 #  define HAVE_ISINF 1
-#  include <ieeefp.h>
 #  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
 #endif
-/* for dec unix */
+
+/* Digital UNIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
 #  define HAVE_ISINF 1
-#  include <fp_class.h>
 #  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
-/* for HP-UX 10.20 */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
-/* for AIX */
+#endif 
+
+/* AIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
 #  define HAVE_ISINF 1
 #  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
 #endif
 
-#if (! defined(HAVE_FINITE) && defined(HAVE_ISNAN) && defined(HAVE_ISINF))
-#  define HAVE_FINITE 1
-#  define finite(a) (! isnan(a) && ! isinf(a))
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
 #endif
 
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
 
 #include <stdio.h>
 int main(void){
-    double nan,inf,c,d;
-     ;
-     /* some math to see if we get a segfault; */
-     nan=0.0/0.0;
-     inf=1.0/0.0;
-     c = 1.0;
-     c = c / 0.0; /* try getting fpe */
-     c = inf + nan;
-     c = inf / nan;
-     if (! isnan(nan)) {printf ("isnan(NaN) ... "); return 1;}
-     if (nan == nan) {printf ("nan != nan ..."); return 1;}
-     if (! isinf(inf)) {printf ("isinf(oo) ... "); return 1;}
-     if (! isinf(-inf)) {printf ("isinf(-oo) ... "); return 1;}
-     if (! inf > 0) {printf ("inf > 0 ... "); return 1;}
-     if (! -inf < 0) {printf ("inf < 0 ... "); return 1;}
-     return 0;
-}
+    double nan,inf,c,zero;
+    ;
+    /* some math to see if we get a floating point exception */
+    zero=sin(0.0); /* don't let the compiler optimize us away */
+    nan=0.0/zero; /* especially here */
+    inf=1.0/zero; /* and here. I want to know if it can do the magic */
+		  /* at run time without sig fpe */
+    c = inf + nan;
+    c = inf / nan;
+    if (! isnan(nan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (nan == nan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(inf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-inf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! inf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -inf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
 EOF
-if { (eval echo configure:2530: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3003: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   rd_cv_ieee_switch=yes
 else
@@ -2540,12 +3013,14 @@
 
 fi
 
-echo "$ac_t""$rd_cv_ieee_switch" 1>&6
-if test "$rd_cv_ieee_switch" != yes ; then
-
-CFLAGS=-qfloat=nofold
-echo $ac_n "checking if IEEE math works with the -qfloat=nofold switch""... $ac_c" 1>&6
-echo "configure:2549: checking if IEEE math works with the -qfloat=nofold switch" >&5
+if test x${rd_cv_ieee_switch} = "xyes"; then
+ echo "$ac_t""yes" 1>&6
+ 
+else
+ echo "$ac_t""no" 1>&6
+ CFLAGS="$_cflags -qfloat=nofold"
+    echo $ac_n "checking if IEEE math works with the -qfloat=nofold switch""... $ac_c" 1>&6
+echo "configure:3024: checking if IEEE math works with the -qfloat=nofold switch" >&5
 if eval "test \"`echo '$''{'rd_cv_ieee_nofold'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2553,68 +3028,75 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2557 "configure"
+#line 3032 "configure"
 #include "confdefs.h"
 
 
 #if HAVE_MATH_H
-#  include <math.h>                                                                                                                                        
+#  include <math.h>
 #endif
 
 #if HAVE_FLOAT_H
 #  include <float.h>  
 #endif
 
-/* for solaris */
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
 #  define HAVE_ISINF 1
-#  include <ieeefp.h>
 #  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
 #endif
-/* for dec unix */
+
+/* Digital UNIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
 #  define HAVE_ISINF 1
-#  include <fp_class.h>
 #  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
-/* for HP-UX 10.20 */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
-/* for AIX */
+#endif 
+
+/* AIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
 #  define HAVE_ISINF 1
 #  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
 #endif
 
-#if (! defined(HAVE_FINITE) && defined(HAVE_ISNAN) && defined(HAVE_ISINF))
-#  define HAVE_FINITE 1
-#  define finite(a) (! isnan(a) && ! isinf(a))
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
 #endif
 
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
 
 #include <stdio.h>
 int main(void){
-    double nan,inf,c,d;
-     ;
-     /* some math to see if we get a segfault; */
-     nan=0.0/0.0;
-     inf=1.0/0.0;
-     c = 1.0;
-     c = c / 0.0; /* try getting fpe */
-     c = inf + nan;
-     c = inf / nan;
-     if (! isnan(nan)) {printf ("isnan(NaN) ... "); return 1;}
-     if (nan == nan) {printf ("nan != nan ..."); return 1;}
-     if (! isinf(inf)) {printf ("isinf(oo) ... "); return 1;}
-     if (! isinf(-inf)) {printf ("isinf(-oo) ... "); return 1;}
-     if (! inf > 0) {printf ("inf > 0 ... "); return 1;}
-     if (! -inf < 0) {printf ("inf < 0 ... "); return 1;}
-     return 0;
-}
+    double nan,inf,c,zero;
+    ;
+    /* some math to see if we get a floating point exception */
+    zero=sin(0.0); /* don't let the compiler optimize us away */
+    nan=0.0/zero; /* especially here */
+    inf=1.0/zero; /* and here. I want to know if it can do the magic */
+		  /* at run time without sig fpe */
+    c = inf + nan;
+    c = inf / nan;
+    if (! isnan(nan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (nan == nan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(inf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-inf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! inf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -inf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
 EOF
-if { (eval echo configure:2618: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3100: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   rd_cv_ieee_nofold=yes
 else
@@ -2628,12 +3110,14 @@
 
 fi
 
-echo "$ac_t""$rd_cv_ieee_nofold" 1>&6
-if test "$rd_cv_ieee_nofold" != yes ; then
-
-CFLAGS="-w -qflttrap=enable:zerodivide"
-echo $ac_n "checking if IEEE math works with the -w -qflttrap=enable:zerodivide""... $ac_c" 1>&6
-echo "configure:2637: checking if IEEE math works with the -w -qflttrap=enable:zerodivide" >&5
+if test x${rd_cv_ieee_nofold} = "xyes"; then
+ echo "$ac_t""yes" 1>&6
+ 
+else
+ echo "$ac_t""no" 1>&6
+ CFLAGS="$_cflags -w -qflttrap=enable:zerodivide"
+      echo $ac_n "checking if IEEE math works with the -w -qflttrap=enable:zerodivide""... $ac_c" 1>&6
+echo "configure:3121: checking if IEEE math works with the -w -qflttrap=enable:zerodivide" >&5
 if eval "test \"`echo '$''{'rd_cv_ieee_flttrap'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2641,68 +3125,75 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2645 "configure"
+#line 3129 "configure"
 #include "confdefs.h"
 
 
 #if HAVE_MATH_H
-#  include <math.h>                                                                                                                                        
+#  include <math.h>
 #endif
 
 #if HAVE_FLOAT_H
 #  include <float.h>  
 #endif
 
-/* for solaris */
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
 #  define HAVE_ISINF 1
-#  include <ieeefp.h>
 #  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
 #endif
-/* for dec unix */
+
+/* Digital UNIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
 #  define HAVE_ISINF 1
-#  include <fp_class.h>
 #  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
-/* for HP-UX 10.20 */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
-/* for AIX */
+#endif 
+
+/* AIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
 #  define HAVE_ISINF 1
 #  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
 #endif
 
-#if (! defined(HAVE_FINITE) && defined(HAVE_ISNAN) && defined(HAVE_ISINF))
-#  define HAVE_FINITE 1
-#  define finite(a) (! isnan(a) && ! isinf(a))
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
 #endif
 
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
 
 #include <stdio.h>
 int main(void){
-    double nan,inf,c,d;
-     ;
-     /* some math to see if we get a segfault; */
-     nan=0.0/0.0;
-     inf=1.0/0.0;
-     c = 1.0;
-     c = c / 0.0; /* try getting fpe */
-     c = inf + nan;
-     c = inf / nan;
-     if (! isnan(nan)) {printf ("isnan(NaN) ... "); return 1;}
-     if (nan == nan) {printf ("nan != nan ..."); return 1;}
-     if (! isinf(inf)) {printf ("isinf(oo) ... "); return 1;}
-     if (! isinf(-inf)) {printf ("isinf(-oo) ... "); return 1;}
-     if (! inf > 0) {printf ("inf > 0 ... "); return 1;}
-     if (! -inf < 0) {printf ("inf < 0 ... "); return 1;}
-     return 0;
-}
+    double nan,inf,c,zero;
+    ;
+    /* some math to see if we get a floating point exception */
+    zero=sin(0.0); /* don't let the compiler optimize us away */
+    nan=0.0/zero; /* especially here */
+    inf=1.0/zero; /* and here. I want to know if it can do the magic */
+		  /* at run time without sig fpe */
+    c = inf + nan;
+    c = inf / nan;
+    if (! isnan(nan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (nan == nan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(inf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-inf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! inf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -inf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
 EOF
-if { (eval echo configure:2706: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3197: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   rd_cv_ieee_flttrap=yes
 else
@@ -2716,12 +3207,14 @@
 
 fi
 
-echo "$ac_t""$rd_cv_ieee_flttrap" 1>&6
-if test "$rd_cv_ieee_flttrap" != yes ; then
-
-CFLAGS=-mieee
-echo $ac_n "checking if IEEE math works with the -mieee switch""... $ac_c" 1>&6
-echo "configure:2725: checking if IEEE math works with the -mieee switch" >&5
+if test x${rd_cv_ieee_flttrap} = "xyes"; then
+ echo "$ac_t""yes" 1>&6
+ 
+else
+ echo "$ac_t""no" 1>&6
+ CFLAGS="$_cflags -mieee"
+       echo $ac_n "checking if IEEE math works with the -mieee switch""... $ac_c" 1>&6
+echo "configure:3218: checking if IEEE math works with the -mieee switch" >&5
 if eval "test \"`echo '$''{'rd_cv_ieee_mswitch'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2729,68 +3222,75 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2733 "configure"
+#line 3226 "configure"
 #include "confdefs.h"
 
 
 #if HAVE_MATH_H
-#  include <math.h>                                                                                                                                        
+#  include <math.h>
 #endif
 
 #if HAVE_FLOAT_H
 #  include <float.h>  
 #endif
 
-/* for solaris */
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
 #  define HAVE_ISINF 1
-#  include <ieeefp.h>
 #  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
 #endif
-/* for dec unix */
+
+/* Digital UNIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
 #  define HAVE_ISINF 1
-#  include <fp_class.h>
 #  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
-/* for HP-UX 10.20 */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
-/* for AIX */
+#endif 
+
+/* AIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
 #  define HAVE_ISINF 1
 #  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
 #endif
 
-#if (! defined(HAVE_FINITE) && defined(HAVE_ISNAN) && defined(HAVE_ISINF))
-#  define HAVE_FINITE 1
-#  define finite(a) (! isnan(a) && ! isinf(a))
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
 #endif
 
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
 
 #include <stdio.h>
 int main(void){
-    double nan,inf,c,d;
-     ;
-     /* some math to see if we get a segfault; */
-     nan=0.0/0.0;
-     inf=1.0/0.0;
-     c = 1.0;
-     c = c / 0.0; /* try getting fpe */
-     c = inf + nan;
-     c = inf / nan;
-     if (! isnan(nan)) {printf ("isnan(NaN) ... "); return 1;}
-     if (nan == nan) {printf ("nan != nan ..."); return 1;}
-     if (! isinf(inf)) {printf ("isinf(oo) ... "); return 1;}
-     if (! isinf(-inf)) {printf ("isinf(-oo) ... "); return 1;}
-     if (! inf > 0) {printf ("inf > 0 ... "); return 1;}
-     if (! -inf < 0) {printf ("inf < 0 ... "); return 1;}
-     return 0;
-}
+    double nan,inf,c,zero;
+    ;
+    /* some math to see if we get a floating point exception */
+    zero=sin(0.0); /* don't let the compiler optimize us away */
+    nan=0.0/zero; /* especially here */
+    inf=1.0/zero; /* and here. I want to know if it can do the magic */
+		  /* at run time without sig fpe */
+    c = inf + nan;
+    c = inf / nan;
+    if (! isnan(nan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (nan == nan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(inf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-inf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! inf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -inf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
 EOF
-if { (eval echo configure:2794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3294: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   rd_cv_ieee_mswitch=yes
 else
@@ -2804,12 +3304,14 @@
 
 fi
 
-echo "$ac_t""$rd_cv_ieee_mswitch" 1>&6
-if test "$rd_cv_ieee_mswitch" != yes ; then
-
-CFLAGS="-q float=rndsngl"
-echo $ac_n "checking if IEEE math works with the -q float=rndsngl switch""... $ac_c" 1>&6
-echo "configure:2813: checking if IEEE math works with the -q float=rndsngl switch" >&5
+if test x${rd_cv_ieee_mswitch} = "xyes"; then
+ echo "$ac_t""yes" 1>&6
+ 
+else
+ echo "$ac_t""no" 1>&6
+ CFLAGS="$_cflags -q float=rndsngl"
+         echo $ac_n "checking if IEEE math works with the -q float=rndsngl switch""... $ac_c" 1>&6
+echo "configure:3315: checking if IEEE math works with the -q float=rndsngl switch" >&5
 if eval "test \"`echo '$''{'rd_cv_ieee_qswitch'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2817,68 +3319,75 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2821 "configure"
+#line 3323 "configure"
 #include "confdefs.h"
 
 
 #if HAVE_MATH_H
-#  include <math.h>                                                                                                                                        
+#  include <math.h>
 #endif
 
 #if HAVE_FLOAT_H
 #  include <float.h>  
 #endif
 
-/* for solaris */
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
 #  define HAVE_ISINF 1
-#  include <ieeefp.h>
 #  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
 #endif
-/* for dec unix */
+
+/* Digital UNIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
 #  define HAVE_ISINF 1
-#  include <fp_class.h>
 #  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
-/* for HP-UX 10.20 */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
-/* for AIX */
+#endif 
+
+/* AIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
 #  define HAVE_ISINF 1
 #  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
 #endif
 
-#if (! defined(HAVE_FINITE) && defined(HAVE_ISNAN) && defined(HAVE_ISINF))
-#  define HAVE_FINITE 1
-#  define finite(a) (! isnan(a) && ! isinf(a))
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
 #endif
 
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
 
 #include <stdio.h>
 int main(void){
-    double nan,inf,c,d;
-     ;
-     /* some math to see if we get a segfault; */
-     nan=0.0/0.0;
-     inf=1.0/0.0;
-     c = 1.0;
-     c = c / 0.0; /* try getting fpe */
-     c = inf + nan;
-     c = inf / nan;
-     if (! isnan(nan)) {printf ("isnan(NaN) ... "); return 1;}
-     if (nan == nan) {printf ("nan != nan ..."); return 1;}
-     if (! isinf(inf)) {printf ("isinf(oo) ... "); return 1;}
-     if (! isinf(-inf)) {printf ("isinf(-oo) ... "); return 1;}
-     if (! inf > 0) {printf ("inf > 0 ... "); return 1;}
-     if (! -inf < 0) {printf ("inf < 0 ... "); return 1;}
-     return 0;
-}
+    double nan,inf,c,zero;
+    ;
+    /* some math to see if we get a floating point exception */
+    zero=sin(0.0); /* don't let the compiler optimize us away */
+    nan=0.0/zero; /* especially here */
+    inf=1.0/zero; /* and here. I want to know if it can do the magic */
+		  /* at run time without sig fpe */
+    c = inf + nan;
+    c = inf / nan;
+    if (! isnan(nan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (nan == nan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(inf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-inf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! inf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -inf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
 EOF
-if { (eval echo configure:2882: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3391: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   rd_cv_ieee_qswitch=yes
 else
@@ -2892,81 +3401,187 @@
 
 fi
 
-echo "$ac_t""$rd_cv_ieee_qswitch" 1>&6
-if test "$rd_cv_ieee_qswitch" != yes ; then
-
-unset CFLAGS
-echo $ac_n "checking if IEEE math works with fpsetmask(0)""... $ac_c" 1>&6
-echo "configure:2901: checking if IEEE math works with fpsetmask(0)" >&5
-if eval "test \"`echo '$''{'rd_cv_ieee_mask'+set}'`\" = set"; then
+if test x${rd_cv_ieee_qswitch} = "xyes"; then
+ echo "$ac_t""yes" 1>&6
+ 
+else
+ echo "$ac_t""no" 1>&6
+ CFLAGS="$_cflags -OPT:IEEE_comparisons=ON"
+           echo $ac_n "checking if IEEE math works with the -OPT:IEEE_comparisons=ON switch""... $ac_c" 1>&6
+echo "configure:3412: checking if IEEE math works with the -OPT:IEEE_comparisons=ON switch" >&5
+if eval "test \"`echo '$''{'rd_cv_ieee_ieeecmpswitch'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2909 "configure"
+#line 3420 "configure"
 #include "confdefs.h"
-#include <floatingpoint.h>
+
 
 #if HAVE_MATH_H
-#  include <math.h>                                                                                                                                        
+#  include <math.h>
 #endif
 
 #if HAVE_FLOAT_H
 #  include <float.h>  
 #endif
 
-/* for solaris */
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
 #  define HAVE_ISINF 1
-#  include <ieeefp.h>
 #  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
 #endif
-/* for dec unix */
+
+/* Digital UNIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
 #  define HAVE_ISINF 1
-#  include <fp_class.h>
 #  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#endif 
+
+/* AIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
 #endif
-/* for HP-UX 10.20 */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY))
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
 #  define HAVE_ISINF 1
 #  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
 #endif
-/* for AIX */
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
+
+#include <stdio.h>
+int main(void){
+    double nan,inf,c,zero;
+    ;
+    /* some math to see if we get a floating point exception */
+    zero=sin(0.0); /* don't let the compiler optimize us away */
+    nan=0.0/zero; /* especially here */
+    inf=1.0/zero; /* and here. I want to know if it can do the magic */
+		  /* at run time without sig fpe */
+    c = inf + nan;
+    c = inf / nan;
+    if (! isnan(nan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (nan == nan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(inf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-inf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! inf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -inf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
+EOF
+if { (eval echo configure:3488: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  rd_cv_ieee_ieeecmpswitch=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  rd_cv_ieee_ieeecmpswitch=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+if test x${rd_cv_ieee_ieeecmpswitch} = "xyes"; then
+ echo "$ac_t""yes" 1>&6
+ 
+else
+ echo "$ac_t""no" 1>&6
+ CFLAGS=$_cflags
+             echo $ac_n "checking if IEEE math works with fpsetmask(0)""... $ac_c" 1>&6
+echo "configure:3509: checking if IEEE math works with fpsetmask(0)" >&5
+if eval "test \"`echo '$''{'rd_cv_ieee_mask'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3517 "configure"
+#include "confdefs.h"
+#include <floatingpoint.h>
+
+#if HAVE_MATH_H
+#  include <math.h>
+#endif
+
+#if HAVE_FLOAT_H
+#  include <float.h>  
+#endif
+
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
+#endif
+
+/* Digital UNIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#endif 
+
+/* AIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
 #  define HAVE_ISINF 1
 #  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
 #endif
 
-#if (! defined(HAVE_FINITE) && defined(HAVE_ISNAN) && defined(HAVE_ISINF))
-#  define HAVE_FINITE 1
-#  define finite(a) (! isnan(a) && ! isinf(a))
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
 #endif
 
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
 
 #include <stdio.h>
 int main(void){
-    double nan,inf,c,d;
-     fpsetmask(0);
-     /* some math to see if we get a segfault; */
-     nan=0.0/0.0;
-     inf=1.0/0.0;
-     c = 1.0;
-     c = c / 0.0; /* try getting fpe */
-     c = inf + nan;
-     c = inf / nan;
-     if (! isnan(nan)) {printf ("isnan(NaN) ... "); return 1;}
-     if (nan == nan) {printf ("nan != nan ..."); return 1;}
-     if (! isinf(inf)) {printf ("isinf(oo) ... "); return 1;}
-     if (! isinf(-inf)) {printf ("isinf(-oo) ... "); return 1;}
-     if (! inf > 0) {printf ("inf > 0 ... "); return 1;}
-     if (! -inf < 0) {printf ("inf < 0 ... "); return 1;}
-     return 0;
-}
+    double nan,inf,c,zero;
+    fpsetmask(0);
+    /* some math to see if we get a floating point exception */
+    zero=sin(0.0); /* don't let the compiler optimize us away */
+    nan=0.0/zero; /* especially here */
+    inf=1.0/zero; /* and here. I want to know if it can do the magic */
+		  /* at run time without sig fpe */
+    c = inf + nan;
+    c = inf / nan;
+    if (! isnan(nan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (nan == nan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(inf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-inf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! inf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -inf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
 EOF
-if { (eval echo configure:2970: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3585: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   rd_cv_ieee_mask=yes
 else
@@ -2980,11 +3595,17 @@
 
 fi
 
-echo "$ac_t""$rd_cv_ieee_mask" 1>&6
-if test "$rd_cv_ieee_mask" != yes ; then
+if test x${rd_cv_ieee_mask} = "xyes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define MUST_DISABLE_FPMASK 1
+EOF
 
-echo $ac_n "checking if IEEE math works with signal(SIGFPE,SIG_IGN)""... $ac_c" 1>&6
-echo "configure:2988: checking if IEEE math works with signal(SIGFPE,SIG_IGN)" >&5
+	       PERLFLAGS="CCFLAGS=-DMUST_DISABLE_FPMASK"
+else
+ echo "$ac_t""no" 1>&6
+ echo $ac_n "checking if IEEE math works with signal(SIGFPE,SIG_IGN)""... $ac_c" 1>&6
+echo "configure:3609: checking if IEEE math works with signal(SIGFPE,SIG_IGN)" >&5
 if eval "test \"`echo '$''{'rd_cv_ieee_sigfpe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2992,68 +3613,75 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2996 "configure"
+#line 3617 "configure"
 #include "confdefs.h"
 #include <signal.h>
 
 #if HAVE_MATH_H
-#  include <math.h>                                                                                                                                        
+#  include <math.h>
 #endif
 
 #if HAVE_FLOAT_H
 #  include <float.h>  
 #endif
 
-/* for solaris */
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
 #  define HAVE_ISINF 1
-#  include <ieeefp.h>
 #  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
 #endif
-/* for dec unix */
+
+/* Digital UNIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
 #  define HAVE_ISINF 1
-#  include <fp_class.h>
 #  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
-/* for HP-UX 10.20 */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
-/* for AIX */
+#endif 
+
+/* AIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
 #  define HAVE_ISINF 1
 #  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
 #endif
 
-#if (! defined(HAVE_FINITE) && defined(HAVE_ISNAN) && defined(HAVE_ISINF))
-#  define HAVE_FINITE 1
-#  define finite(a) (! isnan(a) && ! isinf(a))
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
 #endif
 
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
 
 #include <stdio.h>
 int main(void){
-    double nan,inf,c,d;
-     signal(SIGFPE,SIG_IGN);
-     /* some math to see if we get a segfault; */
-     nan=0.0/0.0;
-     inf=1.0/0.0;
-     c = 1.0;
-     c = c / 0.0; /* try getting fpe */
-     c = inf + nan;
-     c = inf / nan;
-     if (! isnan(nan)) {printf ("isnan(NaN) ... "); return 1;}
-     if (nan == nan) {printf ("nan != nan ..."); return 1;}
-     if (! isinf(inf)) {printf ("isinf(oo) ... "); return 1;}
-     if (! isinf(-inf)) {printf ("isinf(-oo) ... "); return 1;}
-     if (! inf > 0) {printf ("inf > 0 ... "); return 1;}
-     if (! -inf < 0) {printf ("inf < 0 ... "); return 1;}
-     return 0;
-}
+    double nan,inf,c,zero;
+    signal(SIGFPE,SIG_IGN);
+    /* some math to see if we get a floating point exception */
+    zero=sin(0.0); /* don't let the compiler optimize us away */
+    nan=0.0/zero; /* especially here */
+    inf=1.0/zero; /* and here. I want to know if it can do the magic */
+		  /* at run time without sig fpe */
+    c = inf + nan;
+    c = inf / nan;
+    if (! isnan(nan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (nan == nan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(inf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-inf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! inf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -inf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
 EOF
-if { (eval echo configure:3057: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3685: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   rd_cv_ieee_sigfpe=yes
 else
@@ -3067,65 +3695,49 @@
 
 fi
 
-echo "$ac_t""$rd_cv_ieee_sigfpe" 1>&6
-if test "$rd_cv_ieee_sigfpe" != yes ; then
-
+if test x${rd_cv_ieee_sigfpe} = "xyes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define MUST_DISABLE_SIGFPE 1
+EOF
 
-echo "--------------------------------------------------------------"
-echo "Your Compiler does not do propper IEEE math ... "
-echo "Please find out how to make IEEE math work with your Compiler"
-echo "and let me know (oetiker at ee.ethz.ch)"
-echo "Check config.log to see what went wrong ..."
-echo ""
-exit 1
-       fi
-      fi
-     fi
-    fi
-   fi
-  fi
- fi
+                 PERLFLAGS="CCFLAGS=-DMUST_DISABLE_SIGFPE"
+else
+ echo "$ac_t""no" 1>&6
+ { echo "configure: error: 
+Your Compiler does not do propper IEEE math ... Please find out how to
+make IEEE math work with your compiler and let me know (oetiker at ee.ethz.ch).
+Check config.log to see what went wrong ...
+" 1>&2; exit 1; }
 fi
 
-CFLAGS=$oCFLAGS
 
-if test x$rd_cv_ieee_sigfpe = xyes; then
-   cat >> confdefs.h <<\EOF
-#define MUST_DISABLE_SIGFPE 1
-EOF
+fi
+
 
 fi
 
-if test x$rd_cv_ieee_mask = xyes; then
-   cat >> confdefs.h <<\EOF
-#define MUST_DISABLE_FPMASK 1
-EOF
 
-   CFLAGS="$CFLAGS -DMUST_DISABLE_FPMASK"
 fi
 
-if test x$rd_cv_ieee_switch = xyes; then
-   CFLAGS="$CFLAGS -ieee"
+
 fi
 
-if test x$rd_cv_ieee_nofold = xyes; then
-   CFLAGS="$CFLAGS -qfloat=nofold"
+
 fi
 
-if test x$rd_cv_ieee_flttrap = xyes; then
-   CFLAGS="$CFLAGS -w -qflttrap=enable:zerodivide"
+
 fi
 
-if test x$rd_cv_ieee_mswitch = xyes; then
-   CFLAGS="$CFLAGS -mieee"
+
 fi
 
-if test x$rd_cv_ieee_qswitch = xyes; then
-   CFLAGS="$CFLAGS -q float=rndsngl"
+
 fi
 
 
 
+
 trap '' 1 2 15
 cat > confcache <<\EOF
 # This file is a shell script that caches the results of configure
@@ -3238,24 +3850,18 @@
           examples/Makefile				\
           contrib/Makefile				\
           contrib/trytime/Makefile			\
-          contrib/log2rrd/Makefile			\
           contrib/log2rrd/log2rrd.pl			\
-          contrib/killspike/Makefile			\
           contrib/killspike/killspike.pl		\
-          contrib/rrdlastds/Makefile			\
           contrib/rrdlastds/rrdlastds.pl		\
-          contrib/rrdfetchnames/Makefile		\
           contrib/rrdfetchnames/rrdfetchnames.pl	\
-          contrib/add_ds/Makefile			\
           contrib/add_ds/add_ds.pl			\
 	  contrib/add_ds/batch.pl			\
-          contrib/rrd-file-icon/Makefile		\
-          contrib/rrdproc/Makefile			\
           doc/Makefile					\
           gd1.3/Makefile				\
-          libpng-1.0.3/Makefile				\
+          libpng-1.0.9/Makefile				\
           zlib-1.1.3/Makefile				\
           src/Makefile					\
+          tcl/Makefile					\
           Makefile config/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
 EOF
 cat >> $CONFIG_STATUS <<EOF
@@ -3318,15 +3924,26 @@
 s%@GD_LIB_DIR@%$GD_LIB_DIR%g
 s%@PNG_LIB_DIR@%$PNG_LIB_DIR%g
 s%@ZLIB_LIB_DIR@%$ZLIB_LIB_DIR%g
+s%@PERLFLAGS@%$PERLFLAGS%g
 s%@PERL@%$PERL%g
 s%@COMP_PERL@%$COMP_PERL%g
+s%@SO_EXT@%$SO_EXT%g
+s%@PERL_MAKE_OPTIONS@%$PERL_MAKE_OPTIONS%g
+s%@COMP_TCL_TRUE@%$COMP_TCL_TRUE%g
+s%@COMP_TCL_FALSE@%$COMP_TCL_FALSE%g
+s%@TCL_PREFIX@%$TCL_PREFIX%g
+s%@TCL_SHLIB_CFLAGS@%$TCL_SHLIB_CFLAGS%g
+s%@TCL_SHLIB_LD@%$TCL_SHLIB_LD%g
+s%@TCL_SHLIB_SUFFIX@%$TCL_SHLIB_SUFFIX%g
+s%@TCL_PACKAGE_PATH@%$TCL_PACKAGE_PATH%g
+s%@TCL_LD_SEARCH_FLAGS@%$TCL_LD_SEARCH_FLAGS%g
 s%@CC@%$CC%g
 s%@CPP@%$CPP%g
 s%@RANLIB@%$RANLIB%g
-s%@LD@%$LD%g
-s%@NM@%$NM%g
 s%@LN_S@%$LN_S%g
 s%@LIBTOOL@%$LIBTOOL%g
+s%@NROFF@%$NROFF%g
+s%@TROFF@%$TROFF%g
 
 CEOF
 EOF
@@ -3379,24 +3996,18 @@
           examples/Makefile				\
           contrib/Makefile				\
           contrib/trytime/Makefile			\
-          contrib/log2rrd/Makefile			\
           contrib/log2rrd/log2rrd.pl			\
-          contrib/killspike/Makefile			\
           contrib/killspike/killspike.pl		\
-          contrib/rrdlastds/Makefile			\
           contrib/rrdlastds/rrdlastds.pl		\
-          contrib/rrdfetchnames/Makefile		\
           contrib/rrdfetchnames/rrdfetchnames.pl	\
-          contrib/add_ds/Makefile			\
           contrib/add_ds/add_ds.pl			\
 	  contrib/add_ds/batch.pl			\
-          contrib/rrd-file-icon/Makefile		\
-          contrib/rrdproc/Makefile			\
           doc/Makefile					\
           gd1.3/Makefile				\
-          libpng-1.0.3/Makefile				\
+          libpng-1.0.9/Makefile				\
           zlib-1.1.3/Makefile				\
           src/Makefile					\
+          tcl/Makefile					\
           Makefile"}
 EOF
 cat >> $CONFIG_STATUS <<\EOF
@@ -3580,10 +4191,10 @@
 
 
 echo $ac_n "checking in""... $ac_c" 1>&6
-echo "configure:3584: checking in" >&5
+echo "configure:4195: checking in" >&5
 echo "$ac_t""and out again" 1>&6
 
-echo $ac_n "ordering CD from http://ee-staff.ethz-ch/~oetiker/wish $ac_c" 1>&6
+echo $ac_n "ordering CD from http://ee-staff.ethz.ch/~oetiker/wish $ac_c" 1>&6
 sleep 1
 echo $ac_n ".$ac_c" 1>&6
 sleep 1
@@ -3599,13 +4210,14 @@
 echo "Config is DONE!"
 echo
 echo "Type 'make' to compile the software and use 'make install' to "
-echo "install everything to $prefix. If you want to install the perl"
+echo "install everything to: $prefix."
+echo
+echo "If you want to install the perl"
 echo "modules in site-perl, try 'make site-perl-install'."
 echo 
-echo "       ... that wishlist mentioned above does really exist. So if"
-echo "you feel like showing your appreciation for rrdtool this is the"
-echo "place to go. :-)"
+echo "       ... that wishlist is NO JOKE. If you find RRDtool useful"
+echo "make me happy. Go to http://ee-staff.ethz.ch/~oetiker/wish and"
+echo "place an order."
 echo 
-echo "                            -- Tobi Oetiker <oetiker at ee.ethz.ch>"
+echo "                               -- Tobi Oetiker <tobi at oetiker.ch>"
 echo "----------------------------------------------------------------"
-

Modified: trunk/orca/packages/rrdtool-1.0.33/Makefile.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/Makefile.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/Makefile.in	Sat Jul 13 21:25:50 2002
@@ -62,31 +62,42 @@
 target_alias = @target_alias@
 target_triplet = @target@
 CC = @CC@
-CFLAGS = @CFLAGS@
 CGI_LIB_DIR = @CGI_LIB_DIR@
 COMP_PERL = @COMP_PERL@
 CPP = @CPP@
 GD_LIB_DIR = @GD_LIB_DIR@
 LIBTOOL = @LIBTOOL@
+NROFF = @NROFF@
 PERL = @PERL@
+PERLFLAGS = @PERLFLAGS@
+PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PNG_LIB_DIR = @PNG_LIB_DIR@
 RANLIB = @RANLIB@
+SO_EXT = @SO_EXT@
+TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
+TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
+TCL_PREFIX = @TCL_PREFIX@
+TCL_SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@
+TCL_SHLIB_LD = @TCL_SHLIB_LD@
+TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+TROFF = @TROFF@
+VERSION = @VERSION@
 ZLIB_LIB_DIR = @ZLIB_LIB_DIR@
 
 RSYNC = rsync --rsh=ssh
+
 # build the following subdirectories
-SUBDIRS = cgilib-0.4 config gd1.3 zlib-1.1.3 libpng-1.0.3 src doc examples contrib
+SUBDIRS = cgilib-0.4 config gd1.3 zlib-1.1.3 libpng-1.0.9           src doc examples contrib tcl
 
-# the following files are not mentioned in any other Makefile
-EXTRA_DIST = COPYRIGHT CHANGES NT-BUILD-TIPS.txt TODO CONTRIBUTORS   perl-piped/MANIFEST perl-piped/README perl-piped/rrdpl.ds?  perl-piped/RRDp.pm perl-piped/Makefile.PL  perl-piped/t/base.t  perl-shared/MANIFEST perl-shared/README perl-shared/RRDs.xs  perl-shared/ntmake.pl perl-shared/Makefile.PL perl-shared/t/base.t  perl-shared/rrdpl.ds? perl-shared/RRDs.pm
 
+# the following files are not mentioned in any other Makefile
+EXTRA_DIST = COPYRIGHT CHANGES NT-BUILD-TIPS.txt TODO CONTRIBUTORS rrdtool.spec  perl-piped/MANIFEST perl-piped/README perl-piped/rrdpl.ds?  perl-piped/RRDp.pm perl-piped/Makefile.PL  perl-piped/t/base.t  perl-shared/MANIFEST perl-shared/README perl-shared/RRDs.xs  perl-shared/ntmake.pl perl-shared/Makefile.PL perl-shared/t/base.t  perl-shared/rrdpl.ds? perl-shared/RRDs.pm
 
-#
 
 CLEANFILES = config.cache
 
 # use relaxed rules when building dists
-AUTOMAKE_OPTIONS = foreign
+AUTOMAKE_OPTIONS = foreign no-dependencies
 
 # where we keep local rules for automake
 ACLOCAL_M4 = $(top_srcdir)/config/aclocal.m4
@@ -100,7 +111,6 @@
 
 
 PACKAGE = @PACKAGE@
-VERSION = @VERSION@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
@@ -109,7 +119,7 @@
 all: all-redirect
 .SUFFIXES:
 $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-	cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps Makefile
+	cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
 
 Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
 	cd $(top_builddir) \
@@ -281,7 +291,7 @@
 	@for file in $(DISTFILES); do \
 	  d=$(srcdir); \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$/$$file $(distdir)/$$file; \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
 	    test -f $(distdir)/$$file \
 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
@@ -373,42 +383,34 @@
 
 
 # lets schedule the perl stuff for installation
+# the special call to install-sh is because the -d switch is not portable
 install-data-local:
-	$(INSTALL) -d -m 755 $(prefix)/lib/perl/auto/RRDs
-	$(INSTALL) -m 644 perl-piped/RRDp.pm $(prefix)/lib/perl
-	$(INSTALL) -m 644 perl-shared/RRDs.pm $(prefix)/lib/perl
-	$(INSTALL) -m 644 perl-shared/blib/arch/auto/RRDs/RRDs.bs $(prefix)/lib/perl/auto/RRDs
-	$(INSTALL) -m 755 perl-shared/blib/arch/auto/RRDs/RRDs.so $(prefix)/lib/perl/auto/RRDs
+	./config/mkinstalldirs $(DESTDIR)$(prefix)/lib/perl/auto/RRDs
+	$(INSTALL) -m 644 perl-piped/RRDp.pm $(DESTDIR)$(prefix)/lib/perl
+	$(INSTALL) -m 644 perl-shared/RRDs.pm $(DESTDIR)$(prefix)/lib/perl
+	$(INSTALL) -m 644 perl-shared/blib/arch/auto/RRDs/RRDs.bs $(DESTDIR)$(prefix)/lib/perl/auto/RRDs
+	$(INSTALL) -m 755 perl-shared/blib/arch/auto/RRDs/RRDs. at SO_EXT@ $(DESTDIR)$(prefix)/lib/perl/auto/RRDs
 
 # rules for building the perl module
 perl_piped: perl-piped/Makefile
-	cd perl-piped && $(MAKE)  OPTIMIZE="$(CFLAGS)" CC="$(CC)"
+	cd perl-piped && $(MAKE)
 
 perl-piped/Makefile: perl-piped/Makefile.PL
-	cd perl-piped && $(PERL) Makefile.PL
+	cd perl-piped && $(PERL) Makefile.PL $(PERL_MAKE_OPTIONS)
 
 perl_shared: perl-shared/Makefile
-	cd perl-shared && $(MAKE) OPTIMIZE="$(CFLAGS)" CC="$(CC)"
+	cd perl-shared && $(MAKE)
 
 perl-shared/Makefile: perl-shared/Makefile.PL
-	cd perl-shared && $(PERL) Makefile.PL
+	cd perl-shared && $(PERL) Makefile.PL $(PERLFLAGS) $(PERL_MAKE_OPTIONS)
 
 # add the following to the all target
 all-local:	@COMP_PERL@
 
-# add to install
-
-#to-autoconf:
-#	aclocal -I config -I config/libtool --output=config/aclocal.m4
-#	automake --foreign
-#	autoconf --localdir=config
-#	autoheader --localdir=config
-#	./configure
-
 to-docs: to-versync
-	(cd doc && $(MAKE) clean && $(MAKE))
+	(cd doc && $(MAKE) clean && $(MAKE) && $(MAKE) pdf)
+	(cd website && wmk-1.7.4 -f manual tutorial contributors.wml && ./site-sync )
 
-#to-autoconf
 to-versync: 
 	perl -i -p -e '"$(VERSION)" =~ /(\d+)\.(\d+)\.(\d+)/; $$v=sprintf("%1d.%02d0%02d1" ,$${1},$${2},$${3}); s|VERSION\s*=\s*[\d.]+|VERSION = $$v|' perl-*/RRD?.pm
 	perl -i -p -e 's|RRDtool\s+\d+\.\d+\.\d+ |RRDtool $(VERSION) |' src/*.[ch]
@@ -417,8 +419,10 @@
 	mv $(PACKAGE)-$(VERSION).tar.gz archive
 
 to-scp: to-dist
-	$(RSYNC) CHANGES  archive/$(PACKAGE)-$(VERSION).tar.gz oetiker at tardis.ee.ethz.ch:/home/oetiker/public_html/webtools/rrdtool/pub/
-	$(RSYNC) CHANGES archive/$(PACKAGE)-$(VERSION).tar.gz tobi at ipn.caida.org:/ipn/web/Tools/RRDtool/pub/
+	cp CHANGES  archive/$(PACKAGE)-$(VERSION).tar.gz /home/oetiker/public_html/webtools/rrdtool/pub/
+	(cd /home/oetiker/public_html/webtools/rrdtool/pub; rm $(PACKAGE).tar.gz; ln -s $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE).tar.gz)
+
+#	$(RSYNC) CHANGES archive/$(PACKAGE)-$(VERSION).tar.gz tobi at ipn.caida.org:/ipn/web/Tools/RRDtool/pub/
 
 site-perl-inst: site-perl-install
 
@@ -426,6 +430,9 @@
 	cd perl-piped && $(MAKE) install
 	cd perl-shared && $(MAKE) install
 
+site-tcl-install:
+	cd tcl && $(MAKE) tcl-install
+
 clean-local:
 	cd perl-piped && test -f Makefile && $(MAKE) clean || true
 	cd perl-shared && test -f Makefile && $(MAKE) clean || true

Added: trunk/orca/packages/rrdtool-1.0.33/tcl/ifOctets.tcl
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/tcl/ifOctets.tcl	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/tcl/ifOctets.tcl	Sat Jul 13 21:25:50 2002
@@ -0,0 +1,45 @@
+#!/bin/sh
+# the next line restarts using tclsh -*- tcl -*- \
+exec tclsh8.2 "$0" "$@"
+
+#package require Tnm 3.0
+package require Rrd 1.0.13
+
+set rrdfile "[lindex $argv 0]-[lindex $argv 1].rrd"
+
+# create rrdfile if not yet existent
+if {[file exists $rrdfile] == 0} {
+    Rrd::create $rrdfile --step 5 \
+	    DS:inOctets:COUNTER:10:U:U DS:outOctets:COUNTER:10:U:U \
+	    RRA:AVERAGE:0.5:1:12
+}
+
+# get an snmp session context
+set session [Tnm::snmp generator -address [lindex $argv 0]]
+
+# walk through the ifDescr column to find the right interface
+$session walk descr IF-MIB!ifDescr {
+
+    # is this the right interface?
+    if {"[Tnm::snmp value $descr 0]" == "[lindex $argv 1]"} {
+
+	# get the instance part of this table row
+	set inst [lindex [Tnm::mib split [Tnm::snmp oid $descr 0]] 1]
+
+	# get the two interface's octet counter values
+	set in [lindex [lindex [$session get IF-MIB!ifInOctets.$inst] 0] 2]
+	set out [lindex [lindex [$session get IF-MIB!ifOutOctets.$inst] 0] 2]
+
+	# write the values to the rrd
+	puts "$in $out"
+	Rrd::update $rrdfile --template inOctets:outOctets N:$in:$out
+
+	Rrd::graph gaga.png --title "gaga" \
+		DEF:in=$rrdfile:inOctets:AVERAGE \
+		DEF:out=$rrdfile:outOctets:AVERAGE \
+		AREA:in#0000FF:inOctets \
+		LINE2:out#00C000:outOctets
+
+	#puts [Rrd::fetch $rrdfile AVERAGE]
+    }
+}

Added: trunk/orca/packages/rrdtool-1.0.33/tcl/Makefile.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/tcl/Makefile.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/tcl/Makefile.in	Sat Jul 13 21:25:50 2002
@@ -0,0 +1,224 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+CC = @CC@
+CGI_LIB_DIR = @CGI_LIB_DIR@
+COMP_PERL = @COMP_PERL@
+CPP = @CPP@
+LIBTOOL = @LIBTOOL@
+NROFF = @NROFF@
+PERL = @PERL@
+PERLFLAGS = @PERLFLAGS@
+PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
+PNG_LIB_DIR = @PNG_LIB_DIR@
+RANLIB = @RANLIB@
+SO_EXT = @SO_EXT@
+TROFF = @TROFF@
+ZLIB_LIB_DIR = @ZLIB_LIB_DIR@
+
+EXTRA_DIST = README ifOctets.tcl tclrrd.c
+CLEANFILES = tclrrd.o tclrrd.so
+
+VERSION = @VERSION@
+
+CFLAGS = @CFLAGS@
+TCL_PREFIX = @TCL_PREFIX@
+TCL_SHLIB_LD = @TCL_SHLIB_LD@
+TCL_SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@
+TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+TCL_PACKAGE_PATH = $(DESTDIR)@TCL_PACKAGE_PATH@
+TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
+GD_LIB_DIR = $(top_srcdir)/@GD_LIB_DIR@
+
+SRC_DIR = $(top_srcdir)/src
+INCLUDES = -I$(TCL_PREFIX)/include -I$(SRC_DIR)  -I$(GD_LIB_DIR)
+LIBDIRS = -L$(libdir) -L$(SRC_DIR)  -L../src/.libs
+LIB_RUNTIME_DIR = $(libdir)
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = ../config/config.h
+CONFIG_CLEAN_FILES = 
+DIST_COMMON =  README Makefile.am Makefile.in
+
+
+PACKAGE = @PACKAGE@
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+	cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps tcl/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+	cd $(top_builddir) \
+	  && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = tcl
+
+distdir: $(DISTFILES)
+	@for file in $(DISTFILES); do \
+	  d=$(srcdir); \
+	  if test -d $$d/$$file; then \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+	    || cp -p $$d/$$file $(distdir)/$$file || :; \
+	  fi; \
+	done
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile all-local
+all-redirect: all-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-rm -f Makefile $(CONFIG_CLEAN_FILES)
+	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am:  clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am:  distclean-generic clean-am
+	-rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am:  maintainer-clean-generic distclean-am
+	@echo "This command is intended for maintainers to use;"
+	@echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: tags distdir info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-local all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+ at COMP_TCL_TRUE@tclrrd$(TCL_SHLIB_SUFFIX): tclrrd.o
+ at COMP_TCL_TRUE@	$(TCL_SHLIB_LD) $(LIBDIRS) $< -o $@ -lrrd_private -lm
+
+ at COMP_TCL_TRUE@tclrrd.o: tclrrd.c
+ at COMP_TCL_TRUE@	$(CC) $(CFLAGS) $(TCL_SHLIB_CFLAGS) $(INCLUDES) -c $< -DVERSION=\"$(VERSION)\"
+
+ at COMP_TCL_TRUE@all-local: tclrrd$(TCL_SHLIB_SUFFIX)
+
+ at COMP_TCL_TRUE@tcl-install: tclrrd$(TCL_SHLIB_SUFFIX)
+ at COMP_TCL_TRUE@	cp tclrrd$(TCL_SHLIB_SUFFIX) $(TCL_PACKAGE_PATH)/tclrrd$(VERSION)$(TCL_SHLIB_SUFFIX)
+ at COMP_TCL_TRUE@	if [ ! -d $(TCL_PACKAGE_PATH)/tclrrd$(VERSION) ] ; then \
+ at COMP_TCL_TRUE@		mkdir $(TCL_PACKAGE_PATH)/tclrrd$(VERSION) ; \
+ at COMP_TCL_TRUE@	fi
+ at COMP_TCL_TRUE@	echo "package ifneeded Rrd $(VERSION) [list load [file join \$$dir .. tclrrd$(VERSION)$(TCL_SHLIB_SUFFIX)]]" > $(TCL_PACKAGE_PATH)/tclrrd$(VERSION)/pkgIndex.tcl
+
+ at COMP_TCL_FALSE@all-local:
+
+diff:
+	cd .. ; diff -c -u -r -N --exclude Makefile --exclude html --exclude doc --exclude Makefile.in --exclude Makefile.old --exclude perl --exclude aclocal.m4 --exclude configure rrdtool-1.0.13 rrdtool-1.0.13-ibr > rrdtool-1.0.13-ibr.patch
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:

Added: trunk/orca/packages/rrdtool-1.0.33/tcl/Makefile.am
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/tcl/Makefile.am	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/tcl/Makefile.am	Sat Jul 13 21:25:50 2002
@@ -0,0 +1,47 @@
+
+EXTRA_DIST = README ifOctets.tcl tclrrd.c
+CLEANFILES = tclrrd.o tclrrd.so
+
+VERSION = @VERSION@
+
+CFLAGS = @CFLAGS@
+TCL_PREFIX = @TCL_PREFIX@
+TCL_SHLIB_LD = @TCL_SHLIB_LD@
+TCL_SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@
+TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+TCL_PACKAGE_PATH = $(DESTDIR)@TCL_PACKAGE_PATH@
+TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
+GD_LIB_DIR       = $(top_srcdir)/@GD_LIB_DIR@
+
+SRC_DIR            = $(top_srcdir)/src
+INCLUDES           = -I$(TCL_PREFIX)/include -I$(SRC_DIR)  -I$(GD_LIB_DIR)
+LIBDIRS            = -L$(libdir) -L$(SRC_DIR)  -L../src/.libs
+LIB_RUNTIME_DIR    = $(libdir)
+
+if COMP_TCL
+
+tclrrd$(TCL_SHLIB_SUFFIX): tclrrd.o
+	$(TCL_SHLIB_LD) $(LIBDIRS) $< -o $@ -lrrd_private -lm
+
+tclrrd.o: tclrrd.c
+	$(CC) $(CFLAGS) $(TCL_SHLIB_CFLAGS) $(INCLUDES) -c $< -DVERSION=\"$(VERSION)\"
+
+all-local: tclrrd$(TCL_SHLIB_SUFFIX)
+
+tcl-install: tclrrd$(TCL_SHLIB_SUFFIX)
+	cp tclrrd$(TCL_SHLIB_SUFFIX) $(TCL_PACKAGE_PATH)/tclrrd$(VERSION)$(TCL_SHLIB_SUFFIX)
+	if [ ! -d $(TCL_PACKAGE_PATH)/tclrrd$(VERSION) ] ; then \
+		mkdir $(TCL_PACKAGE_PATH)/tclrrd$(VERSION) ; \
+	fi
+	echo "package ifneeded Rrd $(VERSION) [list load [file join \$$dir .. tclrrd$(VERSION)$(TCL_SHLIB_SUFFIX)]]" > $(TCL_PACKAGE_PATH)/tclrrd$(VERSION)/pkgIndex.tcl
+
+else
+
+all-local:
+
+endif
+
+diff:
+	cd .. ; diff -c -u -r -N --exclude Makefile --exclude html --exclude doc --exclude Makefile.in --exclude Makefile.old --exclude perl --exclude aclocal.m4 --exclude configure rrdtool-1.0.13 rrdtool-1.0.13-ibr > rrdtool-1.0.13-ibr.patch
+	
+

Added: trunk/orca/packages/rrdtool-1.0.33/tcl/tclrrd.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/tcl/tclrrd.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/tcl/tclrrd.c	Sat Jul 13 21:25:51 2002
@@ -0,0 +1,389 @@
+/*
+ * tclrrd.c -- A TCL interpreter extension to access the RRD library.
+ *
+ * Copyright (c) 1999,2000 Frank Strauss, Technical University of Braunschweig.
+ *
+ * See the file "COPYING" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * $Id$
+ */
+
+
+
+#include <time.h>
+#include <tcl.h>
+#include <rrd_tool.h>
+#include <rrd_format.h>
+
+
+
+extern int __getopt_initialized;
+
+
+/*
+ * some rrd_XXX() functions might modify the argv strings passed to it.
+ * Furthermore, they use getopt() without initializing getopt's optind
+ * variable themselves. Hence, we need to do some preparation before
+ * calling the rrd library functions.
+ */
+static char ** getopt_init(argc, argv)
+    int argc;
+    char *argv[];
+{
+    char **argv2;
+    int i;
+    
+    optind = 0;
+
+    argv2 = calloc(argc, sizeof(char *));
+    for (i = 0; i < argc; i++) {
+	argv2[i] = strdup(argv[i]);
+    }
+    return argv2;
+}
+
+static void getopt_cleanup(argc, argv2)
+    int argc;
+    char *argv2[];
+{
+    int i;
+    
+    for (i = 0; i < argc; i++) {
+	free(argv2[i]);
+    }
+    free(argv2);
+}
+
+
+
+static int
+Rrd_Create(clientData, interp, argc, argv)
+    ClientData clientData;
+    Tcl_Interp *interp;
+    int argc;
+    char *argv[];
+{
+    char **argv2;
+
+    argv2 = getopt_init(argc, argv);
+    rrd_create(argc, argv2);
+    getopt_cleanup(argc, argv2);
+    
+    if (rrd_test_error()) {
+	Tcl_AppendResult(interp, "RRD Error: ",
+			 rrd_get_error(), (char *) NULL);
+        rrd_clear_error();
+	return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+
+
+static int
+Rrd_Dump(clientData, interp, argc, argv)
+    ClientData clientData;
+    Tcl_Interp *interp;
+    int argc;
+    char *argv[];
+{
+    char **argv2;
+    
+    argv2 = getopt_init(argc, argv);
+    rrd_dump(argc, argv2);
+    getopt_cleanup(argv, argv2);
+
+    /* NOTE: rrd_dump() writes to stdout. No interaction with TCL. */
+
+    if (rrd_test_error()) {
+	Tcl_AppendResult(interp, "RRD Error: ",
+			 rrd_get_error(), (char *) NULL);
+        rrd_clear_error();
+	return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+
+
+static int
+Rrd_Last(clientData, interp, argc, argv)
+    ClientData clientData;
+    Tcl_Interp *interp;
+    int argc;
+    char *argv[];
+{
+    time_t t;
+    char **argv2;
+    
+    argv2 = getopt_init(argc, argv);
+    t = rrd_last(argc, argv2);
+    getopt_cleanup(argv, argv2);
+
+
+    if (rrd_test_error()) {
+	Tcl_AppendResult(interp, "RRD Error: ",
+			 rrd_get_error(), (char *) NULL);
+        rrd_clear_error();
+	return TCL_ERROR;
+    }
+
+    Tcl_SetIntObj(Tcl_GetObjResult(interp), t);
+
+    return TCL_OK;
+}
+
+
+
+static int
+Rrd_Update(clientData, interp, argc, argv)
+    ClientData clientData;
+    Tcl_Interp *interp;
+    int argc;
+    char *argv[];
+{
+    char **argv2;
+    
+    argv2 = getopt_init(argc, argv);
+    rrd_update(argc, argv2);
+    getopt_cleanup(argv, argv2);
+
+    if (rrd_test_error()) {
+	Tcl_AppendResult(interp, "RRD Error: ",
+			 rrd_get_error(), (char *) NULL);
+        rrd_clear_error();
+	return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+
+
+static int
+Rrd_Fetch(clientData, interp, argc, argv)
+    ClientData clientData;
+    Tcl_Interp *interp;
+    int argc;
+    char *argv[];
+{
+    time_t start, end;
+    unsigned long step, ds_cnt, i, ii;
+    rrd_value_t *data, *datai;
+    char **ds_namv;
+    Tcl_Obj *listPtr;
+    char s[30];
+    char **argv2;
+    
+    argv2 = getopt_init(argc, argv);
+    if (rrd_fetch(argc, argv2, &start, &end, &step,
+		  &ds_cnt, &ds_namv, &data) != -1) {
+        datai = data;
+        listPtr = Tcl_GetObjResult(interp);
+        for (i = start; i <= end; i += step) {
+            for (ii = 0; ii < ds_cnt; ii++) {
+		sprintf(s, "%.2f", *(datai++));
+                Tcl_ListObjAppendElement(interp, listPtr,
+					 Tcl_NewStringObj(s, -1));
+            }
+        }
+        for (i=0; i<ds_cnt; i++) free(ds_namv[i]);
+        free(ds_namv);
+        free(data);
+    }
+    getopt_cleanup(argv, argv2);
+
+    if (rrd_test_error()) {
+	Tcl_AppendResult(interp, "RRD Error: ",
+			 rrd_get_error(), (char *) NULL);
+        rrd_clear_error();
+	return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+
+
+static int
+Rrd_Graph(clientData, interp, argc, argv)
+    ClientData clientData;
+    Tcl_Interp *interp;
+    int argc;
+    char *argv[];
+{
+    char **calcpr;
+    int xsize, ysize;
+    Tcl_Obj *listPtr;
+    char **argv2;
+    
+    calcpr = NULL;
+
+    argv2 = getopt_init(argc, argv);
+    if (rrd_graph(argc, argv2, &calcpr, &xsize, &ysize) != -1 ) {
+        listPtr = Tcl_GetObjResult(interp);
+        Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(xsize));
+        Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(ysize));
+        if (calcpr) {
+#if 0
+	    int i;
+	    
+            for(i = 0; calcpr[i]; i++){
+                printf("%s\n", calcpr[i]);
+                free(calcpr[i]);
+            } 
+#endif
+            free(calcpr);
+        }
+    }
+    getopt_cleanup(argv, argv2);
+
+    if (rrd_test_error()) {
+	Tcl_AppendResult(interp, "RRD Error: ",
+			 rrd_get_error(), (char *) NULL);
+        rrd_clear_error();
+	return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+
+
+static int
+Rrd_Tune(clientData, interp, argc, argv)
+    ClientData clientData;
+    Tcl_Interp *interp;
+    int argc;
+    char *argv[];
+{
+    char **argv2;
+    
+    argv2 = getopt_init(argc, argv);
+    rrd_tune(argc, argv2);
+    getopt_cleanup(argv, argv2);
+
+    if (rrd_test_error()) {
+	Tcl_AppendResult(interp, "RRD Error: ",
+			 rrd_get_error(), (char *) NULL);
+        rrd_clear_error();
+	return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+
+
+static int
+Rrd_Resize(clientData, interp, argc, argv)
+    ClientData clientData;
+    Tcl_Interp *interp;
+    int argc;
+    char *argv[];
+{
+    char **argv2;
+    
+    argv2 = getopt_init(argc, argv);
+    rrd_resize(argc, argv2);
+    getopt_cleanup(argv, argv2);
+
+    if (rrd_test_error()) {
+	Tcl_AppendResult(interp, "RRD Error: ",
+			 rrd_get_error(), (char *) NULL);
+        rrd_clear_error();
+	return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+
+
+static int
+Rrd_Restore(clientData, interp, argc, argv)
+    ClientData clientData;
+    Tcl_Interp *interp;
+    int argc;
+    char *argv[];
+{
+    char **argv2;
+    
+    argv2 = getopt_init(argc, argv);
+    rrd_restore(argc, argv2);
+    getopt_cleanup(argv, argv2);
+
+    if (rrd_test_error()) {
+	Tcl_AppendResult(interp, "RRD Error: ",
+			 rrd_get_error(), (char *) NULL);
+        rrd_clear_error();
+	return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+
+
+/*
+ * The following structure defines the commands in the Rrd extension.
+ */
+
+typedef struct {
+    char *name;			/* Name of the command. */
+    Tcl_CmdProc *proc;		/* Procedure for command. */
+} CmdInfo;
+
+static CmdInfo rrdCmds[] = {
+    { "Rrd::create",	Rrd_Create		},
+    { "Rrd::dump",	Rrd_Dump		},
+    { "Rrd::last",	Rrd_Last		},
+    { "Rrd::update",	Rrd_Update		},
+    { "Rrd::fetch",	Rrd_Fetch		},
+    { "Rrd::graph",	Rrd_Graph		},
+    { "Rrd::tune",	Rrd_Tune		},
+    { "Rrd::resize",	Rrd_Resize		},
+    { "Rrd::restore",	Rrd_Restore		},
+    { (char *) NULL,	(Tcl_CmdProc *) NULL	}
+};
+
+
+
+int
+Tclrrd_Init(interp, safe)
+    Tcl_Interp *interp;
+    int safe;
+{ 
+    CmdInfo *cmdInfoPtr;
+    Tcl_CmdInfo info;
+
+    if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 1) == NULL) {
+        return TCL_ERROR;
+    }
+
+    Tcl_SetVar2(interp, "rrd", "version", VERSION, TCL_GLOBAL_ONLY);
+
+    for (cmdInfoPtr = rrdCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
+	/*
+	 * Check if the command already exists and return an error
+	 * to ensure we detect name clashes while loading the Rrd
+	 * extension.
+	 */
+	if (Tcl_GetCommandInfo(interp, cmdInfoPtr->name, &info)) {
+	    Tcl_AppendResult(interp, "command \"", cmdInfoPtr->name,
+			     "\" already exists", (char *) NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_CreateCommand(interp, cmdInfoPtr->name, cmdInfoPtr->proc,
+		          (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
+    }
+
+    if (Tcl_PkgProvide(interp, "Rrd", VERSION) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}

Added: trunk/orca/packages/rrdtool-1.0.33/tcl/README
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/tcl/README	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/tcl/README	Sat Jul 13 21:25:51 2002
@@ -0,0 +1,31 @@
+TCLRRD -- A TCL interpreter extension to access the RRD library,
+	  contributed to Tobias Oetiker's RRD tools.
+
+Copyright (c) 1999,2000 Frank Strauss, Technical University of Braunschweig.
+
+See the file "COPYING" for information on usage and redistribution
+of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+TCLRRD adds a dynamically loadable package to the Tcl 8.x interpreter
+to access all RRD functions as of RRDtool 1.0.13. All command names
+and arguments are equal to those of RRDtool. They are assigned to the
+namespace `Rrd', e.g.  `Rrd::create'. Return values are a bit
+different from plain rrdtool behavior to enable more native Tcl
+usage. Errors are mapped to the TCL_ERROR return code together with
+the RRD error strings.
+
+TCLRRD makes it easy to combine RRD use with advanced SNMP functionality
+of scotty (http://wwwsnmp.cs.utwente.nl/~schoenw/scotty/). E.g., it's easy
+to use some scotty code to get the counters of some interfaces by their
+interface name and then use Rrd::update to store the values. Furthermore,
+data source types (see RRD::create documentation) and integer value ranges
+could be easily retrieved from MIB information.
+
+TCLRRD has been written on a Linux system for use with Tcl 8.x. It should
+work on many other platforms, although it has not been tested. There are
+no fool proof installation procedures. Take a look at Makefile.am and
+adapt it, if required.
+
+TCLRRD has been written for RRD 1.0.13.
+
+	Frank Strauss <strauss at ibr.cs.tu-bs.de>, 09-Mar-2000

Modified: trunk/orca/packages/rrdtool-1.0.33/configure.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/configure.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/configure.in	Sat Jul 13 21:25:51 2002
@@ -16,10 +16,11 @@
 AC_CANONICAL_SYSTEM
 
 dnl tell automake the this script is for rrdtool
-AM_INIT_AUTOMAKE(rrdtool, 1.0.13)
+AM_INIT_AUTOMAKE(rrdtool, 1.0.33)
+AC_SUBST(VERSION)
 
 dnl where we install our stuff ...
-AC_PREFIX_DEFAULT( /usr/local/rrdtool-1.0.13 )
+AC_PREFIX_DEFAULT( /usr/local/rrdtool-1.0.33 )
 
 dnl tell automake which file to use as config header
 AM_CONFIG_HEADER(config/config.h)
@@ -30,7 +31,7 @@
 dnl Define library subdirectory names here.
 CGI_LIB_DIR=cgilib-0.4
 GD_LIB_DIR=gd1.3
-PNG_LIB_DIR=libpng-1.0.3
+PNG_LIB_DIR=libpng-1.0.9
 ZLIB_LIB_DIR=zlib-1.1.3
 
 dnl substitute them in all the files listed in AC_OUTPUT
@@ -38,24 +39,64 @@
 AC_SUBST(GD_LIB_DIR)
 AC_SUBST(PNG_LIB_DIR)
 AC_SUBST(ZLIB_LIB_DIR)
-
+AC_SUBST(PERLFLAGS)
 
 dnl Check for Perl.
 AC_PATH_PROG(PERL, perl, no)
-if test "x$PERL" = "nox"; then
+if test "x$PERL" = "xno"; then
 	COMP_PERL=
 else
 	COMP_PERL="perl_piped perl_shared"
+	AC_MSG_CHECKING(for shared library extension)
+	SO_EXT=`$PERL -e 'use Config; if (defined $Config{so} and $Config{so} ne 'a') {print "$Config{so}\n"} else {print "so\n"};'`
+	AC_MSG_RESULT($SO_EXT)
 fi
 AC_SUBST(COMP_PERL)
+AC_SUBST(SO_EXT)
+
+dnl Check for Tcl.
+withval=""
+AC_ARG_WITH(tcllib,[  --with-tcllib=DIR       location of the tclConfig.sh])
+found=0
+AC_MSG_CHECKING(for tclConfig.sh in $withval)
+if test -f "$withval/tclConfig.sh" ; then
+    	tcl_config=$withval/tclConfig.sh
+        found=1
+        AC_MSG_RESULT(yes)
+        break
+else
+        AC_MSG_RESULT(no)
+fi
+
+if test $found -eq 0 ; then
+        AC_MSG_WARN([tclConfig.sh not found - Tcl interface won't be built])
+else
+	. $tcl_config
+fi
 
+dnl Pass additional perl options when generating Makefile from Makefile.PL
+# Options to pass when configuring perl module
+AC_ARG_WITH(perl-options,
+[  --with-perl-options=[OPTIONS]  options to pass on command-line when
+                          generating Makefile from Makefile.PL],
+[PERL_MAKE_OPTIONS=$withval])
+AC_SUBST(PERL_MAKE_OPTIONS)
+
+AM_CONDITIONAL(COMP_TCL, test x$found = x1 )
+
+AC_SUBST(TCL_PREFIX)
+AC_SUBST(TCL_SHLIB_CFLAGS)
+AC_SUBST(TCL_SHLIB_LD)
+AC_SUBST(TCL_SHLIB_SUFFIX)
+AC_SUBST(TCL_PACKAGE_PATH)
+AC_SUBST(TCL_LD_SEARCH_FLAGS)
 
 dnl Check for the compiler and static/shared library creation.
 AC_PROG_CC
 AC_PROG_CPP
 dnl RRD_ACLOCAL_FIND_LIBTOOL
 
-dnl don't build a shared library ... perl will do it's own magic. 
+dnl don't build a shared library ...
 dnl this can be changed when running configure
 AC_DISABLE_SHARED
 
@@ -63,7 +104,7 @@
 
 dnl Checks for header files.
 AC_HEADER_STDC
-AC_CHECK_HEADERS(fcntl.h fp_class.h malloc.h unistd.h math.h sys/time.h sys/times.h sys/param.h sys/resource.h float.h)
+AC_CHECK_HEADERS(fcntl.h fp_class.h malloc.h unistd.h ieeefp.h math.h sys/time.h sys/times.h sys/param.h sys/resource.h float.h)
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -71,35 +112,36 @@
 AC_STRUCT_TM
 
 dnl Checks for libraries.
-AC_CHECK_LIB(m, acos)
+AC_CHECK_FUNC(acos, , AC_CHECK_LIB(m, acos))
 
-dnl Does the compiler like -Wall and -pedantic ?
-oCFLAGS=$CFLAGS
-CFLAGS="$CFLAGS -Wall -pedantic"
-AC_CACHE_CHECK(if we can use GCC-specific compiler options, rd_cv_gcc_opt,
-               [AC_TRY_COMPILE( , return 0 ,
-             	    rd_cv_gcc_opt=yes,
-		    rd_cv_gcc_opt=no )
-	       ]
-       )
-if test $rd_cv_gcc_opt = no; then
-	CFLAGS=$oCFLAGS
+dnl Check for nroff
+AC_PATH_PROGS(NROFF, gnroff nroff)
+AC_PATH_PROGS(TROFF, groff troff)
+
+dnl Does the compiler like -Wall and -pedantic?
+if test "x$GCC" = "xyes"; then
+  oCFLAGS=$CFLAGS
+  CFLAGS="$CFLAGS -Wall -pedantic -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline"
+  AC_CACHE_CHECK(if we can use GCC-specific compiler options, rd_cv_gcc_opt,
+                [AC_TRY_COMPILE( , return 0 ,
+                    rd_cv_gcc_opt=yes,
+                    rd_cv_gcc_opt=no )
+               ]
+        )
+  if test $rd_cv_gcc_opt = no; then
+         CFLAGS=$oCFLAGS
+  fi
 fi
 
-dnl Can the compiler take -fPIC
-
-oCFLAGS=$CFLAGS
-CFLAGS="$CFLAGS -fPIC"
-AC_CACHE_CHECK(if we can use -fPIC as this may help building the perl module, rd_cv_pic,
-               [AC_TRY_RUN([int main(void){return 0;}],
-             	    rd_cv_pic=yes,
-		    rd_cv_pic=no,:)
-	       ]
-       )
-if test $rd_cv_pic = no; then
-	CFLAGS=$oCFLAGS
-fi
+dnl add pic flag in any case this makes sure all our code is relocatable
+CFLAGS="$CFLAGS "`grep pic_flag= libtool | sed -e 's/.*pic_flag=//' -e 's/"//g'`
 
+dnl it seems that hpux chockes on -fPIC for some reason
+case $target_os in
+*hpux*)
+	CLFAGS=`echo $CFLAGS|sed -e 's/-fPIC/-fpic/g'`
+;;
+esac
 
 dnl Checks for library functions.
 AC_FUNC_STRFTIME
@@ -107,7 +149,26 @@
 
 dnl for each function found we get a definition in config.h 
 dnl of the form HAVE_FUNCTION
-AC_CHECK_FUNCS(snprintf vsnprintf fpclass class fpclassify fp_class isnan finite isinf memmove strchr mktime getrusage gettimeofday)
+
+AC_CHECK_FUNCS(strerror snprintf vsnprintf fpclass class fp_class isnan memmove strchr mktime getrusage gettimeofday)
+
+dnl HP-UX 11.00 does not have finite but does have isfinite as a macro
+AC_CHECK_FUNCS(fpclassify, ,
+  [AC_MSG_CHECKING(for fpclassify with <math.h>)
+    AC_TRY_LINK([#include <math.h>], [float f = 0.0; fpclassify(f)],
+      AC_MSG_RESULT(yes)
+      AC_DEFINE(HAVE_FPCLASSIFY), AC_MSG_RESULT(no))])
+AC_CHECK_FUNCS(finite, ,
+  [AC_CHECK_FUNCS(isfinite, ,
+    [AC_MSG_CHECKING(for isfinite with <math.h>)
+    AC_TRY_LINK([#include <math.h>], [float f = 0.0; isfinite(f)],
+      AC_MSG_RESULT(yes)
+      AC_DEFINE(HAVE_ISFINITE), AC_MSG_RESULT(no))])])
+AC_CHECK_FUNCS(isinf, ,
+  [AC_MSG_CHECKING(for isinf with <math.h>)
+    AC_TRY_LINK([#include <math.h>], [float f = 0.0; isinf(f)],
+      AC_MSG_RESULT(yes)
+      AC_DEFINE(HAVE_ISINF), AC_MSG_RESULT(no))])
 
 dnl what does realloc do if it gets called with a NULL pointer
 
@@ -125,152 +186,122 @@
 AC_DEFINE(NO_NULL_REALLOC)
 fi
 
-dnl determine how to get IEEE math to work on this box.
+dnl determine how to get IEEE math working
+dnl AC_IEEE(MESSAGE, set rd_cv_ieee_[var] variable, INCLUDES,
+dnl   FUNCTION-BODY, [ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]])
 
 AC_DEFUN(AC_IEEE, 
-AC_CACHE_CHECK([if IEEE math works $1], [rd_cv_ieee_$2],
+AC_MSG_CHECKING([if IEEE math works $1])
+AC_CACHE_VAL([rd_cv_ieee_$2],
 [AC_TRY_RUN([$3
 
 #if HAVE_MATH_H
-#  include <math.h>                                                                                                                                        
+#  include <math.h>
 #endif
 
 #if HAVE_FLOAT_H
 #  include <float.h>  
 #endif
 
-/* for solaris */
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
 #  define HAVE_ISINF 1
-#  include <ieeefp.h>
 #  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
 #endif
-/* for dec unix */
+
+/* Digital UNIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
 #  define HAVE_ISINF 1
-#  include <fp_class.h>
 #  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
-/* for HP-UX 10.20 */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
-/* for AIX */
+#endif 
+
+/* AIX */
 #if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
 #  define HAVE_ISINF 1
 #  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
 #endif
 
-#if (! defined(HAVE_FINITE) && defined(HAVE_ISNAN) && defined(HAVE_ISINF))
-#  define HAVE_FINITE 1
-#  define finite(a) (! isnan(a) && ! isinf(a))
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
 #endif
 
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
 
 #include <stdio.h>
 int main(void){
-    double nan,inf,c,d;
-     $4;
-     /* some math to see if we get a segfault; */
-     nan=0.0/0.0;
-     inf=1.0/0.0;
-     c = 1.0;
-     c = c / 0.0; /* try getting fpe */
-     c = inf + nan;
-     c = inf / nan;
-     if (! isnan(nan)) {printf ("isnan(NaN) ... "); return 1;}
-     if (nan == nan) {printf ("nan != nan ..."); return 1;}
-     if (! isinf(inf)) {printf ("isinf(oo) ... "); return 1;}
-     if (! isinf(-inf)) {printf ("isinf(-oo) ... "); return 1;}
-     if (! inf > 0) {printf ("inf > 0 ... "); return 1;}
-     if (! -inf < 0) {printf ("inf < 0 ... "); return 1;}
-     return 0;
-}],
-           [rd_cv_ieee_$2=yes],[rd_cv_ieee_$2=no],:)]))
-
-oCFLAGS=$CFLAGS
-unset CFLAGS
-
-AC_IEEE([out of the box],works)
-if test "$rd_cv_ieee_works" != yes ; then
-
-CFLAGS=-ieee
-AC_IEEE([with the -ieee switch],switch)
-if test "$rd_cv_ieee_switch" != yes ; then
-
-CFLAGS=-qfloat=nofold
-AC_IEEE([with the -qfloat=nofold switch],nofold)
-if test "$rd_cv_ieee_nofold" != yes ; then
-
-CFLAGS="-w -qflttrap=enable:zerodivide"
-AC_IEEE([with the -w -qflttrap=enable:zerodivide],flttrap)
-if test "$rd_cv_ieee_flttrap" != yes ; then
-
-CFLAGS=-mieee
-AC_IEEE([with the -mieee switch],mswitch)
-if test "$rd_cv_ieee_mswitch" != yes ; then
-
-CFLAGS="-q float=rndsngl"
-AC_IEEE([with the -q float=rndsngl switch],qswitch)
-if test "$rd_cv_ieee_qswitch" != yes ; then
-
-unset CFLAGS
-AC_IEEE([with fpsetmask(0)],mask,[#include <floatingpoint.h>],[fpsetmask(0)])
-if test "$rd_cv_ieee_mask" != yes ; then
-
-AC_IEEE([with signal(SIGFPE,SIG_IGN)],sigfpe,[#include <signal.h>],[signal(SIGFPE,SIG_IGN)])
-if test "$rd_cv_ieee_sigfpe" != yes ; then
-
-
-echo "--------------------------------------------------------------"
-echo "Your Compiler does not do propper IEEE math ... "
-echo "Please find out how to make IEEE math work with your Compiler"
-echo "and let me know (oetiker at ee.ethz.ch)"
-echo "Check config.log to see what went wrong ..."
-echo ""
-exit 1
-       fi
-      fi
-     fi
-    fi
-   fi
-  fi
- fi
-fi
-
-CFLAGS=$oCFLAGS
-
-if test x$rd_cv_ieee_sigfpe = xyes; then
-   AC_DEFINE(MUST_DISABLE_SIGFPE)
-fi
-
-if test x$rd_cv_ieee_mask = xyes; then
-   AC_DEFINE(MUST_DISABLE_FPMASK)
-   CFLAGS="$CFLAGS -DMUST_DISABLE_FPMASK"
-fi
-
-if test x$rd_cv_ieee_switch = xyes; then
-   CFLAGS="$CFLAGS -ieee"
-fi
-
-if test x$rd_cv_ieee_nofold = xyes; then
-   CFLAGS="$CFLAGS -qfloat=nofold"
-fi
-
-if test x$rd_cv_ieee_flttrap = xyes; then
-   CFLAGS="$CFLAGS -w -qflttrap=enable:zerodivide"
+    double nan,inf,c,zero;
+    $4;
+    /* some math to see if we get a floating point exception */
+    zero=sin(0.0); /* don't let the compiler optimize us away */
+    nan=0.0/zero; /* especially here */
+    inf=1.0/zero; /* and here. I want to know if it can do the magic */
+		  /* at run time without sig fpe */
+    c = inf + nan;
+    c = inf / nan;
+    if (! isnan(nan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (nan == nan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(inf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-inf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! inf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -inf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }],
+
+rd_cv_ieee_$2=yes,
+rd_cv_ieee_$2=no,
+:)])
+dnl these we run regardles is cached or not
+if test x${rd_cv_ieee_$2} = "xyes"; then
+ AC_MSG_RESULT(yes)
+ $5
+else
+ AC_MSG_RESULT(no)
+ $6
 fi
 
-if test x$rd_cv_ieee_mswitch = xyes; then
-   CFLAGS="$CFLAGS -mieee"
-fi
+)
 
-if test x$rd_cv_ieee_qswitch = xyes; then
-   CFLAGS="$CFLAGS -q float=rndsngl"
-fi
+_cflags=${CFLAGS}
+AC_IEEE([out of the box], works, , , ,
+  [CFLAGS="$_cflags -ieee"
+  AC_IEEE([with the -ieee switch], switch, , , ,
+    [CFLAGS="$_cflags -qfloat=nofold"
+    AC_IEEE([with the -qfloat=nofold switch], nofold, , , ,
+      [CFLAGS="$_cflags -w -qflttrap=enable:zerodivide"
+      AC_IEEE([with the -w -qflttrap=enable:zerodivide], flttrap, , , ,
+       [CFLAGS="$_cflags -mieee"
+       AC_IEEE([with the -mieee switch], mswitch, , , ,
+         [CFLAGS="$_cflags -q float=rndsngl"
+         AC_IEEE([with the -q float=rndsngl switch], qswitch, , , ,
+           [CFLAGS="$_cflags -OPT:IEEE_comparisons=ON"
+           AC_IEEE([with the -OPT:IEEE_comparisons=ON switch], ieeecmpswitch, , , ,
+             [CFLAGS=$_cflags
+             AC_IEEE([with fpsetmask(0)], mask,
+               [#include <floatingpoint.h>], [fpsetmask(0)],
+               [AC_DEFINE(MUST_DISABLE_FPMASK)
+	       PERLFLAGS="CCFLAGS=-DMUST_DISABLE_FPMASK"],
+               [AC_IEEE([with signal(SIGFPE,SIG_IGN)], sigfpe,
+                 [#include <signal.h>], [signal(SIGFPE,SIG_IGN)],
+                 [AC_DEFINE(MUST_DISABLE_SIGFPE)
+                 PERLFLAGS="CCFLAGS=-DMUST_DISABLE_SIGFPE"],		
+                 AC_MSG_ERROR([
+Your Compiler does not do propper IEEE math ... Please find out how to
+make IEEE math work with your compiler and let me know (oetiker at ee.ethz.ch).
+Check config.log to see what went wrong ...
+]))])])])])])])])])
 
-AC_SUBST(CFLAGS)
 
 AC_OUTPUT(cgilib-0.4/Makefile				\
           config/Makefile				\
@@ -283,31 +314,25 @@
           examples/Makefile				\
           contrib/Makefile				\
           contrib/trytime/Makefile			\
-          contrib/log2rrd/Makefile			\
           contrib/log2rrd/log2rrd.pl			\
-          contrib/killspike/Makefile			\
           contrib/killspike/killspike.pl		\
-          contrib/rrdlastds/Makefile			\
           contrib/rrdlastds/rrdlastds.pl		\
-          contrib/rrdfetchnames/Makefile		\
           contrib/rrdfetchnames/rrdfetchnames.pl	\
-          contrib/add_ds/Makefile			\
           contrib/add_ds/add_ds.pl			\
 	  contrib/add_ds/batch.pl			\
-          contrib/rrd-file-icon/Makefile		\
-          contrib/rrdproc/Makefile			\
           doc/Makefile					\
           gd1.3/Makefile				\
-          libpng-1.0.3/Makefile				\
+          libpng-1.0.9/Makefile				\
           zlib-1.1.3/Makefile				\
           src/Makefile					\
+          tcl/Makefile					\
           Makefile,					\
           [chmod +x examples/*.cgi examples/*.pl contrib/*/*.pl])
 
 AC_MSG_CHECKING(in)
 AC_MSG_RESULT(and out again)
 
-echo $ac_n "ordering CD from http://ee-staff.ethz-ch/~oetiker/wish $ac_c" 1>&6
+echo $ac_n "ordering CD from http://ee-staff.ethz.ch/~oetiker/wish $ac_c" 1>&6
 sleep 1
 echo $ac_n ".$ac_c" 1>&6
 sleep 1
@@ -323,13 +348,14 @@
 echo "Config is DONE!"
 echo
 echo "Type 'make' to compile the software and use 'make install' to "
-echo "install everything to $prefix. If you want to install the perl"
+echo "install everything to: $prefix."
+echo
+echo "If you want to install the perl"
 echo "modules in site-perl, try 'make site-perl-install'."
 echo 
-echo "       ... that wishlist mentioned above does really exist. So if"
-echo "you feel like showing your appreciation for rrdtool this is the"
-echo "place to go. :-)"
+echo "       ... that wishlist is NO JOKE. If you find RRDtool useful"
+echo "make me happy. Go to http://ee-staff.ethz.ch/~oetiker/wish and"
+echo "place an order."
 echo 
-echo "                            -- Tobi Oetiker <oetiker at ee.ethz.ch>"
+echo "                               -- Tobi Oetiker <tobi at oetiker.ch>"
 echo "----------------------------------------------------------------"
-

Modified: trunk/orca/packages/rrdtool-1.0.33/src/parsetime.h
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/parsetime.h	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/parsetime.h	Sat Jul 13 21:25:51 2002
@@ -1,23 +1,8 @@
 #ifndef __PARSETIME_H__
 #define __PARSETIME_H__
 
-#include <time.h>
 #include <stdio.h>
 
-typedef enum {
-	ABSOLUTE_TIME,
-	RELATIVE_TO_START_TIME, 
-	RELATIVE_TO_END_TIME
-} timetype;
-
-#define TIME_OK NULL
-
-struct time_value {
-  timetype type;
-  long offset;
-  struct tm tm;
-};
-
-char *parsetime(char *spec, struct time_value *ptv);
+#include "rrd.h"
 
 #endif

Modified: trunk/orca/packages/rrdtool-1.0.33/src/gifsize.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/gifsize.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/gifsize.c	Sat Jul 13 21:25:51 2002
@@ -1,5 +1,5 @@
 /****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997,1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  ****************************************************************************
  * gifsize.c  provides the function gifsize which determines the size of a gif
  ****************************************************************************/

Modified: trunk/orca/packages/rrdtool-1.0.33/src/Makefile.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/Makefile.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/Makefile.in	Sat Jul 13 21:25:51 2002
@@ -69,12 +69,23 @@
 target_alias = @target_alias@
 target_triplet = @target@
 CC = @CC@
-CFLAGS = @CFLAGS@
 COMP_PERL = @COMP_PERL@
 CPP = @CPP@
 LIBTOOL = @LIBTOOL@
+NROFF = @NROFF@
 PERL = @PERL@
+PERLFLAGS = @PERLFLAGS@
+PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 RANLIB = @RANLIB@
+SO_EXT = @SO_EXT@
+TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
+TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
+TCL_PREFIX = @TCL_PREFIX@
+TCL_SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@
+TCL_SHLIB_LD = @TCL_SHLIB_LD@
+TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+TROFF = @TROFF@
+VERSION = @VERSION@
 
 CGI_LIB_DIR = $(top_srcdir)/@CGI_LIB_DIR@
 GD_LIB_DIR = $(top_srcdir)/@GD_LIB_DIR@
@@ -87,7 +98,7 @@
 #LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(CFLAGS_EXTRA)
 #LINK      = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -o $@
 
-RRD_C_FILES =  	gdpng.c			getopt.c		getopt1.c		gifsize.c		parsetime.c		pngsize.c		rrd_create.c		rrd_diff.c		rrd_dump.c		rrd_error.c		rrd_fetch.c		rrd_format.c		rrd_graph.c		rrd_last.c		rrd_open.c		rrd_resize.c		rrd_restore.c		rrd_tune.c		rrd_update.c		getopt.h      ntconfig.h    parsetime.h   rrd_format.h  rrd_tool.h
+RRD_C_FILES =  	gdpng.c			getopt.c		getopt1.c		gifsize.c		parsetime.c		pngsize.c		rrd_create.c		rrd_diff.c		rrd_dump.c		rrd_info.c		rrd_error.c		rrd_fetch.c		rrd_format.c		rrd_graph.c		rrd_last.c		rrd_open.c		rrd_resize.c		rrd_restore.c		rrd_tune.c		rrd_update.c		getopt.h ntconfig.h parsetime.h rrd_format.h rrd_tool.h rrd.h
 
 
 # Build two libraries.  One is a public one that gets installed in
@@ -107,14 +118,21 @@
 librrd_private_la_SOURCES = $(RRD_C_FILES)
 
 librrd_la_LIBADD = $(RRD_LIBS)
-librrd_private_la_LIBADD = $(RRD_LIBS)
 librrd_la_LDFLAGS = -version-info 0:0:0
 
-bin_PROGRAMS = rrdcgi rrdtool
+include_HEADERS = rrd.h
+
+librrd_private_la_LIBADD = $(RRD_LIBS)
+librrd_private_la_LDFLAGS = -static
+
+bin_PROGRAMS = rrdcgi rrdtool rrdupdate
 
 rrdcgi_SOURCES = rrd_cgi.c
 rrdcgi_LDADD = librrd.la
 
+rrdupdate_SOURCES = 
+rrdupdate_LDADD = rrdupdate.o librrd.la
+
 rrdtool_SOURCES = rrd_tool.c
 rrdtool_LDADD = librrd.la
 
@@ -134,16 +152,17 @@
 $(ZLIB_LIB_DIR)/librrd_z.la
 librrd_la_OBJECTS =  gdpng.lo getopt.lo getopt1.lo gifsize.lo \
 parsetime.lo pngsize.lo rrd_create.lo rrd_diff.lo rrd_dump.lo \
-rrd_error.lo rrd_fetch.lo rrd_format.lo rrd_graph.lo rrd_last.lo \
-rrd_open.lo rrd_resize.lo rrd_restore.lo rrd_tune.lo rrd_update.lo
-librrd_private_la_LDFLAGS = 
+rrd_info.lo rrd_error.lo rrd_fetch.lo rrd_format.lo rrd_graph.lo \
+rrd_last.lo rrd_open.lo rrd_resize.lo rrd_restore.lo rrd_tune.lo \
+rrd_update.lo
 librrd_private_la_DEPENDENCIES =  $(CGI_LIB_DIR)/librrd_cgi.la \
 $(GD_LIB_DIR)/librrd_gd.la $(PNG_LIB_DIR)/librrd_png.la \
 $(ZLIB_LIB_DIR)/librrd_z.la
 librrd_private_la_OBJECTS =  gdpng.lo getopt.lo getopt1.lo gifsize.lo \
 parsetime.lo pngsize.lo rrd_create.lo rrd_diff.lo rrd_dump.lo \
-rrd_error.lo rrd_fetch.lo rrd_format.lo rrd_graph.lo rrd_last.lo \
-rrd_open.lo rrd_resize.lo rrd_restore.lo rrd_tune.lo rrd_update.lo
+rrd_info.lo rrd_error.lo rrd_fetch.lo rrd_format.lo rrd_graph.lo \
+rrd_last.lo rrd_open.lo rrd_resize.lo rrd_restore.lo rrd_tune.lo \
+rrd_update.lo
 PROGRAMS =  $(bin_PROGRAMS)
 
 rrdcgi_OBJECTS =  rrd_cgi.o
@@ -152,22 +171,27 @@
 rrdtool_OBJECTS =  rrd_tool.o
 rrdtool_DEPENDENCIES =  librrd.la
 rrdtool_LDFLAGS = 
+rrdupdate_OBJECTS = 
+rrdupdate_DEPENDENCIES =  rrdupdate.o librrd.la
+rrdupdate_LDFLAGS = 
+CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
 LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS =  $(include_HEADERS)
+
 DIST_COMMON =  Makefile.am Makefile.in
 
 
 PACKAGE = @PACKAGE@
-VERSION = @VERSION@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
-SOURCES = $(librrd_la_SOURCES) $(librrd_private_la_SOURCES) $(rrdcgi_SOURCES) $(rrdtool_SOURCES)
-OBJECTS = $(librrd_la_OBJECTS) $(librrd_private_la_OBJECTS) $(rrdcgi_OBJECTS) $(rrdtool_OBJECTS)
+SOURCES = $(librrd_la_SOURCES) $(librrd_private_la_SOURCES) $(rrdcgi_SOURCES) $(rrdtool_SOURCES) $(rrdupdate_SOURCES)
+OBJECTS = $(librrd_la_OBJECTS) $(librrd_private_la_OBJECTS) $(rrdcgi_OBJECTS) $(rrdtool_OBJECTS) $(rrdupdate_OBJECTS)
 
 all: all-redirect
 .SUFFIXES:
@@ -291,6 +315,25 @@
 	@rm -f rrdtool
 	$(LINK) $(rrdtool_LDFLAGS) $(rrdtool_OBJECTS) $(rrdtool_LDADD) $(LIBS)
 
+rrdupdate: $(rrdupdate_OBJECTS) $(rrdupdate_DEPENDENCIES)
+	@rm -f rrdupdate
+	$(LINK) $(rrdupdate_LDFLAGS) $(rrdupdate_OBJECTS) $(rrdupdate_LDADD) $(LIBS)
+
+install-includeHEADERS: $(include_HEADERS)
+	@$(NORMAL_INSTALL)
+	$(mkinstalldirs) $(DESTDIR)$(includedir)
+	@list='$(include_HEADERS)'; for p in $$list; do \
+	  if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+	  echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+	  $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+	done
+
+uninstall-includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	list='$(include_HEADERS)'; for p in $$list; do \
+	  rm -f $(DESTDIR)$(includedir)/$$p; \
+	done
+
 tags: TAGS
 
 ID: $(HEADERS) $(SOURCES) $(LISP)
@@ -328,55 +371,56 @@
 	@for file in $(DISTFILES); do \
 	  d=$(srcdir); \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$/$$file $(distdir)/$$file; \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
 	    test -f $(distdir)/$$file \
 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
 	    || cp -p $$d/$$file $(distdir)/$$file || :; \
 	  fi; \
 	done
-gdpng.lo gdpng.o : gdpng.c ../libpng-1.0.3/png.h ../zlib-1.1.3/zlib.h \
-	../zlib-1.1.3/zconf.h ../libpng-1.0.3/pngconf.h ../gd1.3/gd.h
+gdpng.lo gdpng.o : gdpng.c ../libpng-1.0.9/png.h ../zlib-1.1.3/zlib.h \
+	../zlib-1.1.3/zconf.h ../libpng-1.0.9/pngconf.h ../gd1.3/gd.h
 getopt.lo getopt.o : getopt.c ../config/config.h getopt.h
 getopt1.lo getopt1.o : getopt1.c ../config/config.h getopt.h
 gifsize.lo gifsize.o : gifsize.c
 parsetime.lo parsetime.o : parsetime.c rrd_tool.h ../config/config.h \
-	parsetime.h getopt.h rrd_format.h ../gd1.3/gd.h
-pngsize.lo pngsize.o : pngsize.c ../libpng-1.0.3/png.h \
+	rrd.h getopt.h rrd_format.h ../gd1.3/gd.h
+pngsize.lo pngsize.o : pngsize.c ../libpng-1.0.9/png.h \
 	../zlib-1.1.3/zlib.h ../zlib-1.1.3/zconf.h \
-	../libpng-1.0.3/pngconf.h
-rrd_cgi.o: rrd_cgi.c rrd_tool.h ../config/config.h parsetime.h getopt.h \
+	../libpng-1.0.9/pngconf.h
+rrd_cgi.o: rrd_cgi.c rrd_tool.h ../config/config.h rrd.h getopt.h \
 	rrd_format.h ../gd1.3/gd.h ../cgilib-0.4/cgi.h
 rrd_create.lo rrd_create.o : rrd_create.c rrd_tool.h ../config/config.h \
-	parsetime.h getopt.h rrd_format.h ../gd1.3/gd.h
-rrd_diff.lo rrd_diff.o : rrd_diff.c rrd_tool.h ../config/config.h \
-	parsetime.h getopt.h rrd_format.h ../gd1.3/gd.h
-rrd_dump.lo rrd_dump.o : rrd_dump.c rrd_tool.h ../config/config.h \
-	parsetime.h getopt.h rrd_format.h ../gd1.3/gd.h
+	rrd.h getopt.h rrd_format.h ../gd1.3/gd.h
+rrd_diff.lo rrd_diff.o : rrd_diff.c rrd_tool.h ../config/config.h rrd.h \
+	getopt.h rrd_format.h ../gd1.3/gd.h
+rrd_dump.lo rrd_dump.o : rrd_dump.c rrd_tool.h ../config/config.h rrd.h \
+	getopt.h rrd_format.h ../gd1.3/gd.h
 rrd_error.lo rrd_error.o : rrd_error.c rrd_tool.h ../config/config.h \
-	parsetime.h getopt.h rrd_format.h ../gd1.3/gd.h
+	rrd.h getopt.h rrd_format.h ../gd1.3/gd.h
 rrd_fetch.lo rrd_fetch.o : rrd_fetch.c rrd_tool.h ../config/config.h \
-	parsetime.h getopt.h rrd_format.h ../gd1.3/gd.h
+	rrd.h getopt.h rrd_format.h ../gd1.3/gd.h
 rrd_format.lo rrd_format.o : rrd_format.c rrd_tool.h ../config/config.h \
-	parsetime.h getopt.h rrd_format.h ../gd1.3/gd.h
+	rrd.h getopt.h rrd_format.h ../gd1.3/gd.h
 rrd_graph.lo rrd_graph.o : rrd_graph.c rrd_tool.h ../config/config.h \
-	parsetime.h getopt.h rrd_format.h ../gd1.3/gd.h \
+	rrd.h getopt.h rrd_format.h ../gd1.3/gd.h \
 	../gd1.3/gdlucidan10.h ../gd1.3/gdlucidab12.h
-rrd_last.lo rrd_last.o : rrd_last.c rrd_tool.h ../config/config.h \
-	parsetime.h getopt.h rrd_format.h ../gd1.3/gd.h
-rrd_open.lo rrd_open.o : rrd_open.c rrd_tool.h ../config/config.h \
-	parsetime.h getopt.h rrd_format.h ../gd1.3/gd.h
+rrd_info.lo rrd_info.o : rrd_info.c rrd_tool.h ../config/config.h rrd.h \
+	getopt.h rrd_format.h ../gd1.3/gd.h
+rrd_last.lo rrd_last.o : rrd_last.c rrd_tool.h ../config/config.h rrd.h \
+	getopt.h rrd_format.h ../gd1.3/gd.h
+rrd_open.lo rrd_open.o : rrd_open.c rrd_tool.h ../config/config.h rrd.h \
+	getopt.h rrd_format.h ../gd1.3/gd.h
 rrd_resize.lo rrd_resize.o : rrd_resize.c rrd_tool.h ../config/config.h \
-	parsetime.h getopt.h rrd_format.h ../gd1.3/gd.h
+	rrd.h getopt.h rrd_format.h ../gd1.3/gd.h
 rrd_restore.lo rrd_restore.o : rrd_restore.c rrd_tool.h \
-	../config/config.h parsetime.h getopt.h rrd_format.h \
-	../gd1.3/gd.h
-rrd_tool.o: rrd_tool.c rrd_tool.h ../config/config.h parsetime.h \
+	../config/config.h rrd.h getopt.h rrd_format.h ../gd1.3/gd.h
+rrd_tool.o: rrd_tool.c rrd_tool.h ../config/config.h rrd.h getopt.h \
+	rrd_format.h ../gd1.3/gd.h
+rrd_tune.lo rrd_tune.o : rrd_tune.c rrd_tool.h ../config/config.h rrd.h \
 	getopt.h rrd_format.h ../gd1.3/gd.h
-rrd_tune.lo rrd_tune.o : rrd_tune.c rrd_tool.h ../config/config.h \
-	parsetime.h getopt.h rrd_format.h ../gd1.3/gd.h
 rrd_update.lo rrd_update.o : rrd_update.c rrd_tool.h ../config/config.h \
-	parsetime.h getopt.h rrd_format.h ../gd1.3/gd.h
+	rrd.h getopt.h rrd_format.h ../gd1.3/gd.h
 
 info-am:
 info: info-am
@@ -389,20 +433,22 @@
 install-exec-am: install-libLTLIBRARIES install-binPROGRAMS
 install-exec: install-exec-am
 
-install-data-am:
+install-data-am: install-includeHEADERS
 install-data: install-data-am
 
 install-am: all-am
 	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
 install: install-am
-uninstall-am: uninstall-libLTLIBRARIES uninstall-binPROGRAMS
+uninstall-am: uninstall-libLTLIBRARIES uninstall-binPROGRAMS \
+		uninstall-includeHEADERS
 uninstall: uninstall-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
 all-redirect: all-am
 install-strip:
 	$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
 installdirs:
-	$(mkinstalldirs)  $(DESTDIR)$(libdir) $(DESTDIR)$(bindir)
+	$(mkinstalldirs)  $(DESTDIR)$(libdir) $(DESTDIR)$(bindir) \
+		$(DESTDIR)$(includedir)
 
 
 mostlyclean-generic:
@@ -454,14 +500,21 @@
 maintainer-clean-compile mostlyclean-libtool distclean-libtool \
 clean-libtool maintainer-clean-libtool mostlyclean-binPROGRAMS \
 distclean-binPROGRAMS clean-binPROGRAMS maintainer-clean-binPROGRAMS \
-uninstall-binPROGRAMS install-binPROGRAMS tags mostlyclean-tags \
-distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
-install-exec install-data-am install-data install-am install \
-uninstall-am uninstall all-redirect all-am all installdirs \
-mostlyclean-generic distclean-generic clean-generic \
-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+uninstall-binPROGRAMS install-binPROGRAMS uninstall-includeHEADERS \
+install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \
+maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+rrdupdate.c: rrd_update.c
+	-ln -s rrd_update.c rrdupdate.c
 
+rrdupdate.o: rrdupdate.c
+	$(COMPILE) -DSTANDALONE -c rrdupdate.c
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.

Added: trunk/orca/packages/rrdtool-1.0.33/src/rrd_info.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_info.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_info.c	Sat Jul 13 21:25:51 2002
@@ -0,0 +1,142 @@
+/*****************************************************************************
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
+ *****************************************************************************
+ * rrd_info  Get Information about the configuration of an RRD
+ *****************************************************************************/
+
+#include "rrd_tool.h"
+#include <stdarg.h>
+
+/* proto */
+static char * sprintf_alloc(char *, ...);
+static info_t *push(info_t *, char *, enum info_type, infoval);
+info_t *rrd_info(int, char **);
+
+/* allocate memory for string */
+static char *
+sprintf_alloc(char *fmt, ...) {
+#ifdef HAVE_VSNPRINTF    
+    int maxlen = 50;
+#else
+    int maxlen = 1000;
+#endif
+    char *str = NULL;
+    va_list argp;
+    str = malloc(sizeof(char)*(strlen(fmt)+maxlen));
+    if (str != NULL) {
+	va_start(argp, fmt);
+#ifdef HAVE_VSNPRINTF
+	vsnprintf(str, maxlen-1, fmt, argp);
+#else
+	vsprintf(str, fmt, argp);
+#endif
+    }
+    va_end(argp);
+    return str;
+}
+
+static info_t 
+*push(info_t *info, char *key, enum info_type type, infoval value){
+    info_t *next;
+    next = malloc(sizeof(*next));
+    next->next = (info_t *) 0;
+    if( info )
+	info->next = next;
+    next->type = type;
+    next->key  = key;
+    switch (type) {
+    case RD_I_VAL:
+	next->value.u_val = value.u_val;
+	break;
+    case RD_I_CNT:
+	next->value.u_cnt = value.u_cnt;
+	break;
+    case RD_I_STR:
+	next->value.u_str = malloc(sizeof(char)*(strlen(value.u_str)+1));
+	strcpy(next->value.u_str,value.u_str);
+	break;
+    }
+    return(next);
+}
+
+  
+info_t *
+rrd_info(int argc, char **argv) {   
+    int          i,ii=0;
+    FILE         *in_file;
+    rrd_t        rrd;
+    info_t       *data,*cd;
+    infoval      info;
+
+    if(rrd_open(argv[1],&in_file,&rrd, RRD_READONLY)==-1){
+	return(NULL);
+    }
+    fclose(in_file);
+
+    info.u_str=argv[1];
+    cd=push(NULL,sprintf_alloc("filename"),    RD_I_STR, info);
+    data=cd;
+
+    info.u_str=rrd.stat_head->version;
+    cd=push(cd,sprintf_alloc("rrd_version"),    RD_I_STR, info);
+
+    info.u_cnt=rrd.stat_head->pdp_step;
+    cd=push(cd,sprintf_alloc("step"),       RD_I_CNT, info);
+
+    info.u_cnt=rrd.live_head->last_up;
+    cd=push(cd,sprintf_alloc("last_update"), RD_I_CNT, info);
+
+    for(i=0;i<rrd.stat_head->ds_cnt;i++){
+
+	info.u_str=rrd.ds_def[i].dst;
+	cd=push(cd,sprintf_alloc("ds[%s].type",             rrd.ds_def[i].ds_nam), RD_I_STR, info);
+
+	info.u_cnt=rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt;
+	cd=push(cd,sprintf_alloc("ds[%s].minimal_heartbeat",rrd.ds_def[i].ds_nam), RD_I_CNT, info);
+
+	info.u_val=rrd.ds_def[i].par[DS_min_val].u_val;
+	cd=push(cd,sprintf_alloc("ds[%s].min",              rrd.ds_def[i].ds_nam), RD_I_VAL, info);
+	
+	info.u_val=rrd.ds_def[i].par[DS_max_val].u_val;
+	cd=push(cd,sprintf_alloc("ds[%s].max",              rrd.ds_def[i].ds_nam), RD_I_VAL, info);
+	
+	info.u_str=rrd.pdp_prep[i].last_ds;
+	cd=push(cd,sprintf_alloc("ds[%s].last_ds",          rrd.ds_def[i].ds_nam), RD_I_STR, info);
+
+	info.u_val=rrd.pdp_prep[i].scratch[PDP_val].u_val;
+        cd=push(cd,sprintf_alloc("ds[%s].value",            rrd.ds_def[i].ds_nam), RD_I_VAL, info);
+
+	info.u_cnt=rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt;
+	cd=push(cd,sprintf_alloc("ds[%s].unknown_sec",      rrd.ds_def[i].ds_nam), RD_I_CNT, info);
+    }
+
+    for(i=0;i<rrd.stat_head->rra_cnt;i++){
+	info.u_str=rrd.rra_def[i].cf_nam;
+	cd=push(cd,sprintf_alloc("rra[%d].cf",         i),  RD_I_STR,   info);
+
+	info.u_cnt=rrd.rra_def[i].row_cnt;
+	cd=push(cd,sprintf_alloc("rra[%d].rows",i),  RD_I_CNT,   info);
+
+	info.u_cnt=rrd.rra_def[i].pdp_cnt;
+	cd=push(cd,sprintf_alloc("rra[%d].pdp_per_row",i),  RD_I_CNT,   info);
+
+        info.u_val=rrd.rra_def[i].par[RRA_cdp_xff_val].u_val;
+        cd=push(cd,sprintf_alloc("rra[%d].xff",i),  RD_I_VAL,   info);
+        
+	for(ii=0;ii<rrd.stat_head->ds_cnt;ii++){
+	    info.u_val=rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_val].u_val;
+	    cd=push(cd,sprintf_alloc("rra[%d].cdp_prep[%d].value",i,ii), RD_I_VAL, info);
+
+	    info.u_cnt=rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_unkn_pdp_cnt].u_cnt;
+	    cd=push(cd,sprintf_alloc("rra[%d].cdp_prep[%d].unknown_datapoints",i,ii), RD_I_CNT, info);
+        }
+    }
+    rrd_free(&rrd);
+    return(data);
+
+}
+
+
+
+
+

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_last.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_last.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_last.c	Sat Jul 13 21:25:52 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  *****************************************************************************
  * rrd_last.c
  *****************************************************************************

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_dump.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_dump.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_dump.c	Sat Jul 13 21:25:52 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  *****************************************************************************
  * rrd_dump  Display a RRD
  *****************************************************************************
@@ -80,9 +80,10 @@
                       * sizeof(rrd_value_t));
 	printf("\t<rra>\n");
 	printf("\t\t<cf> %s </cf>\n",rrd.rra_def[i].cf_nam);
-	printf("\t\t<pdp_per_row> %lu </pdp_per_row> <!-- %lu seconds -->\n\n",
+	printf("\t\t<pdp_per_row> %lu </pdp_per_row> <!-- %lu seconds -->\n",
 	       rrd.rra_def[i].pdp_cnt, rrd.rra_def[i].pdp_cnt
 	       *rrd.stat_head->pdp_step);
+	printf("\t\t<xff> %0.10e </xff>\n\n",rrd.rra_def[i].par[RRA_cdp_xff_val].u_val);
 	printf("\t\t<cdp_prep>\n");
 	for(ii=0;ii<rrd.stat_head->ds_cnt;ii++){
 	    double value = rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_val].u_val;
@@ -122,7 +123,7 @@
 #else
 # error "Need strftime"
 #endif
-	    printf("\t\t\t<!-- %s --> <row>",somestring);
+	    printf("\t\t\t<!-- %s / %d --> <row>",somestring,(int)now);
 	    for(iii=0;iii<rrd.stat_head->ds_cnt;iii++){			 
 		fread(&my_cdp,sizeof(rrd_value_t),1,in_file);		
 		if (isnan(my_cdp)){

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_diff.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_diff.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_diff.c	Sat Jul 13 21:25:52 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1999
  * This code is stolen from rateup (mrtg-2.x) by Dave Rand
  *****************************************************************************
  * diff calculate the difference between two very long integers available as

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_tool.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_tool.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_tool.c	Sat Jul 13 21:25:52 2002
@@ -1,15 +1,12 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2001
  *****************************************************************************
  * rrd_tool.c  Startup wrapper
- *****************************************************************************
- * $Id: rrd_tool.c,v 1.8 1998/03/08 12:35:11 oetiker Exp oetiker $
- * $Log: rrd_tool.c,v $
  *****************************************************************************/
 
 #include "rrd_tool.h"
 
-void PrintUsage(void);
+void PrintUsage(char *cmd);
 int CountArgs(char *aLine);
 int CreateArgs(char *, char *, int, char **);
 int HandleInputLine(int, char **, FILE*);
@@ -18,38 +15,53 @@
 #define MAX_LENGTH	10000
 
 
-void PrintUsage(void)
+void PrintUsage(char *cmd)
 {
-    printf("\n"
-	   "RRDtool 1.0.13  Copyright (C) 1999 by Tobias Oetiker <tobi at oetiker.ch>\n\n"
-	   "Usage: rrdtool [options] command command_options\n\n"
-	   "Valid commands and command_options are listed below.\n\n"
 
+    char help_main[] =
+	   "RRDtool 1.0.33  Copyright 1997-2001 by Tobias Oetiker <tobi at oetiker.ch>\n\n"
+	   "Usage: rrdtool [options] command command_options\n\n";
+
+    char help_list[] =
+	   "Valid commands: create, update, graph, dump, restore,\n"
+	   "\t\tlast, info, fetch, tune, resize\n\n";
+
+    char help_create[] =
 	   "* create - create a new RRD\n\n"
 	   "\trrdtool create filename [--start|-b start time]\n"
 	   "\t\t[--step|-s step]\n"
-	   "\t\t[DS:ds-name:DST:heartbeat:min:max] [RRA:CF:xff:steps:rows]\n\n"
+	   "\t\t[DS:ds-name:DST:heartbeat:min:max] [RRA:CF:xff:steps:rows]\n\n";
 
+    char help_dump[] =
 	   "* dump - dump an RRD to XML\n\n"
-	   "\trrdtool dump filename.rrd >filename.xml\n\n"
+	   "\trrdtool dump filename.rrd >filename.xml\n\n";
 
+    char help_info[] =
+	   "* info - returns the configuration and status of the\n\n"
+	   "\trrdtool info filename.rrd\n\n";
+
+    char help_restore[] =
 	   "* restore - restore an RRD file from its XML form\n\n"
-	   "\trrdtool restore [--range-check|-r] filename.xml filename.rrd\n\n"
+	   "\trrdtool restore [--range-check|-r] filename.xml filename.rrd\n\n";
 
+    char help_last[] =
            "* last - show last update time for RRD\n\n"
-           "\trrdtool last filename.rrd\n\n"
+           "\trrdtool last filename.rrd\n\n";
 
+    char help_update[] =
 	   "* update - update an RRD\n\n"
 	   "\trrdtool update filename\n"
 	   "\t\t--template|-t ds-name:ds-name:...\n"
 	   "\t\ttime|N:value[:value...]\n\n"
-	   "\t\t[ time:value[:value...] ..]\n\n"
+	   "\t\t[ time:value[:value...] ..]\n\n";
 
+    char help_fetch[] =
 	   "* fetch - fetch data out of an RRD\n\n"
 	   "\trrdtool fetch filename.rrd CF\n"
 	   "\t\t[--resolution|-r resolution]\n"
-	   "\t\t[--start|-s start] [--end|-e end]\n\n"
-	   	   
+	   "\t\t[--start|-s start] [--end|-e end]\n\n";
+
+    char help_graph[] =
 	   "* graph - generate a graph from one or several RRD\n\n"
 	   "\trrdtool graph filename [-s|--start seconds] [-e|--end seconds]\n"
 	   "\t\t[-x|--x-grid x-axis grid and label]\n"
@@ -60,6 +72,9 @@
 	   "\t\t[-u|--upper-limit value] [-z|--lazy]\n"
 	   "\t\t[-l|--lower-limit value] [-r|--rigid]\n"
 	   "\t\t[--alt-autoscale]\n"
+	   "\t\t[--alt-autoscale-max]\n"
+	   "\t\t[--units-exponent value]\n"	   
+	   "\t\t[--step seconds]\n"	   
 	   "\t\t[-f|--imginfo printfstr]\n"
 	   "\t\t[-a|--imgformat GIF|PNG]\n"
 	   "\t\t[-c|--color COLORTAG#rrggbb] [-t|--title string]\n"
@@ -71,23 +86,92 @@
 	   "\t\t[VRULE:value#rrggbb[:legend]]\n"
 	   "\t\t[LINE{1|2|3}:vname[#rrggbb[:legend]]]\n"
 	   "\t\t[AREA:vname[#rrggbb[:legend]]]\n"
-	   "\t\t[STACK:vname[#rrggbb[:legend]]]\n\n"
+	   "\t\t[STACK:vname[#rrggbb[:legend]]]\n\n";
 
-	   
+    char help_tune[] =
 	   " * tune -  Modify some basic properties of an RRD\n\n"
 	   "\trrdtool tune filename\n"
 	   "\t\t[--heartbeat|-h ds-name:heartbeat]\n"
 	   "\t\t[--data-source-type|-d ds-name:DST\n"
 	   "\t\t[--data-source-rename|-r old-name:new-name\n"
-	   "\t\t[--minimum|-i ds-name:min] [--maximum|-a ds-name:max]\n\n"
+	   "\t\t[--minimum|-i ds-name:min] [--maximum|-a ds-name:max]\n\n";
 
+    char help_resize[] =
 	   " * resize - alter the lenght of one of the RRAs in an RRD\n\n"
-	   "\trrdtool resize filename rranum GROW|SHRINK rows\n\n"
+	   "\trrdtool resize filename rranum GROW|SHRINK rows\n\n";
 
+    char help_lic[] =
 	   "RRDtool is distributed under the Terms of the GNU General\n"
 	   "Public License Version 2. (www.gnu.org/copyleft/gpl.html)\n\n"
 
-	   "For more information read the RRD manpages\n\n");
+	   "For more information read the RRD manpages\n\n";
+
+    enum { C_NONE, C_CREATE, C_DUMP, C_INFO, C_RESTORE, C_LAST,
+	   C_UPDATE, C_FETCH, C_GRAPH, C_TUNE, C_RESIZE };
+
+    int help_cmd = C_NONE;
+
+    if (cmd)
+	{
+	    if (!strcmp(cmd,"create"))
+		help_cmd = C_CREATE;
+    	    else if (!strcmp(cmd,"dump"))
+		help_cmd = C_DUMP;
+    	    else if (!strcmp(cmd,"info"))
+		help_cmd = C_INFO;
+    	    else if (!strcmp(cmd,"restore"))
+		help_cmd = C_RESTORE;
+    	    else if (!strcmp(cmd,"last"))
+		help_cmd = C_LAST;
+    	    else if (!strcmp(cmd,"update"))
+		help_cmd = C_UPDATE;
+    	    else if (!strcmp(cmd,"fetch"))
+		help_cmd = C_FETCH;
+    	    else if (!strcmp(cmd,"graph"))
+		help_cmd = C_GRAPH;
+    	    else if (!strcmp(cmd,"tune"))
+		help_cmd = C_TUNE;
+    	    else if (!strcmp(cmd,"resize"))
+		help_cmd = C_RESIZE;
+	}
+    fputs(help_main, stdout);
+    switch (help_cmd)
+	{
+	    case C_NONE:
+		fputs(help_list, stdout);
+		break;
+	    case C_CREATE:
+		fputs(help_create, stdout);
+		break;
+	    case C_DUMP:
+		fputs(help_dump, stdout);
+		break;
+	    case C_INFO:
+		fputs(help_info, stdout);
+		break;
+	    case C_RESTORE:
+		fputs(help_restore, stdout);
+		break;
+	    case C_LAST:
+		fputs(help_last, stdout);
+		break;
+	    case C_UPDATE:
+		fputs(help_update, stdout);
+		break;
+	    case C_FETCH:
+		fputs(help_fetch, stdout);
+		break;
+	    case C_GRAPH:
+		fputs(help_graph, stdout);
+		break;
+	    case C_TUNE:
+		fputs(help_tune, stdout);
+		break;
+	    case C_RESIZE:
+		fputs(help_resize, stdout);
+		break;
+	}
+    fputs(help_lic, stdout);
 }
 
 
@@ -103,11 +187,11 @@
 #endif
     if (argc == 1)
 	{
-	    PrintUsage();
+	    PrintUsage("");
 	    return 0;
 	}
     
-    if ((argc == 2) && (*argv[1] == '-'))
+    if ((argc == 2) && !strcmp("-",argv[1]))
 	{
 #if HAVE_GETRUSAGE
 	  struct rusage  myusage;
@@ -155,6 +239,11 @@
 		fflush(stdout); /* this is important for pipes to work */
 	    }
 	}
+    else if (argc == 2)
+	{
+		PrintUsage(argv[1]);
+		exit(0);
+	}
     else
 	HandleInputLine(argc, argv, stderr);    
     return 0;
@@ -171,7 +260,7 @@
 	|| strcmp("-help", argv[1]) == 0
 	|| strcmp("-?", argv[1]) == 0
 	|| strcmp("-h", argv[1]) == 0 ) {
-	PrintUsage();
+	PrintUsage("");
 	return 0;
     }
     
@@ -179,12 +268,42 @@
 	rrd_create(argc-1, &argv[1]);
     else if (strcmp("dump", argv[1]) == 0)
 	rrd_dump(argc-1, &argv[1]);
+    else if (strcmp("info", argv[1]) == 0){
+	info_t *data,*save;
+	data=rrd_info(argc-1, &argv[1]);
+	while (data) {
+	    save=data;
+	    printf ("%s = ", data->key);
+	    free(data->key);
+	    
+	    switch (data->type) {
+	    case RD_I_VAL:
+		if (isnan (data->value.u_val))
+		    printf("NaN");
+		else
+		    printf ("%0.10e", data->value.u_val);
+		break;
+	    case RD_I_CNT:
+		printf ("%lu", data->value.u_cnt);
+		break;
+	    case RD_I_STR:
+		printf ("\"%s\"", data->value.u_str);
+		free(data->value.u_str);
+		break;
+	    }
+	    data = data->next;
+	    free(save);
+	    printf ("\n");
+	}
+	free(data);
+    }
+	
     else if (strcmp("--version", argv[1]) == 0 ||
 	     strcmp("version", argv[1]) == 0 || 
 	     strcmp("v", argv[1]) == 0 ||
 	     strcmp("-v", argv[1]) == 0  ||
 	     strcmp("-version", argv[1]) == 0  )
-        printf("RRDtool   Copyright (C) 1999 by Tobias Oetiker <tobi at oetiker.ch>\n");
+        printf("RRDtool 1.0.33  Copyright (C) 1997-2001 by Tobias Oetiker <tobi at oetiker.ch>\n");
     else if (strcmp("restore", argv[1]) == 0)
 	rrd_restore(argc-1, &argv[1]);
     else if (strcmp("resize", argv[1]) == 0)
@@ -207,7 +326,7 @@
 	    for (i = start; i <= end; i += step){
 	        printf("%10lu:", i);
 	        for (ii = 0; ii < ds_cnt; ii++)
-		    printf(" %13.2f", *(datai++));
+		    printf(" %0.10e", *(datai++));
 	        printf("\n");
 	    }
 	    for (i=0;i<ds_cnt;i++)

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_update.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_update.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_update.c	Sat Jul 13 21:25:52 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  *****************************************************************************
  * rrd_update.c  RRD Update Function
  *****************************************************************************
@@ -23,7 +23,27 @@
 
 /*#define DEBUG */
 
+
+#ifdef STANDALONE
 int 
+main(int argc, char **argv){
+        rrd_update(argc,argv);
+        if (rrd_test_error()) {
+                printf("RRDtool 1.0.33  Copyright 1997-2000 by Tobias Oetiker <tobi at oetiker.ch>\n\n"
+                        "Usage: rrdupdate filename\n"
+                        "\t\t\t[--template|-t ds-name:ds-name:...]\n"
+                        "\t\t\ttime|N:value[:value...]\n\n"
+                        "\t\t\t[ time:value[:value...] ..]\n\n");
+                                   
+                printf("ERROR: %s\n",rrd_get_error());
+                rrd_clear_error();                                                            
+                return 1;
+        }
+        return 0;
+}
+#endif
+
+int
 rrd_update(int argc, char **argv)
 {
 
@@ -73,6 +93,7 @@
     int              wrote_to_file = 0;
     char             *template = NULL;          
 
+
     while (1) {
 	static struct option long_options[] =
 	{
@@ -101,7 +122,7 @@
 
     /* need at least 2 arguments: filename, data. */
     if (argc-optind < 2) {
-	rrd_set_error("not enough arguments");
+	rrd_set_error("Not enough arguments");
 	return -1;
     }
 
@@ -190,6 +211,11 @@
 		  tmpl_idx[tmpl_cnt-1]++; 
 		  /* go to the next entry on the template */
 		  dsname = &template[i+1];
+                  /* fix the damage we did before */
+                  if (i<tmpl_len) {
+                     template[i]=':';
+                  } 
+
 		}
 	    }	    
 	}
@@ -207,12 +233,22 @@
 
     /* loop through the arguments. */
     for(arg_i=optind+1; arg_i<argc;arg_i++) {
-	char *stepper;
+	char *stepper = malloc((strlen(argv[arg_i])+1)*sizeof(char));
+        char *step_start = stepper;
+        if (stepper == NULL){
+                rrd_set_error("faild duplication argv entry");
+                free(updvals);
+                free(pdp_temp);  
+                free(tmpl_idx);
+                rrd_free(&rrd);
+                fclose(rrd_file);
+                return(-1);
+         }
 	/* initialize all ds input to unknown except the first one
            which has always got to be set */
 	for(ii=1;ii<=rrd.stat_head->ds_cnt;ii++) updvals[ii] = "U";
 	ii=0;
-	stepper = argv[arg_i];
+	strcpy(stepper,argv[arg_i]);
 	updvals[0]=stepper;
 	while (*stepper) {
 	    if (*stepper == ':') {
@@ -228,6 +264,7 @@
 	if (ii != tmpl_cnt-1) {
 	    rrd_set_error("expected %lu data source readings (got %lu) from %s:...",
 			  tmpl_cnt-1, ii, argv[arg_i]);
+	    free(step_start);
 	    break;
 	}
 	
@@ -242,6 +279,7 @@
 	    rrd_set_error("illegal attempt to update using time %ld when "
 			  "last update time is %ld (minimum one second step)",
 			  current_time, rrd.live_head->last_up);
+	    free(step_start);
 	    break;
 	}
 	
@@ -250,6 +288,7 @@
 	if (rra_current != rra_begin) {
 	    if(fseek(rrd_file, rra_begin, SEEK_SET) != 0) {
 		rrd_set_error("seek error in rrd");
+		free(step_start);
 		break;
 	    }
 	    rra_current = rra_begin;
@@ -332,7 +371,7 @@
 		    rate = pdp_new[i] / interval;		   
 		    break;
 		default:
-		    rrd_set_error("rrd contains and DS type : '%s'",
+		    rrd_set_error("rrd contains unknown DS type : '%s'",
 				  rrd.ds_def[i].dst);
 		    break;
 		}
@@ -373,9 +412,10 @@
 	    }
 	}
 	/* break out of the argument parsing loop if the error_string is set */
-	if (rrd_test_error())
+	if (rrd_test_error()){
+	    free(step_start);
 	    break;
-
+	}
 	/* has a pdp_st moment occurred since the last run ? */
 
 	if (proc_pdp_st == occu_pdp_st){
@@ -615,12 +655,16 @@
 
 	    }
 	    /* break out of the argument parsing loop if error_string is set */
-	    if (rrd_test_error())
+	    if (rrd_test_error()){
+		free(step_start);
 		break;
+	    }
 	}
 	rrd.live_head->last_up = current_time;
+	free(step_start);
     }
 
+
     /* if we got here and if there is an error and if the file has not been
      * written to, then close things up and return. */
     if (rrd_test_error()) {

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_tool.h
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_tool.h	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_tool.h	Sat Jul 13 21:25:52 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997,1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  *****************************************************************************
  * rrd_tool.h   Common Header File
  *****************************************************************************
@@ -66,8 +66,7 @@
 #endif /* __svr4__ && __sun__ */
 #endif
 
-#include "parsetime.h"
-int proc_start_end (struct time_value *,  struct time_value *, time_t *, time_t *);
+#include "rrd.h"
 
 #ifndef WIN32
 
@@ -100,30 +99,35 @@
 
 #define DIM(x) (sizeof(x)/sizeof(x[0]))
 
-/* main function blocks */
-int    rrd_create(int argc, char **argv);
-int    rrd_update(int argc, char **argv);
-int    rrd_graph(int argc, char **argv, char ***prdata, int *xsize, int *ysize);
-int    rrd_fetch(int argc, char **argv, 
-		 time_t *start, time_t *end, unsigned long *step, 
-		 unsigned long *ds_cnt, char ***ds_namv, rrd_value_t **data);
-int    rrd_restore(int argc, char **argv);
-int    rrd_dump(int argc, char **argv);
-int    rrd_tune(int argc, char **argv);
-time_t rrd_last(int argc, char **argv);
-int    rrd_resize(int argc, char **argv);
+/* rrd info interface */
+enum info_type   { RD_I_VAL=0,
+	       RD_I_CNT,
+	       RD_I_STR  };
+
+typedef union infoval { 
+    unsigned long u_cnt; 
+    rrd_value_t   u_val;
+    char         *u_str;
+} infoval;
+
+typedef struct info_t {
+    char            *key;
+    enum info_type  type;
+    union infoval   value;
+    struct info_t   *next;
+} info_t;
+
+
+info_t *rrd_info(int, char **);
 
 /* HELPER FUNCTIONS */
-void rrd_set_error(char *fmt,...);
-void rrd_clear_error(void);
-int  rrd_test_error(void);
-char *rrd_get_error(void);
-int  LockRRD(FILE *);
 int GifSize(FILE *, long *, long *);
 int PngSize(FILE *, long *, long *);
 int PngSize(FILE *, long *, long *);
+
 #include <gd.h>
 void gdImagePng(gdImagePtr im, FILE *out);
+
 int rrd_create_fn(char *file_name, rrd_t *rrd);
 int rrd_fetch_fn(char *filename, enum cf_en cf_idx,
 		 time_t *start,time_t *end,
@@ -131,13 +135,13 @@
 		 unsigned long *ds_cnt,
 		 char        ***ds_namv,
 		 rrd_value_t **data);
+
 void rrd_free(rrd_t *rrd);
 void rrd_init(rrd_t *rrd);
 
-int  rrd_open(char *file_name, FILE **in_file, rrd_t *rrd, int rdwr);
+int rrd_open(char *file_name, FILE **in_file, rrd_t *rrd, int rdwr);
 int readfile(char *file, char **buffer, int skipfirst);
 
-
 #define RRD_READONLY    0
 #define RRD_READWRITE   1
 
@@ -149,7 +153,6 @@
 #endif
 
 
-
 #ifdef  __cplusplus
 }
 #endif

Added: trunk/orca/packages/rrdtool-1.0.33/src/rrd.h
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd.h	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd.h	Sat Jul 13 21:25:53 2002
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997,1998, 1999
+ *****************************************************************************
+ * rrdlib.h   Public header file for librrd
+ *****************************************************************************
+ * $Id: rrd_tool.h,v 1.5 1998/03/08 12:35:11 oetiker Exp oetiker $
+ * $Log: rrd_tool.h,v $
+ *****************************************************************************/
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifndef _RRDLIB_H
+#define _RRDLIB_H
+
+#include <time.h>
+
+/* Transplanted from rrd_format.h */
+typedef double       rrd_value_t;         /* the data storage type is
+                                           * double */
+/* END rrd_format.h */
+
+/* main function blocks */
+int    rrd_create(int, char **);
+int    rrd_update(int, char **);
+int    rrd_graph(int, char **, char ***, int *, int *);
+int    rrd_fetch(int, char **, time_t *, time_t *, unsigned long *,
+		 unsigned long *, char ***, rrd_value_t **);
+int    rrd_restore(int, char **);
+int    rrd_dump(int, char **);
+int    rrd_tune(int, char **);
+time_t rrd_last(int, char **);
+int    rrd_resize(int, char **);
+
+/* Transplanted from parsetime.h */
+typedef enum {
+        ABSOLUTE_TIME,
+        RELATIVE_TO_START_TIME, 
+        RELATIVE_TO_END_TIME
+} timetype;
+
+#define TIME_OK NULL
+
+struct time_value {
+  timetype type;
+  long offset;
+  struct tm tm;
+};
+
+char *parsetime(char *spec, struct time_value *ptv);
+/* END parsetime.h */
+
+int proc_start_end (struct time_value *,  struct time_value *, time_t *, time_t *);
+
+/* HELPER FUNCTIONS */
+void rrd_set_error(char *,...);
+void rrd_clear_error(void);
+int  rrd_test_error(void);
+char *rrd_get_error(void);
+int  LockRRD(FILE *);
+
+#endif /* _RRDLIB_H */
+
+#ifdef  __cplusplus
+}
+#endif

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_format.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_format.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_format.c	Sat Jul 13 21:25:53 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1999
  *****************************************************************************
  * rrd_format.c  RRD Database Format helper functions
  *****************************************************************************

Modified: trunk/orca/packages/rrdtool-1.0.33/src/gdpng.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/gdpng.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/gdpng.c	Sat Jul 13 21:25:53 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  *****************************************************************************
  * gdpng.c  add PNG output routine to gd library
  *****************************************************************************/

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_error.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_error.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_error.c	Sat Jul 13 21:25:53 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  *****************************************************************************
  * rrd_error.c   Common Header File
  *****************************************************************************
@@ -8,7 +8,8 @@
  *************************************************************************** */
 
 #include "rrd_tool.h"
-static char* rrd_error = NULL;
+#define MAXLEN 4096
+static char rrd_error[MAXLEN] = "\0";
 #include <stdarg.h>
 
 
@@ -16,33 +17,30 @@
 void
 rrd_set_error(char *fmt, ...)
 {
-    int maxlen = 4096;
     va_list argp;
     rrd_clear_error();
-    rrd_error = malloc(sizeof(char)*maxlen);
     va_start(argp, fmt);
 #ifdef HAVE_VSNPRINTF
-    vsnprintf(rrd_error, maxlen-1, fmt, argp);
+    vsnprintf((char *)rrd_error, MAXLEN-1, fmt, argp);
 #else
-    vsprintf(rrd_error, fmt, argp);
+    vsprintf((char *)rrd_error, fmt, argp);
 #endif
     va_end(argp);
 }
 
 int
 rrd_test_error(void) {
-    return rrd_error != NULL;
+    return rrd_error[0] != '\0';
 }
 
 void
 rrd_clear_error(void){
-    free(rrd_error);
-    rrd_error = NULL;
+    rrd_error[0] = '\0';
 }
 
 char *
 rrd_get_error(void){
-    return rrd_error;
+    return (char *)rrd_error;
 }
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_fetch.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_fetch.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_fetch.c	Sat Jul 13 21:25:53 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  *****************************************************************************
  * rrd_fetch.c  read date from an rrd to use for further processing
  *****************************************************************************
@@ -231,7 +231,6 @@
 
     *ds_cnt =   rrd.stat_head->ds_cnt; 
     if (((*data) = malloc(*ds_cnt * rows * sizeof(rrd_value_t)))==NULL){
-	long i;
 	rrd_set_error("malloc fetch data area");
 	for (i=0;i<*ds_cnt;i++)
 	      free((*ds_namv)[i]);
@@ -273,7 +272,6 @@
 		   + (rra_pointer
 		      * *ds_cnt
 		      * sizeof(rrd_value_t))),SEEK_SET) != 0){
-	long i;
 	rrd_set_error("seek error in RRA");
 	for (i=0;i<*ds_cnt;i++)
 	      free((*ds_namv)[i]);
@@ -325,10 +323,9 @@
 		if(fseek(in_file,(rra_base+rra_pointer
 			       * *ds_cnt
 			       * sizeof(rrd_value_t)),SEEK_SET) != 0){
-		    long i;
 		    rrd_set_error("wrap seek in RRA did fail");
-		    for (i=0;i<*ds_cnt;i++)
-			free((*ds_namv)[i]);
+		    for (ii=0;ii<*ds_cnt;ii++)
+			free((*ds_namv)[ii]);
 		    free(*ds_namv);
 		    rrd_free(&rrd);
 		    free(*data);
@@ -344,10 +341,9 @@
 	    if(fread(data_ptr,
 		     sizeof(rrd_value_t),
 		     *ds_cnt,in_file) != rrd.stat_head->ds_cnt){
-		long i;
 		rrd_set_error("fetching cdp from rra");
-		for (i=0;i<*ds_cnt;i++)
-		    free((*ds_namv)[i]);
+		for (ii=0;ii<*ds_cnt;ii++)
+		    free((*ds_namv)[ii]);
 		free(*ds_namv);
 		rrd_free(&rrd);
 		free(*data);

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_format.h
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_format.h	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_format.h	Sat Jul 13 21:25:53 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997, 1998, 1999
  *****************************************************************************
  * rrd_format.h  RRD Database Format header
  *****************************************************************************/
@@ -7,6 +7,8 @@
 #ifndef _RRD_FORMAT_H
 #define _RRD_FORMAT_H
 
+#include "rrd.h"
+
 /*****************************************************************************
  * put this in your /usr/lib/magic file (/etc/magic on HPUX)
  *
@@ -34,10 +36,6 @@
 					       * */
 #endif
 
-
-typedef double       rrd_value_t;         /* the data storage type is
-					   * double */
-
 typedef union unival { 
     unsigned long u_cnt; 
     rrd_value_t   u_val;
@@ -150,7 +148,9 @@
 					   * both can be set to UNKNOWN if you
 					   * do not care. Data outside the limits
  					   * set to UNKNOWN */
-#define DS_NAM_FMT    "%19[a-zA-Z0-9_]"
+
+/* The magic number here is one less than DS_NAM_SIZE */
+#define DS_NAM_FMT    "%19[a-zA-Z0-9_-]"
 #define DS_NAM_SIZE   20
 
 #define DST_FMT    "%19[A-Z]"
@@ -171,8 +171,8 @@
                        CF_LAST};
 
 enum rra_par_en {   RRA_cdp_xff_val=0};   /* what part of the consolidated 
-					    datapoint must be known, to produce a
-					    valid entry in the rra */
+					    datapoint may be unknown, while 
+					    still a valid entry in goes into the rra */
 		   	
 #define CF_NAM_FMT    "%19[A-Z]"
 #define CF_NAM_SIZE   20

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_resize.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_resize.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_resize.c	Sat Jul 13 21:25:53 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  *****************************************************************************
  * rrd_resize.c Alters size of an RRA
  *****************************************************************************

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_graph.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_graph.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_graph.c	Sat Jul 13 21:25:54 2002
@@ -1,5 +1,5 @@
 /****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997,1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  ****************************************************************************
  * rrd__graph.c  make creates ne rrds
  ****************************************************************************/
@@ -9,6 +9,10 @@
 #include <gdlucidan10.h>
 #include <gdlucidab12.h>
 #include <sys/stat.h>
+#ifdef WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
 
 #define SmallFont gdLucidaNormal10
 #define LargeFont gdLucidaBold12
@@ -21,20 +25,24 @@
 # define DPRINT(x)
 #endif
 
+#define DEF_NAM_FMT "%29[_A-Za-z0-9]"
+
 enum tmt_en {TMT_SECOND=0,TMT_MINUTE,TMT_HOUR,TMT_DAY,
 	     TMT_WEEK,TMT_MONTH,TMT_YEAR};
 
 enum grc_en {GRC_CANVAS=0,GRC_BACK,GRC_SHADEA,GRC_SHADEB,
 	     GRC_GRID,GRC_MGRID,GRC_FONT,GRC_FRAME,GRC_ARROW,__GRC_END__};
 
+
 enum gf_en {GF_PRINT=0,GF_GPRINT,GF_COMMENT,GF_HRULE,GF_VRULE,GF_LINE1,
 	    GF_LINE2,GF_LINE3,GF_AREA,GF_STACK, GF_DEF, GF_CDEF };
 
 enum op_en {OP_NUMBER=0,OP_VARIABLE,OP_INF,OP_PREV,OP_NEGINF,
-	    OP_UNKN,OP_NOW,OP_TIME,OP_ADD,OP_MOD,
+	    OP_UNKN,OP_NOW,OP_TIME,OP_LTIME,OP_ADD,OP_MOD,
             OP_SUB,OP_MUL,
 	    OP_DIV,OP_SIN, OP_DUP, OP_EXC, OP_POP,
 	    OP_COS,OP_LOG,OP_EXP,OP_LT,OP_LE,OP_GT,OP_GE,OP_EQ,OP_IF,
+	    OP_MIN,OP_MAX,OP_LIMIT, OP_FLOOR, OP_CEIL,
 	    OP_UN,OP_END};
 
 enum if_en {IF_GIF=0,IF_PNG=1};
@@ -173,8 +181,10 @@
 
 } graph_desc_t;
 
-#define ALTYGRID      0x01  /* use alternative y grid algorithm */
-#define ALTAUTOSCALE  0x02  /* use alternative algorithm to find lower and upper bounds */
+#define ALTYGRID          0x01  /* use alternative y grid algorithm */
+#define ALTAUTOSCALE      0x02  /* use alternative algorithm to find lower and upper bounds */
+#define ALTAUTOSCALE_MAX  0x04  /* use alternative algorithm to find upper bounds */
+#define NOLEGEND          0x08  /* use no legend */
 
 typedef struct image_desc_t {
 
@@ -185,6 +195,8 @@
     col_trip_t     graph_col[__GRC_END__]; /* real colors for the graph */   
     char           ylegend[200];   /* legend along the yaxis */
     char           title[200];     /* title for graph */
+    int            draw_x_grid;      /* no x-grid at all */
+    int            draw_y_grid;      /* no x-grid at all */
     xlab_t         xlab_user;      /* user defined labeling for xaxis */
     char           xlab_form[200]; /* format for the label on the xaxis */
 
@@ -192,6 +204,7 @@
     int            ylabfact;       /* every how many y grid shall a label be written ? */
 
     time_t         start,end;      /* what time does the graph cover */
+    unsigned long           step;           /* any preference for the default step ? */
     rrd_value_t    minval,maxval;  /* extreme values in the data */
     int            rigid;          /* do not expand range even with 
 				      values outside */
@@ -210,6 +223,7 @@
     double         magfact;        /* numerical magnitude*/
     long         base;            /* 1000 or 1024 depending on what we graph */
     char           symbol;         /* magnitude symbol for y-axis */
+    int            unitsexponent;    /* 10*exponent for units on y-asis */
     int            extra_flags;    /* flags for boolean options */
     /* data elements */
 
@@ -219,8 +233,42 @@
 
 } image_desc_t;
 
+/* Prototypes */
+int xtr(image_desc_t *,time_t);
+int ytr(image_desc_t *, double);
+enum gf_en gf_conv(char *);
+enum if_en if_conv(char *);
+enum tmt_en tmt_conv(char *);
+enum grc_en grc_conv(char *);
+int im_free(image_desc_t *);
+void auto_scale( image_desc_t *,  double *, char **, double *);
+void si_unit( image_desc_t *);
+void expand_range(image_desc_t *);
+void reduce_data( enum cf_en,  unsigned long,  time_t *, time_t *,  unsigned long *,  unsigned long *,  rrd_value_t **);
+int data_fetch( image_desc_t *);
+long find_var(image_desc_t *, char *);
+long lcd(long *);
+int data_calc( image_desc_t *);
+int data_proc( image_desc_t *);
+time_t find_first_time( time_t,  enum tmt_en,  long);
+time_t find_next_time( time_t,  enum tmt_en,  long);
+void gator( gdImagePtr, int, int);
+int tzoffset(time_t);
+int print_calc(image_desc_t *, char ***);
+int leg_place(image_desc_t *);
+int horizontal_grid(gdImagePtr, image_desc_t *);
+int horizontal_log_grid(gdImagePtr, image_desc_t *);
+void vertical_grid( gdImagePtr, image_desc_t *);
+void axis_paint( image_desc_t *, gdImagePtr);
+void grid_paint( image_desc_t *, gdImagePtr);
+gdImagePtr MkLineBrush(image_desc_t *,long, enum gf_en);
+int lazy_check(image_desc_t *);
+int graph_paint(image_desc_t *, char ***);
+int gdes_alloc(image_desc_t *);
+int scan_for_col(char *, int, char *);
+int rrd_graph(int, char **, char ***, int *, int *);
 int bad_format(char *);
-
+rpnp_t * str2rpn(image_desc_t *,char *);
 
 /* translate time values into x coordinates */   
 /*#define xtr(x) (int)((double)im->xorigin \
@@ -228,14 +276,14 @@
 		* ((double)(x) - im->start)+0.5) */
 /* initialize with xtr(im,0); */
 int
-xtr(image_desc_t *im,time_t time){
+xtr(image_desc_t *im,time_t mytime){
     static double pixie;
-    if (time==0){
+    if (mytime==0){
 	pixie = (double) im->xsize / (double)(im->end - im->start);
 	return im->xorigin;
     }
     return (int)((double)im->xorigin 
-		 + pixie * ( time - im->start ) );
+		 + pixie * ( mytime - im->start ) );
 }
 
 /* translate data values into y coordinates */
@@ -282,6 +330,7 @@
 
 /* conversion function for symbolic entry names */
 
+
 #define conv_if(VV,VVV) \
    if (strcmp(#VV, string) == 0) return VVV ;
 
@@ -389,18 +438,18 @@
 		      "E"};/* 10e18  Exa */
 
     int symbcenter = 6;
-    int index;  
+    int sindex;  
 
     if (*value == 0.0 || isnan(*value) ) {
-	index = 0;
+	sindex = 0;
 	*magfact = 1.0;
     } else {
-	index = floor(log(fabs(*value))/log(im->base)); 
-	*magfact = pow(im->base, index);
+	sindex = floor(log(fabs(*value))/log((double)im->base)); 
+	*magfact = pow((double)im->base, (double)sindex);
 	(*value) /= (*magfact);
     }
-    if ( index <= symbcenter && index >= -symbcenter) {
-	(*symb_ptr) = symbol[index+symbcenter];
+    if ( sindex <= symbcenter && sindex >= -symbcenter) {
+	(*symb_ptr) = symbol[sindex+symbcenter];
     }
     else {
 	(*symb_ptr) = "?";
@@ -432,11 +481,18 @@
     int   symbcenter = 6;
     double digits;  
     
-    digits = floor( log( max( fabs(im->minval),fabs(im->maxval)))/log(im->base)); 
-    im->magfact = pow(im->base , digits);
+    if (im->unitsexponent != 9999) {
+	/* unitsexponent = 9, 6, 3, 0, -3, -6, -9, etc */
+        digits = floor(im->unitsexponent / 3);
+    } else {
+        digits = floor( log( max( fabs(im->minval),fabs(im->maxval)))/log((double)im->base)); 
+    }
+    im->magfact = pow((double)im->base , digits);
+
 #ifdef DEBUG
     printf("digits %6.3f  im->magfact %6.3f\n",digits,im->magfact);
 #endif
+
     if ( ((digits+symbcenter) < sizeof(symbol)) &&
 		    ((digits+symbcenter) >= 0) )
         im->symbol = symbol[(int)digits+symbcenter];
@@ -464,20 +520,38 @@
     
 
     
-    #ifdef DEBUG
+#ifdef DEBUG
     printf("Min: %6.2f Max: %6.2f MagFactor: %6.2f\n",
 	   im->minval,im->maxval,im->magfact);
-    #endif
+#endif
 
     if (isnan(im->ygridstep)){
 	if(im->extra_flags & ALTAUTOSCALE) {
 	    /* measure the amplitude of the function. Make sure that
 	       graph boundaries are slightly higher then max/min vals
 	       so we can see amplitude on the graph */
-	      adj = (im->maxval - im->minval) * 0.1;
+	      double delt, fact;
+
+	      delt = im->maxval - im->minval;
+	      adj = delt * 0.1;
+	      fact = 2.0 * pow(10.0,
+		    floor(log10(max(fabs(im->minval), fabs(im->maxval)))) - 2);
+	      if (delt < fact) {
+		adj = (fact - delt) * 0.55;
+#ifdef DEBUG
+	      printf("Min: %6.2f Max: %6.2f delt: %6.2f fact: %6.2f adj: %6.2f\n", im->minval, im->maxval, delt, fact, adj);
+#endif
+	      }
 	      im->minval -= adj;
 	      im->maxval += adj;
 	}
+	else if(im->extra_flags & ALTAUTOSCALE_MAX) {
+	    /* measure the amplitude of the function. Make sure that
+	       graph boundaries are slightly higher than max vals
+	       so we can see amplitude on the graph */
+	      adj = (im->maxval - im->minval) * 0.1;
+	      im->maxval += adj;
+	}
 	else {
 	    scaled_min = im->minval / im->magfact;
 	    scaled_max = im->maxval / im->magfact;
@@ -515,96 +589,140 @@
 }
 
     
+/* reduce data reimplementation by Alex */
 
 void
 reduce_data(
     enum cf_en     cf,         /* which consolidation function ?*/
     unsigned long  cur_step,   /* step the data currently is in */
-    time_t         *start,
-    time_t         *end,       /* which time frame do you want ?
-				* will be changed to represent reality */
-    unsigned long  *step,      /* desired step size. Will be adjusted to new increassed step size */
+    time_t         *start,     /* start, end and step as requested ... */
+    time_t         *end,       /* ... by the application will be   ... */
+    unsigned long  *step,      /* ... adjusted to represent reality    */
     unsigned long  *ds_cnt,    /* number of data sources in file */
     rrd_value_t    **data)     /* two dimensional array containing the data */
 {
     int i,reduce_factor = ceil((double)(*step) / (double)cur_step);
-    unsigned long src_row,trg_row,col,row_cnt,start_offset,skiprows=0;
+    unsigned long col,dst_row,row_cnt,start_offset,end_offset,skiprows=0;
+    rrd_value_t    *srcptr,*dstptr;
 
     (*step) = cur_step*reduce_factor; /* set new step size for reduced data */
-    /* adjust the start time so that it is a multiple of the new steptime */
+    dstptr = *data;
+    srcptr = *data;
 
-    row_cnt = ((*end)-(*start))/cur_step+1; /* +1 because start and end are pointers to first and last entry */
-    
+    /* We were given one extra row at the beginning of the interval.
+    ** We also need to return one extra row.  The extra interval is
+    ** the one defined by the start time in both cases.  It is not
+    ** used when graphing but maybe we can use it while reducing the
+    ** data.
+    */
+    row_cnt = ((*end)-(*start))/cur_step +1;
+
+    /* alter start and end so that they are multiples of the new steptime.
+    ** End will be shifted towards the future and start will be shifted
+    ** towards the past in order to include the requested interval
+    */ 
+    end_offset = (*end) % (*step);
+    if (end_offset) end_offset = (*step)-end_offset;
     start_offset = (*start) % (*step);
-    /* move the start pointer into the past so that the reduced data set
-       fully covers the timespan of the new dataset */
-    (*start) -= start_offset;
-
-    trg_row=0;
-    /* skip the first <skiprows> of original data because we already covered
-       by the row of *unknown* data added to the reduced dataset */
-    
-    skiprows = ((*step) - start_offset) / cur_step;
-
-    if (start_offset > 0) {
-      /* we don't have full data for the first row, so we'll ditch 
-         what is there and fill it with *UNKNOWN* */
-      for (col=0;col<(*ds_cnt);col++) {
-	(*data)[col] = DNAN;
-      }
-      trg_row++; /* one row of target filled already */
+    (*end) = (*end)+end_offset;
+    (*start) = (*start)-start_offset;
 
-    };
- 
-        
-    for (src_row = skiprows; src_row < row_cnt; src_row+=reduce_factor) {
-	for (col=0;col<(*ds_cnt);col++){
-	    double newval=DNAN;
+    /* The first destination row is unknown yet it still needs
+    ** to be present in the returned data.  Skip it.
+    ** Don't make it NaN or we might overwrite the source.
+    */
+    dstptr += (*ds_cnt);
+
+    /* Depending on the amount of extra data needed at the
+    ** start of the destination, three things can happen:
+    ** -1- start_offset == 0:  skip the extra source row
+    ** -2- start_offset == cur_step: do nothing
+    ** -3- start_offset > cur_step: skip some source rows and 
+    **                      fill one destination row with NaN
+    */
+    if (start_offset==0) {
+	srcptr+=(*ds_cnt);
+	row_cnt--;
+    } else if (start_offset!=cur_step) {
+	skiprows=((*step)-start_offset)/cur_step+1;
+	srcptr += ((*ds_cnt)*skiprows);
+	row_cnt-=skiprows;
+	for (col=0;col<(*ds_cnt);col++) *dstptr++=DNAN;
+    }
+
+    /* If we had to alter the endtime, there won't be
+    ** enough data to fill the last row.  This means
+    ** we have to skip some rows at the end
+    */
+    if (end_offset) {
+	skiprows = ((*step)-end_offset)/cur_step;
+	row_cnt-=skiprows;
+    }
+
+
+/* Sanity check: row_cnt should be multiple of reduce_factor */
+/* if this gets triggered, something is REALY WRONG ... we die immediately */
+
+    if (row_cnt%reduce_factor) {
+	printf("SANITY CHECK: %lu rows cannot be reduced by %i \n",
+				row_cnt,reduce_factor);
+	printf("BUG in reduce_data()\n");
+	exit(1);
+    }
+
+    /* Now combine reduce_factor intervals at a time
+    ** into one interval for the destination.
+    */
+
+    for (dst_row=0;row_cnt>=reduce_factor;dst_row++) {
+	for (col=0;col<(*ds_cnt);col++) {
+	    rrd_value_t newval=DNAN;
 	    unsigned long validval=0;
-	    for (i=0;i<reduce_factor && src_row+i<row_cnt;i++) {		
-		unsigned long ptr = (src_row+i)* (*ds_cnt)+col;
-		if (isnan((*data)[ptr])) continue; /* we can't help with NAN */
+
+	    for (i=0;i<reduce_factor;i++) {
+		if (isnan(srcptr[i*(*ds_cnt)+col])) {
+		    continue;
+		}
 		validval++;
-		if (isnan(newval)) {
-		    newval = (*data)[ptr];
-		} else {
-		   
-  		  switch (cf) {
-		  case CF_AVERAGE:
-		      newval += (*data)[ptr];
-		      break;
-		  case CF_MINIMUM:
-		      newval = min (newval,(*data)[ptr]);
-		      break;
-		  case CF_MAXIMUM:
-		      newval = max (newval,(*data)[ptr]);
-		      break;
-		  case CF_LAST:
-		      newval = (*data)[ptr];
-		      break;
-		  }
+		if (isnan(newval)) newval = srcptr[i*(*ds_cnt)+col];
+		else {
+		    switch (cf) {
+			case CF_AVERAGE:
+			    newval += srcptr[i*(*ds_cnt)+col];
+			    break;
+			case CF_MINIMUM:
+			    newval = min (newval,srcptr[i*(*ds_cnt)+col]);
+			    break;
+			case CF_MAXIMUM:
+			    newval = max (newval,srcptr[i*(*ds_cnt)+col]);
+			    break;
+			case CF_LAST:
+			    newval = srcptr[i*(*ds_cnt)+col];
+			    break;
+		    }
 		}
 	    }
 	    if (validval == 0){newval = DNAN;} else{
 		switch (cf) {
-		case CF_AVERAGE:		
-		    newval /= validval;
-		    break;
-		case CF_MINIMUM:
-		case CF_MAXIMUM:
-		case CF_LAST:
-		    break;
+		    case CF_AVERAGE:		
+			newval /= validval;
+			break;
+		    case CF_MINIMUM:
+		    case CF_MAXIMUM:
+		    case CF_LAST:
+			break;
 		}
 	    }
-	    (*data)[(trg_row)* (*ds_cnt)+col] = newval;
+	    *dstptr++=newval;
 	}
-	trg_row++;
-    }
-    *end = (*start) + (*step) * (trg_row);
-    /* make sure there is some NAN at the end of the graph */
-    for (col=0;col<(*ds_cnt);col++){
-      (*data)[(trg_row)* *ds_cnt+col] = DNAN;
+	srcptr+=(*ds_cnt)*reduce_factor;
+	row_cnt-=reduce_factor;
     }
+
+    /* If we had to alter the endtime, we didn't have enough
+    ** source rows to fill the last row. Fill it with NaN.
+    */
+    if (end_offset!=0) for (col=0;col<(*ds_cnt);col++) *dstptr++ = DNAN;
 }
 
 
@@ -740,13 +858,15 @@
 	    return NULL;
 	}
 
-	else if((sscanf(expr,"%lf%n",&rpnp[steps].val,&pos) == 1) && (expr[pos] == ',')){
+	else if((sscanf(expr,"%lf%n",&rpnp[steps].val,&pos) == 1) 
+	        && (expr[pos] == ',')){
  	    rpnp[steps].op = OP_NUMBER;
 	    expr+=pos;
 	} 
 	
 #define match_op(VV,VVV) \
-        else if (strncmp(expr, #VVV, strlen(#VVV))==0){ \
+        else if (strncmp(expr, #VVV, strlen(#VVV))==0 && \
+                (expr[strlen(#VVV)] == ',' || expr[strlen(#VVV)] == '\0') ){ \
 	    rpnp[steps].op = VV; \
 	    expr+=strlen(#VVV); \
 	}
@@ -759,6 +879,8 @@
 	match_op(OP_SIN,SIN)
 	match_op(OP_COS,COS)
 	match_op(OP_LOG,LOG)
+	match_op(OP_FLOOR,FLOOR)
+	match_op(OP_CEIL,CEIL)
 	match_op(OP_EXP,EXP)
 	match_op(OP_DUP,DUP)
 	match_op(OP_EXC,EXC)
@@ -769,6 +891,9 @@
 	match_op(OP_GE,GE)
 	match_op(OP_EQ,EQ)
 	match_op(OP_IF,IF)
+	match_op(OP_MIN,MIN)
+	match_op(OP_MAX,MAX)
+	match_op(OP_LIMIT,LIMIT)
 	  /* order is important here ! .. match longest first */
 	match_op(OP_UNKN,UNKN)
 	match_op(OP_UN,UN)
@@ -776,12 +901,14 @@
 	match_op(OP_PREV,PREV)
 	match_op(OP_INF,INF)
 	match_op(OP_NOW,NOW)
+	match_op(OP_LTIME,LTIME)
 	match_op(OP_TIME,TIME)
 
+
 #undef match_op
 
 
-	else if ((sscanf(expr,"%29[_A-Za-z0-9]%n",
+	else if ((sscanf(expr,DEF_NAM_FMT "%n",
 			 vname,&pos) == 1) 
 		 && ((rpnp[steps].ptr = find_var(im,vname)) != -1)){
 	    rpnp[steps].op = OP_VARIABLE;
@@ -805,6 +932,38 @@
     return rpnp;
 }
 
+/* figure out what the local timezone offset for any point in
+   time was. Return it in seconds */
+
+int
+tzoffset( time_t now ){
+  int gm_sec, gm_min, gm_hour, gm_yday, gm_year,
+    l_sec, l_min, l_hour, l_yday, l_year;
+  struct tm *t;
+  int off;
+  t = gmtime(&now);
+  gm_sec = t->tm_sec;
+  gm_min = t->tm_min;
+  gm_hour = t->tm_hour;
+  gm_yday = t->tm_yday;
+  gm_year = t->tm_year;
+  t = localtime(&now);
+  l_sec = t->tm_sec;
+  l_min = t->tm_min;
+  l_hour = t->tm_hour;
+  l_yday = t->tm_yday;
+  l_year = t->tm_year;
+  off = (l_sec-gm_sec)+(l_min-gm_min)*60+(l_hour-gm_hour)*3600; 
+  if ( l_yday > gm_yday || l_year > gm_year){
+        off += 24*3600;
+  } else if ( l_yday < gm_yday || l_year < gm_year){
+        off -= 24*3600;
+  }
+
+  return off;
+}
+
+    
 
 #define dc_stackblock 100
 
@@ -841,7 +1000,7 @@
 	for(rpi=0;im->gdes[gdi].rpnp[rpi].op != OP_END;rpi++){
 	    if(im->gdes[gdi].rpnp[rpi].op == OP_VARIABLE){
 		long ptr = im->gdes[gdi].rpnp[rpi].ptr;
-		if ((steparray = rrd_realloc(steparray, (++stepcnt+1)*sizeof(double)))==NULL){
+		if ((steparray = rrd_realloc(steparray, (++stepcnt+1)*sizeof(*steparray)))==NULL){
 		  rrd_set_error("realloc steparray");
 		  free(stack);
 		  return -1;
@@ -903,7 +1062,7 @@
 	    for (rpi=0;im->gdes[gdi].rpnp[rpi].op != OP_END;rpi++){
 		if (stptr +5 > dc_stacksize){
 		    dc_stacksize += dc_stackblock;		
-		    stack = rrd_realloc(stack,dc_stacksize*sizeof(long));
+		    stack = rrd_realloc(stack,dc_stacksize*sizeof(*stack));
 		    if (stack==NULL){
 			rrd_set_error("RPN stack overflow");
 			return -1;
@@ -924,7 +1083,7 @@
 		    stack[++stptr] =  *im->gdes[gdi].rpnp[rpi].data;
 		    break;
 		case OP_PREV:
-		    if (dataidx == 0) {
+		    if (dataidx <= 0) {
                        stack[++stptr] = DNAN;
                     } else {
                        stack[++stptr] = im->gdes[gdi].data[dataidx];
@@ -945,6 +1104,9 @@
 		case OP_TIME:
 		    stack[++stptr] = (double)now;
 		    break;
+		case OP_LTIME:
+		    stack[++stptr] = (double)tzoffset(now)+(double)now;
+		    break;
 		case OP_ADD:
 		    if(stptr<1){
 			rrd_set_error("RPN stack underflow");
@@ -1006,6 +1168,22 @@
 		    }
 		    stack[stptr] = cos(stack[stptr]);
 		    break;
+		case OP_CEIL:
+		    if(stptr<0){
+			rrd_set_error("RPN stack underflow");
+			free(stack);
+			return -1;
+		    }
+		    stack[stptr] = ceil(stack[stptr]);
+		    break;
+		case OP_FLOOR:
+		    if(stptr<0){
+			rrd_set_error("RPN stack underflow");
+			free(stack);
+			return -1;
+		    }
+		    stack[stptr] = floor(stack[stptr]);
+		    break;
 		case OP_LOG:
 		    if(stptr<0){
 			rrd_set_error("RPN stack underflow");
@@ -1057,7 +1235,10 @@
 			free(stack);
 			return -1;
 		    }
-		    stack[stptr-1] = stack[stptr-1] < stack[stptr] ? 1.0 : 0.0;
+		    if (isnan(stack[stptr-1]) || isnan(stack[stptr]))
+		        stack[stptr-1] = 0.0;
+		    else
+			stack[stptr-1] = stack[stptr-1] < stack[stptr] ? 1.0 : 0.0;
 		    stptr--;
 		    break;
 		case OP_LE:
@@ -1066,7 +1247,10 @@
 			free(stack);
 			return -1;
 		    }
-		    stack[stptr-1] = stack[stptr-1] <= stack[stptr] ? 1.0 : 0.0;
+		    if (isnan(stack[stptr-1]) || isnan(stack[stptr]))
+		        stack[stptr-1] = 0.0;
+		    else
+		        stack[stptr-1] = stack[stptr-1] <= stack[stptr] ? 1.0 : 0.0;
 		    stptr--;
 		    break;
 		case OP_GT:
@@ -1075,7 +1259,10 @@
 			free(stack);
 			return -1;
 		    }
-		    stack[stptr-1] = stack[stptr-1] > stack[stptr] ? 1.0 : 0.0;
+		    if (isnan(stack[stptr-1]) || isnan(stack[stptr]))
+		        stack[stptr-1] = 0.0;
+		    else
+		        stack[stptr-1] = stack[stptr-1] > stack[stptr] ? 1.0 : 0.0;
 		    stptr--;
 		    break;
 		case OP_GE:
@@ -1084,7 +1271,10 @@
 			free(stack);
 			return -1;
 		    }
-		    stack[stptr-1] = stack[stptr-1] >= stack[stptr] ? 1.0 : 0.0;
+		    if (isnan(stack[stptr-1]) || isnan(stack[stptr]))
+		        stack[stptr-1] = 0.0;
+		    else
+		        stack[stptr-1] = stack[stptr-1] >= stack[stptr] ? 1.0 : 0.0;
 		    stptr--;
 		    break;
 		case OP_EQ:
@@ -1093,7 +1283,10 @@
 			free(stack);
 			return -1;
 		    }
-		    stack[stptr-1] = stack[stptr-1] == stack[stptr] ? 1.0 : 0.0;
+		    if (isnan(stack[stptr-1]) || isnan(stack[stptr]))
+		        stack[stptr-1] = 0.0;
+		    else
+		        stack[stptr-1] = stack[stptr-1] == stack[stptr] ? 1.0 : 0.0;
 		    stptr--;
 		    break;
 		case OP_IF:
@@ -1106,6 +1299,52 @@
 		    stptr--;
 		    stptr--;
 		    break;
+		case OP_MIN:
+		    if(stptr<1){
+			rrd_set_error("RPN stack underflow");
+			free(stack);
+			return -1;
+		    }
+		    if (isnan(stack[stptr-1])) 
+			;
+		    else if (isnan(stack[stptr]))
+		        stack[stptr-1] = stack[stptr];
+		    else if (stack[stptr-1] > stack[stptr])
+		        stack[stptr-1] = stack[stptr];
+		    stptr--;
+		    break;
+		case OP_MAX:
+		    if(stptr<1){
+			rrd_set_error("RPN stack underflow");
+			free(stack);
+			return -1;
+		    }
+		    if (isnan(stack[stptr-1])) 
+			;
+		    else if (isnan(stack[stptr]))
+		        stack[stptr-1] = stack[stptr];
+		    else if (stack[stptr-1] < stack[stptr])
+		        stack[stptr-1] = stack[stptr];
+		    stptr--;
+		    break;
+		case OP_LIMIT:
+		    if(stptr<2){
+			rrd_set_error("RPN stack underflow");
+			free(stack);
+			return -1;
+		    }
+		    if (isnan(stack[stptr-2])) 
+			;
+		    else if (isnan(stack[stptr-1]))
+		        stack[stptr-2] = stack[stptr-1];
+		    else if (isnan(stack[stptr]))
+		        stack[stptr-2] = stack[stptr];
+		    else if (stack[stptr-2] < stack[stptr-1])
+		        stack[stptr-2] = DNAN;
+		    else if (stack[stptr-2] > stack[stptr])
+		        stack[stptr-2] = DNAN;
+		    stptr-=2;
+		    break;
 		case OP_UN:
 		    if(stptr<0){
 			rrd_set_error("RPN stack underflow");
@@ -1283,8 +1522,9 @@
 	tm.tm_sec=0;
 	tm.tm_min = 0;
 	tm.tm_hour = 0;
-	tm.tm_mday -= tm.tm_wday -1 ; break;	/* -1 because we want the monday */
+	tm.tm_mday -= tm.tm_wday -1;	/* -1 because we want the monday */
 	if (tm.tm_wday==0) tm.tm_mday -= 7; /* we want the *previous* monday */
+	break;
     case TMT_MONTH:
 	tm.tm_sec=0;
 	tm.tm_min = 0;
@@ -1338,14 +1578,25 @@
 	  
 }
 
-/* create a grid on the graph. it determines what to do
-   from the values of xsize, start and end */
-/* the xaxis labels are determined from the number of seconds per pixel
-   in the requested graph */
-
-
 void gator( gdImagePtr gif, int x, int y){ 
 
+/* this function puts the name of the author and the tool into the
+   graph. Remove if you must, but please note, that it is here,
+   because I would like people who look at rrdtool generated graphs to
+   see what was used to do it. No obviously you can also add a credit
+   line to your webpage or printed document, this is fine with me. But
+   as I have no control over this, I added the little tag in here. 
+*/
+
+/* the fact that the text of what gets put into the graph is not
+   visible in the function, has lead some to think this is for
+   obfuscation reasons. While this is a nice side effect (I addmit),
+   it is not the prime reason. The prime reason is, that the font
+   used, is so small, that I had to hand edit the characters to ensure
+   readability. I could thus not use the normal gd functions to write,
+   but had to embed a slightly compressed bitmap version into the code. 
+*/
+
     int li[]={0,0,1, 0,4,5, 0,8,9, 0,12,14, 0,17,17, 0,21,21, 
 	      0,24,24, 0,34,34, 0,40,42, 0,45,45, 0,48,49, 0,52,54, 
 	      0,61,61, 0,64,66, 0,68,70, 0,72,74, 0,76,76, 0,78,78, 
@@ -1374,6 +1625,7 @@
 	  gdImageSetPixel(gif,x-li[i],ii,graph_col[GRC_GRID].i); 
 }
 
+
 /* calculate values required for PRINT and GPRINT functions */
 
 int
@@ -1405,8 +1657,8 @@
 		     *im->gdes[vidx].ds_cnt);
 	    printval = DNAN;
 	    validsteps = 0;
-	    for(ii=im->gdes[vidx].ds;
-		ii < max_ii;
+	    for(ii=im->gdes[vidx].ds+im->gdes[vidx].ds_cnt;
+		ii < max_ii+im->gdes[vidx].ds_cnt;
 		ii+=im->gdes[vidx].ds_cnt){
 		 if (! finite(im->gdes[vidx].data[ii]))
 		     continue;
@@ -1504,7 +1756,6 @@
 int
 leg_place(image_desc_t *im)
 {
-    
     /* graph labels */
     int   interleg = SmallFont->w*2;
     int   box = SmallFont->h*1.2;
@@ -1518,6 +1769,7 @@
     char  prt_fctn; /*special printfunctions */
     int  *legspace;
 
+  if( !(im->extra_flags & NOLEGEND) ) {
     if ((legspace = malloc(im->gdes_c*sizeof(int)))==NULL){
        rrd_set_error("malloc for legspace");
        return -1;
@@ -1615,9 +1867,16 @@
     }
     im->ygif = leg_y+6;
     free(legspace);
-    return 0;
+  }
+  return 0;
 }
 
+/* create a grid on the graph. it determines what to do
+   from the values of xsize, start and end */
+
+/* the xaxis labels are determined from the number of seconds per pixel
+   in the requested graph */
+
 
 
 int
@@ -1667,7 +1926,7 @@
 		sprintf(labfmt, "%%%d.%df", decimals - fractionals + 1, -fractionals + 1);
 	    else
 		sprintf(labfmt, "%%%d.1f", decimals + 1);
-	    gridstep = pow(10, fractionals);
+	    gridstep = pow((double)10, (double)fractionals);
 	    if(gridstep == 0) /* range is one -> 0.1 is reasonable scale */
 		gridstep = 0.1;
 	    /* should have at least 5 lines but no more then 15 */
@@ -1810,7 +2069,7 @@
     polyPoints[0].x=im->xorigin;
     polyPoints[1].x=im->xorigin+im->xsize;
     /* paint minor grid */
-    for (value = pow(10, log10(im->minval) 
+    for (value = pow((double)10, log10(im->minval) 
 			  - fmod(log10(im->minval),log10(yloglab[minoridx][0])));
 	 value  <= im->maxval;
 	 value *= yloglab[minoridx][0]){
@@ -1831,7 +2090,7 @@
     }
 
     /* paint major grid and labels*/
-    for (value = pow(10, log10(im->minval) 
+    for (value = pow((double)10, log10(im->minval) 
 			  - fmod(log10(im->minval),log10(yloglab[majoridx][0])));
 	 value <= im->maxval;
 	 value *= yloglab[majoridx][0]){
@@ -2017,7 +2276,7 @@
 {   
     long i;
     int boxH=8, boxV=8;
-	int res;
+    int res=0;
     gdPoint polyPoints[4];	 /* points for filled graph and more*/
 
     /* draw 3d border */
@@ -2031,23 +2290,26 @@
     gdImageLine(gif,1,im->ygif-2,im->xgif-2,im->ygif-2,graph_col[GRC_SHADEB].i);
 
 
-    vertical_grid(gif, im);
+    if (im->draw_x_grid == 1 )
+      vertical_grid(gif, im);
     
-    /* dont draw horizontal grid if there is no min and max val */
+    if (im->draw_y_grid == 1){
 	if(im->logarithmic){
 		res = horizontal_log_grid(gif,im);
 	} else {
 		res = horizontal_grid(gif,im);
 	}
-    if (! res) {
-       char *nodata = "No Data found";
-       gdImageString(gif, LargeFont,
-		     im->xgif/2 
-		     - (strlen(nodata)*LargeFont->w)/2,
-		     (2*im->yorigin-im->ysize) / 2,
-		     (unsigned char *)nodata, graph_col[GRC_FONT].i);
-    }
 
+	/* dont draw horizontal grid if there is no min and max val */
+	if (! res ) {
+	  char *nodata = "No Data found";
+	  gdImageString(gif, LargeFont,
+			im->xgif/2 
+			- (strlen(nodata)*LargeFont->w)/2,
+			(2*im->yorigin-im->ysize) / 2,
+			(unsigned char *)nodata, graph_col[GRC_FONT].i);
+	}
+    }
 
     /* yaxis description */
     gdImageStringUp(gif, SmallFont,
@@ -2065,8 +2327,8 @@
 		    (unsigned char *)im->title, graph_col[GRC_FONT].i);
     
     /* graph labels */
-
-    for(i=0;i<im->gdes_c;i++){
+    if( !(im->extra_flags & NOLEGEND) ) {
+      for(i=0;i<im->gdes_c;i++){
 	if(im->gdes[i].legend[0] =='\0')
 	    continue;
 	
@@ -2098,6 +2360,7 @@
 			  (unsigned char *)im->gdes[i].legend,
 			  graph_col[GRC_FONT].i);
 	}
+      }
     }
     
     
@@ -2160,6 +2423,7 @@
 
 int lazy_check(image_desc_t *im){
     FILE *fd = NULL;
+    int size = 1;
     struct stat  gifstat;
     
     if (im->lazy == 0) return 0; /* no lazy option */
@@ -2174,12 +2438,14 @@
       return 0; /* the file does not exist */
     switch (im->imgformat) {
     case IF_GIF:
-	return GifSize(fd,&(im->xgif),&(im->ygif));
+	size = GifSize(fd,&(im->xgif),&(im->ygif));
+	break;
     case IF_PNG:
-	return PngSize(fd,&(im->xgif),&(im->ygif));
+	size = PngSize(fd,&(im->xgif),&(im->ygif));
+	break;
     }
     fclose(fd);
-    return 1;
+    return size;
 }
 
 /* draw that picture thing ... */
@@ -2215,8 +2481,9 @@
      * if there are no graph elements we stop here ... 
      * if we are lazy, try to quit ... 
      */
-    if(print_calc(im,calcpr)==0 || lazy)
-	return 0;
+    i=print_calc(im,calcpr);
+    if(i<0) return -1;
+    if(i==0 || lazy) return 0;
 
     /* get actual drawing data and find min and max values*/
     if(data_proc(im)==-1)
@@ -2424,10 +2691,14 @@
     }
 
     if (strcmp(im->graphfile,"-")==0) {
-	fo = stdout;
+#ifdef WIN32
+        /* Change translation mode for stdout to BINARY */
+        _setmode( _fileno( stdout ), O_BINARY );
+#endif
+        fo = stdout;
     } else {
 	if ((fo = fopen(im->graphfile,"wb")) == NULL) {
-	    rrd_set_error("cannot open %s for write",im->graphfile);
+	    rrd_set_error("Opening '%s' for write: %s",im->graphfile, strerror(errno));
 	    return (-1);
 	}
     }
@@ -2455,6 +2726,9 @@
 gdes_alloc(image_desc_t *im){
 
     long def_step = (im->end-im->start)/im->xsize;
+    
+    if (im->step > def_step) /* step can be increassed ... no decreassed */
+      def_step = im->step;
 
     im->gdes_c++;
     
@@ -2523,6 +2797,7 @@
     int linepass = 0; /* stack can only follow directly after LINE* AREA or STACK */    
     struct time_value start_tv, end_tv;
     char *parsetime_error = NULL;
+    int stroff;    
 
     (*prdata)=NULL;
 
@@ -2534,17 +2809,21 @@
     im.ygif=0;
     im.xsize = 400;
     im.ysize = 100;
+    im.step = 0;
     im.ylegend[0] = '\0';
     im.title[0] = '\0';
     im.minval = DNAN;
     im.maxval = DNAN;    
     im.interlaced = 0;
+    im.unitsexponent= 9999;
     im.extra_flags= 0;
     im.rigid = 0;
     im.imginfo = NULL;
     im.lazy = 0;
     im.logarithmic = 0;
     im.ygridstep = DNAN;
+    im.draw_x_grid = 1;
+    im.draw_y_grid = 1;
     im.base = 1000;
     im.prt_c = 0;
     im.gdes_c = 0;
@@ -2576,15 +2855,19 @@
 	    {"imginfo",    required_argument, 0,  'f'},
 	    {"imgformat",  required_argument, 0,  'a'},
 	    {"lazy",       no_argument,       0,  'z'},
+	    {"no-legend",  no_argument,       0,  'g'},
 	    {"alt-y-grid", no_argument,       0,   257 },
 	    {"alt-autoscale", no_argument,    0,   258 },
+	    {"alt-autoscale-max", no_argument,    0,   259 },
+	    {"units-exponent",required_argument, 0,  260},
+	    {"step",       required_argument, 0,   261},
 	    {0,0,0,0}};
 	int option_index = 0;
 	int opt;
 
 	
 	opt = getopt_long(argc, argv, 
-			  "s:e:x:y:v:w:h:iu:l:rb:oc:t:f:a:z",
+			  "s:e:x:y:v:w:h:iu:l:rb:oc:t:f:a:z:g",
 			  long_options, &option_index);
 
 	if (opt == EOF)
@@ -2597,6 +2880,18 @@
 	case 258:
 	    im.extra_flags |= ALTAUTOSCALE;
 	    break;
+	case 259:
+	    im.extra_flags |= ALTAUTOSCALE_MAX;
+	    break;
+	case 'g':
+	    im.extra_flags |= NOLEGEND;
+	    break;
+	case 260:
+	    im.unitsexponent = atoi(optarg);
+	    break;
+	case 261:
+	    im.step =  atoi(optarg);
+	    break;
 	case 's':
 	    if ((parsetime_error = parsetime(optarg, &start_tv))) {
 	        rrd_set_error( "start time: %s", parsetime_error );
@@ -2610,8 +2905,13 @@
 	    }
 	    break;
 	case 'x':
+	    if(strcmp(optarg,"none") == 0){
+	      im.draw_x_grid=0;
+	      break;
+	    };
+	        
 	    if(sscanf(optarg,
-		      "%10[A-Z]:%lu:%10[A-Z]:%lu:%10[A-Z]:%lu:%lu:%100s",
+		      "%10[A-Z]:%ld:%10[A-Z]:%ld:%10[A-Z]:%ld:%ld:%n",
 		      scan_gtm,
 		      &im.xlab_user.gridst,
 		      scan_mtm,
@@ -2619,7 +2919,8 @@
 		      scan_ltm,
 		      &im.xlab_user.labst,
 		      &im.xlab_user.precis,
-		      im.xlab_form) == 8){
+		      &stroff) == 7 && stroff != 0){
+                strncpy(im.xlab_form, optarg+stroff, sizeof(im.xlab_form) - 1);
 		if((im.xlab_user.gridtm = tmt_conv(scan_gtm)) == -1){
 		    rrd_set_error("unknown keyword %s",scan_gtm);
 		    return -1;
@@ -2633,11 +2934,17 @@
 		im.xlab_user.minsec = 1;
 		im.xlab_user.stst = im.xlab_form;
 	    } else {
-		rrd_set_error("invalid xgrid format");
+		rrd_set_error("invalid x-grid format");
 		return -1;
 	    }
 	    break;
 	case 'y':
+
+	    if(strcmp(optarg,"none") == 0){
+	      im.draw_y_grid=0;
+	      break;
+	    };
+
 	    if(sscanf(optarg,
 		      "%lf:%d",
 		      &im.ygridstep,
@@ -2650,7 +2957,7 @@
 		    return -1;
 		} 
 	    } else {
-		rrd_set_error("invalid ygrid format");
+		rrd_set_error("invalid y-grid format");
 		return -1;
 	    }
 	    break;
@@ -2922,7 +3229,7 @@
 	    }
 	    if(sscanf(
 		    &argv[i][argstart],
-		    "%29[_A-Za-z0-9]=%[^: ]",
+		    DEF_NAM_FMT "=%[^: ]",
 		    im.gdes[im.gdes_c-1].vname,
 		    rpnex) != 2){
 		im_free(&im);
@@ -2947,9 +3254,9 @@
 	case GF_DEF:
 	    if (sscanf(
 		&argv[i][argstart],
-		"%29[_A-Za-z0-9]=%n",
+		DEF_NAM_FMT "=%n",
 		im.gdes[im.gdes_c-1].vname,
-		&strstart)== 1){
+		&strstart)== 1 && strstart){ /* is the = did not match %n returns 0 */ 
 		if(sscanf(&argv[i][argstart
 				  +strstart
 				  +scan_for_col(&argv[i][argstart+strstart],

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_open.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_open.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_open.c	Sat Jul 13 21:25:54 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  *****************************************************************************
  * rrd_open.c  Open an RRD File
  *****************************************************************************
@@ -35,7 +35,7 @@
     }
     
     if (((*in_file) = fopen(file_name,mode)) == NULL ){
-	rrd_set_error("rrdopen can't open '%s'",file_name);
+	rrd_set_error("opening '%s': %s",file_name, strerror(errno));
 	return (-1);
     }
     
@@ -50,7 +50,7 @@
     
 	/* lets do some test if we are on track ... */
 	if (strncmp(rrd->stat_head->cookie,RRD_COOKIE,4) != 0){
-	    rrd_set_error("not an RRD file");
+	    rrd_set_error("'%s' is not an RRD file",file_name);
 	    free(rrd->stat_head);
 	    return(-1);}
 
@@ -61,7 +61,7 @@
 	    return(-1);}
 
 	if (rrd->stat_head->float_cookie != FLOAT_COOKIE){
-	    rrd_set_error("This RRD created on other architecture");
+	    rrd_set_error("This RRD was created on other architecture");
 	    free(rrd->stat_head);
 	    return(-1);}
 
@@ -108,7 +108,7 @@
     if ((strcmp("-",file_name) == 0)) { input = stdin; }
     else {
       if ((input = fopen(file_name,"rb")) == NULL ){
-	rrd_set_error("readfile can't open '%s'",file_name);
+	rrd_set_error("opening '%s': %s",file_name,strerror(errno));
 	return (-1);
       }
     }

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_cgi.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_cgi.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_cgi.c	Sat Jul 13 21:25:54 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  *****************************************************************************
  * rrd_cgi.c  RRD Web Page Generator
  *****************************************************************************/
@@ -47,6 +47,9 @@
 /* set an evironment variable */
 char* rrdsetenv(long, char **);
 
+/* get an evironment variable */
+char* rrdgetenv(long, char **);
+
 /* include the named file at this point */
 char* includefile(long, char **);
 
@@ -56,6 +59,8 @@
 /** http protocol needs special format, and GMT time **/
 char *http_time(time_t *);
 
+/* return a pointer to newly alocated copy of this string */
+char *stralloc(char *);
 
 static long goodfor=0;
 static char **calcpr=NULL;
@@ -63,9 +68,13 @@
   if (calcpr) {
     long i;
     for(i=0;calcpr[i];i++){
-      free(calcpr[i]);
+      if (calcpr[i]){
+	      free(calcpr[i]);
+      }
     } 
-    free(calcpr);
+    if (calcpr) {
+	    free(calcpr);
+    }
   }
 }
 
@@ -135,25 +144,26 @@
   if(filter==0) {
   /* pass 1 makes only sense in cgi mode */
       for (i=0;buffer[i] != '\0'; i++){    
-	  i +=parse(&buffer,i,"<RRD::CV ",cgiget);
-	  i +=parse(&buffer,i,"<RRD::CV::QUOTE ",cgigetq);
-	  i +=parse(&buffer,i,"<RRD::CV::PATH ",cgigetqp);
+	  i +=parse(&buffer,i,"<RRD::CV",cgiget);
+	  i +=parse(&buffer,i,"<RRD::CV::QUOTE",cgigetq);
+	  i +=parse(&buffer,i,"<RRD::CV::PATH",cgigetqp);
+	  i +=parse(&buffer,i,"<RRD::GETENV",rrdgetenv);	 
       }
   }
 
   /* pass 2 */
   for (i=0;buffer[i] != '\0'; i++){    
-      i +=parse(&buffer,i,"<RRD::GOODFOR ",rrdgoodfor);
-      i += parse(&buffer,i,"<RRD::SETENV ",rrdsetenv);
-      i += parse(&buffer,i,"<RRD::INCLUDE ",includefile);
-      i += parse(&buffer,i,"<RRD::TIME::LAST ",printtimelast);
-      i += parse(&buffer,i,"<RRD::TIME::NOW ",printtimenow);
+      i += parse(&buffer,i,"<RRD::GOODFOR",rrdgoodfor);
+      i += parse(&buffer,i,"<RRD::SETENV",rrdsetenv);
+      i += parse(&buffer,i,"<RRD::INCLUDE",includefile);
+      i += parse(&buffer,i,"<RRD::TIME::LAST",printtimelast);
+      i += parse(&buffer,i,"<RRD::TIME::NOW",printtimenow);
   }
 
   /* pass 3 */
   for (i=0;buffer[i] != '\0'; i++){    
-    i += parse(&buffer,i,"<RRD::GRAPH ",drawgraph);
-    i += parse(&buffer,i,"<RRD::PRINT ",drawprint);
+    i += parse(&buffer,i,"<RRD::GRAPH",drawgraph);
+    i += parse(&buffer,i,"<RRD::PRINT",drawprint);
   }
 
   if (filter==0){
@@ -173,7 +183,9 @@
   }
   printf ("%s", buffer);
   calfree();
-  free(buffer);
+  if (buffer){
+     free(buffer);
+  }
   exit(0);
 }
 
@@ -196,6 +208,13 @@
   return stralloc("");
 }
 
+char* rrdgetenv(long argc, char **args){
+  if (argc != 1) {
+    return stralloc("[ERROR: getenv faild because it did not get 1 argument only]");
+  };
+  return stralloc(getenv(args[0]));
+}
+
 char* rrdgoodfor(long argc, char **args){
   if (argc == 1) {
       goodfor = atol(args[0]);
@@ -215,7 +234,7 @@
   if (argc >= 1) {
       readfile(args[0], &buffer, 0);
       if (rrd_test_error()) {
-	  char *err = malloc((strlen(rrd_get_error())+20)*sizeof(char));
+	  char *err = malloc((strlen(rrd_get_error())+DS_NAM_SIZE)*sizeof(char));
 	  sprintf(err, "[ERROR: %s]",rrd_get_error());
 	  rrd_clear_error();
 	  return err;
@@ -232,13 +251,15 @@
 char* rrdstrip(char *buf){
   char *start;
   if (buf == NULL) return NULL;
+  buf = stralloc(buf); /* make a copy of the buffer */
+  if (buf == NULL) return NULL;
   while ((start = strstr(buf,"<"))){
     *start = '_';
   }
   while ((start = strstr(buf,">"))){
     *start = '_';
   }
-  return stralloc(buf);
+  return buf;
 }
 
 char* cgigetq(long argc, char **args){
@@ -251,7 +272,7 @@
 
     for(c=buf;*c != '\0';c++)
       if (*c == '"') qc++;
-    if((buf2=malloc((strlen(buf) + qc*4 +2) * sizeof(char)))==NULL){
+    if((buf2=malloc((strlen(buf) + qc*4 +4) * sizeof(char)))==NULL){
 	perror("Malloc Buffer");
 	exit(1);
     };
@@ -289,7 +310,7 @@
 
     for(c=buf;*c != '\0';c++)
       if (*c == '"') qc++;
-    if((buf2=malloc((strlen(buf) + qc*4 +2) * sizeof(char)))==NULL){
+    if((buf2=malloc((strlen(buf) + qc*4 +4) * sizeof(char)))==NULL){
 	perror("Malloc Buffer");
 	exit(1);
     };
@@ -350,7 +371,7 @@
     return stralloc(calcpr[0]);
   } else {
     if (rrd_test_error()) {
-      char *err = malloc((strlen(rrd_get_error())+20)*sizeof(char));
+      char *err = malloc((strlen(rrd_get_error())+DS_NAM_SIZE)*sizeof(char));
       sprintf(err, "[ERROR: %s]",rrd_get_error());
       rrd_clear_error();
       calfree();
@@ -381,7 +402,7 @@
     };
     last = rrd_last(argc+1, args-1); 
     if (rrd_test_error()) {
-      char *err = malloc((strlen(rrd_get_error())+20)*sizeof(char));
+      char *err = malloc((strlen(rrd_get_error())+DS_NAM_SIZE)*sizeof(char));
       sprintf(err, "[ERROR: %s]",rrd_get_error());
       rrd_clear_error();
       return err;
@@ -506,6 +527,7 @@
   long argc;
   /* do we like it ? */
   if (strncmp((*buf)+i, tag, strlen(tag))!=0) return 0;      
+  if (! isspace(*( (*buf) + i + strlen(tag) )) ) return 0;
   /* scanargs puts \0 into *buf ... so after scanargs it is probably
      not a good time to use strlen on buf */
   end = scanargs((*buf)+i+strlen(tag),&argc,&args);
@@ -543,7 +565,7 @@
   /* splice the variable */
   memmove ((*buf)+i+valln,end,strlen(end)+1);
   if (val != NULL ) memmove ((*buf)+i,val, valln);
-  free(val);
+  if (val){ free(val);}
   return valln > 0 ? valln-1: valln;
 }
 

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_create.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_create.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_create.c	Sat Jul 13 21:25:54 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  *****************************************************************************
  * rrd_create.c  creates new rrds
  *****************************************************************************/
@@ -105,7 +105,7 @@
     rrd.live_head->last_up = last_up;
 
     for(i=optind+1;i<argc;i++){
-	char minstr[20], maxstr[20];	
+	char minstr[DS_NAM_SIZE], maxstr[DS_NAM_SIZE];	
 	int ii;
 	if (strncmp(argv[i],"DS:",3)==0){
 	    size_t old_size = sizeof(ds_def_t)*(rrd.stat_head->ds_cnt);
@@ -224,7 +224,7 @@
     rrd_value_t       unknown = DNAN ;
 
     if ((rrd_file = fopen(file_name,"wb")) == NULL ) {
-	rrd_set_error("can't create '%s'",file_name);
+	rrd_set_error("creating '%s': %s",file_name,strerror(errno));
 	free(rrd->stat_head);
 	free(rrd->ds_def);
 	free(rrd->rra_def);

Modified: trunk/orca/packages/rrdtool-1.0.33/src/pngsize.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/pngsize.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/pngsize.c	Sat Jul 13 21:25:55 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  *****************************************************************************
  * pngsize.c  determine the size of a PNG image
  *****************************************************************************/

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_tune.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_tune.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_tune.c	Sat Jul 13 21:25:55 2002
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  *****************************************************************************
  * change header parameters of an rrd
  *****************************************************************************
@@ -53,10 +53,12 @@
 	    if ((matches = sscanf(optarg, DS_NAM_FMT ":%ld",ds_nam,&heartbeat)) != 2){
 		rrd_set_error("invalid arguments for heartbeat");
 		rrd_free(&rrd);
+	        fclose(rrd_file);
 		return -1;
 	    }
 	    if ((ds=ds_match(&rrd,ds_nam))==-1){
 		rrd_free(&rrd);
+                fclose(rrd_file);
 		return -1;
 	    }
 	    rrd.ds_def[ds].par[DS_mrhb_cnt].u_cnt = heartbeat;
@@ -66,10 +68,12 @@
 	    if ((matches = sscanf(optarg,DS_NAM_FMT ":%lf",ds_nam,&min)) <1){
 		rrd_set_error("invalid arguments for minimum ds value");
 		rrd_free(&rrd);
+                fclose(rrd_file);
 		return -1;
 	    }
 	    if ((ds=ds_match(&rrd,ds_nam))==-1){
 		rrd_free(&rrd);
+                fclose(rrd_file);
 		return -1;
 	    }
 
@@ -82,10 +86,12 @@
 	    if ((matches = sscanf(optarg, DS_NAM_FMT ":%lf",ds_nam,&max)) <1){
 		rrd_set_error("invalid arguments for maximum ds value");
 		rrd_free(&rrd);
+	        fclose(rrd_file);
 		return -1;
 	    }
 	    if ((ds=ds_match(&rrd,ds_nam))==-1){
 		rrd_free(&rrd);
+	        fclose(rrd_file);
 		return -1;
 	    }
 	    if(matches == 1) 
@@ -97,14 +103,17 @@
 	    if ((matches = sscanf(optarg, DS_NAM_FMT ":" DST_FMT ,ds_nam,dst)) != 2){
 		rrd_set_error("invalid arguments for data source type");
 		rrd_free(&rrd);
+	        fclose(rrd_file);
 		return -1;
 	    }
 	    if ((ds=ds_match(&rrd,ds_nam))==-1){
 		rrd_free(&rrd);
+	        fclose(rrd_file);
 		return -1;
 	    }
 	    if (dst_conv(dst) == -1){
 		rrd_free(&rrd);
+	        fclose(rrd_file);
 		return -1;
 	    }
 	    strncpy(rrd.ds_def[ds].dst,dst,DST_SIZE-1);
@@ -122,10 +131,12 @@
 		 sscanf(optarg,DS_NAM_FMT ":" DS_NAM_FMT , ds_nam,ds_new)) != 2){
 		rrd_set_error("invalid arguments for data source type");
 		rrd_free(&rrd);
+	        fclose(rrd_file);
 		return -1;
 	    }
 	    if ((ds=ds_match(&rrd,ds_nam))==-1){
 		rrd_free(&rrd);
+	        fclose(rrd_file);
 		return -1;
 	    }
 	    strncpy(rrd.ds_def[ds].ds_nam,ds_new,DS_NAM_SIZE-1);
@@ -137,6 +148,7 @@
             else
                 rrd_set_error("unknown option '%s'",argv[optind-1]);
 	    rrd_free(&rrd);	    
+            fclose(rrd_file);
             return -1;
         }
     }

Modified: trunk/orca/packages/rrdtool-1.0.33/src/Makefile.am
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/Makefile.am	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/Makefile.am	Sat Jul 13 21:25:55 2002
@@ -26,6 +26,7 @@
 	rrd_create.c	\
 	rrd_diff.c	\
 	rrd_dump.c	\
+	rrd_info.c	\
 	rrd_error.c	\
 	rrd_fetch.c	\
 	rrd_format.c	\
@@ -36,7 +37,7 @@
 	rrd_restore.c	\
 	rrd_tune.c	\
 	rrd_update.c	\
-	getopt.h      ntconfig.h    parsetime.h   rrd_format.h  rrd_tool.h
+	getopt.h ntconfig.h parsetime.h rrd_format.h rrd_tool.h rrd.h
 
 # Build two libraries.  One is a public one that gets installed in
 # $prefix/lib.  Libtool does not create an archive of the PIC compiled
@@ -58,14 +59,28 @@
 librrd_private_la_SOURCES = $(RRD_C_FILES)
 
 librrd_la_LIBADD          = $(RRD_LIBS)
-librrd_private_la_LIBADD  = $(RRD_LIBS)
 librrd_la_LDFLAGS         = -version-info 0:0:0
 
-bin_PROGRAMS	= rrdcgi rrdtool
+include_HEADERS	= rrd.h
+
+librrd_private_la_LIBADD  = $(RRD_LIBS)
+librrd_private_la_LDFLAGS = -static
+
+bin_PROGRAMS	= rrdcgi rrdtool rrdupdate
 
 rrdcgi_SOURCES	= rrd_cgi.c
 rrdcgi_LDADD	= librrd.la
 
+rrdupdate_SOURCES = 
+rrdupdate_LDADD	= rrdupdate.o librrd.la
+
+
+rrdupdate.c: rrd_update.c
+	-ln -s rrd_update.c rrdupdate.c
+
+rrdupdate.o: rrdupdate.c
+	$(COMPILE) -DSTANDALONE -c rrdupdate.c
+
 rrdtool_SOURCES	= rrd_tool.c
 rrdtool_LDADD	= librrd.la
 

Modified: trunk/orca/packages/rrdtool-1.0.33/src/parsetime.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/parsetime.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/parsetime.c	Sat Jul 13 21:25:55 2002
@@ -630,8 +630,8 @@
 static char *
 assign_date(struct time_value *ptv, long mday, long mon, long year)
 {
-    if (year > 99) {
-	if (year > 1899)
+    if (year > 138) {
+	if (year > 1970)
 	    year -= 1900;
 	else {
 	    panic(e("invalid year %d (should be either 00-99 or >1900)",
@@ -641,9 +641,6 @@
 	year += 100;	     /* Allow year 2000-2037 to be specified as   */
     }			     /* 00-37 until the problem of 2038 year will */
 			     /* arise for unices with 32-bit time_t :)    */
-    if (year < 0) {
-      panic(e("don't know what's the use of the year %d (negative!)?", year));
-    }
     if (year < 70) {
       panic(e("won't handle dates before epoch (01/01/1970), sorry"));
     }
@@ -838,11 +835,11 @@
     /* Only absolute time specifications below */
     case NUMBER:
 	    try(tod(ptv))
-	    if (sc_tokid != NUMBER) break;
+	    if (sc_tokid != NUMBER) break; 
     /* fix month parsing */
     case JAN: case FEB: case MAR: case APR: case MAY: case JUN:
     case JUL: case AUG: case SEP: case OCT: case NOV: case DEC:
-    	    try(day(ptv));
+            try(day(ptv));
 	    if (sc_tokid != NUMBER) break;
 	    try(tod(ptv))
 	    break;
@@ -861,14 +858,15 @@
 	    hr += 12;
 	    /* FALLTHRU */
     case MIDNIGHT:
-	    if (ptv->tm.tm_hour >= hr) {
+            /* if (ptv->tm.tm_hour >= hr) {
 		ptv->tm.tm_mday++;
 		ptv->tm.tm_wday++;
-	    }
+	    } */ /* shifting does not makes sense here ... noon is noon */ 
 	    ptv->tm.tm_hour = hr;
 	    ptv->tm.tm_min = 0;
 	    ptv->tm.tm_sec = 0;
 	    token();
+	    try(day(ptv));
 	    break;
     default:
     	    panic(e("unparsable time: %s%s",sc_token,sct));

Modified: trunk/orca/packages/rrdtool-1.0.33/src/rrd_restore.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/src/rrd_restore.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/src/rrd_restore.c	Sat Jul 13 21:25:55 2002
@@ -1,11 +1,20 @@
 /*****************************************************************************
- * RRDtool 1.0.13  Copyright Tobias Oetiker, 1997, 1998, 1999, 2000
+ * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
  *****************************************************************************
  * rrd_restore.c  creates new rrd from data dumped by rrd_dump.c
  *****************************************************************************/
 
 #include "rrd_tool.h"
 
+/* Prototypes */
+
+void xml_lc(char*);
+int skip(char **);
+int eat_tag(char **, char *);
+int read_tag(char **, char *, char *, void *);
+int xml2rrd(char*, rrd_t*, char);
+int rrd_write(char *, rrd_t *);
+
 /* convert all ocurances of <BlaBlaBla> to <blablabla> */
 
 void xml_lc(char* buf){
@@ -156,7 +165,6 @@
   
   ptr2 = ptr;
   while (eat_tag(&ptr2,"rra") == 1){
-      long i;
       rrd->stat_head->rra_cnt++;
 
       /* alocate and reset rra definition areas */
@@ -179,6 +187,10 @@
       if(cf_conv(rrd->rra_def[rrd->stat_head->rra_cnt-1].cf_nam) == -1) return -1;
 
       read_tag(&ptr2,"pdp_per_row","%lu",&(rrd->rra_def[rrd->stat_head->rra_cnt-1].pdp_cnt));
+      read_tag(&ptr2,"xff","%lf",&(rrd->rra_def[rrd->stat_head->rra_cnt-1].par[RRA_cdp_xff_val].u_val));
+      if(rrd->rra_def[rrd->stat_head->rra_cnt-1].par[RRA_cdp_xff_val].u_val > 1 ||
+         rrd->rra_def[rrd->stat_head->rra_cnt-1].par[RRA_cdp_xff_val].u_val < 0)
+          return -1;
       
       eat_tag(&ptr2,"cdp_prep");
       for(i=0;i<rrd->stat_head->ds_cnt;i++){
@@ -268,7 +280,7 @@
       *rrd_file= *stdout;
     } else {
       if ((rrd_file = fopen(file_name,"wb")) == NULL ) {
-	rrd_set_error("can't create '%s'",file_name);
+	rrd_set_error("creating '%s': %s",file_name,strerror(errno));
 	rrd_free(rrd);
 	return(-1);
       }

Modified: trunk/orca/packages/rrdtool-1.0.33/cgilib-0.4/Makefile.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/cgilib-0.4/Makefile.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/cgilib-0.4/Makefile.in	Sat Jul 13 21:25:56 2002
@@ -10,12 +10,6 @@
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
-#AUTOMAKE_OPTIONS        = foreign
-
-# our local rules for autoconf (automake and libtool)
-#ACLOCAL_M4 = $(top_srcdir)/config/aclocal.m4
-#AUTOHEADER = @AUTOHEADER@ --localdir=config
-
 
 SHELL = @SHELL@
 
@@ -70,15 +64,26 @@
 target_alias = @target_alias@
 target_triplet = @target@
 CC = @CC@
-CFLAGS = @CFLAGS@
 CGI_LIB_DIR = @CGI_LIB_DIR@
 COMP_PERL = @COMP_PERL@
 CPP = @CPP@
 GD_LIB_DIR = @GD_LIB_DIR@
 LIBTOOL = @LIBTOOL@
+NROFF = @NROFF@
 PERL = @PERL@
+PERLFLAGS = @PERLFLAGS@
+PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PNG_LIB_DIR = @PNG_LIB_DIR@
 RANLIB = @RANLIB@
+SO_EXT = @SO_EXT@
+TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
+TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
+TCL_PREFIX = @TCL_PREFIX@
+TCL_SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@
+TCL_SHLIB_LD = @TCL_SHLIB_LD@
+TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+TROFF = @TROFF@
+VERSION = @VERSION@
 ZLIB_LIB_DIR = @ZLIB_LIB_DIR@
 
 noinst_LTLIBRARIES = librrd_cgi.la
@@ -99,6 +104,7 @@
 librrd_cgi_la_LDFLAGS = 
 librrd_cgi_la_LIBADD = 
 librrd_cgi_la_OBJECTS =  cgi.lo
+CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
@@ -107,7 +113,6 @@
 
 
 PACKAGE = @PACKAGE@
-VERSION = @VERSION@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
@@ -214,7 +219,7 @@
 	@for file in $(DISTFILES); do \
 	  d=$(srcdir); \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$/$$file $(distdir)/$$file; \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
 	    test -f $(distdir)/$$file \
 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \

Modified: trunk/orca/packages/rrdtool-1.0.33/cgilib-0.4/Makefile.am
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/cgilib-0.4/Makefile.am	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/cgilib-0.4/Makefile.am	Sat Jul 13 21:25:56 2002
@@ -1,11 +1,3 @@
-## Process this file with automake to produce Makefile.in
-
-#AUTOMAKE_OPTIONS        = foreign
-
-# our local rules for autoconf (automake and libtool)
-#ACLOCAL_M4 = $(top_srcdir)/config/aclocal.m4
-#AUTOHEADER = @AUTOHEADER@ --localdir=config
-
 noinst_LTLIBRARIES    = librrd_cgi.la
 
 librrd_cgi_la_SOURCES = cgi.c cgi.h

Modified: trunk/orca/packages/rrdtool-1.0.33/README
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/README	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/README	Sat Jul 13 21:25:56 2002
@@ -18,29 +18,48 @@
   make             <------ GNU make
   make install     <------ GNU make
 
-This will configure, compile and install RRDtool in /usr/local/rrdtool-VERSION.
-If you prefer to install RRDtool in some other place, use 
+This will configure, compile and install RRDtool in
+/usr/local/rrdtool-VERSION. If you prefer to install RRDtool in some other
+place, use
 
   sh configure --prefix=/some/other/RRDtool-dir
 
-If you prefer to live with shared libraries, make sure you add the --enable-shared
-option to your configure call.
+If you prefer to live with shared libraries, make sure you add the
+--enable-shared option to your configure call.
 
   sh configure --enable-shared
 
-The configure script will try to find your perl installation (5.004 preferred).
-If it does not find it, you can still build RRDtool but no perl modules will be
-generated.
-
-By default the perl modules will be installed under the RRDtool install directory.
-This will require you to use a 'use lib' statement in your RRDtool perl programs.
-If you do not care what happens to your site-perl directory, you can also use
+The configure script will try to find your perl installation (5.004
+preferred). If it does not find it, you can still build RRDtool but no perl
+modules will be generated.
+
+By default the perl modules will be installed under the RRDtool install
+directory. This will require you to use a 'use lib' statement in your
+RRDtool perl programs. If you do not care what happens to your site-perl
+directory, you can also use
 
   make site-perl-install
 
 will install the perl modules whereever you keep your local perl modules.
 Doing this reliefs you from using 'use lib' in your scripts.
 
+Configure will also look for an TCL installation on your system. If it finds
+one it will build a TCL interface for rrdtool. If you keep tcl in a non
+standard location you can use
+
+  sh configure --with-tcllib=/sw/tcl-8.3/lib
+
+to indicte the right version (note, this must point to the directory where
+tclConfig.sh is located). Note that install will integrate the tcl bindings
+into your tcl installation. It will use a separate directory for each
+version though, so this is not much of a problem. Never the less the TCL
+module will not get intalled by default as TCL wants its module in the base
+tcl installation where you might not be able to write to. So if you want the
+tcl stuff installed, type
+
+  make site-tcl-install
+
+
 Getting Started:
 ----------------
 

Modified: trunk/orca/packages/rrdtool-1.0.33/CONTRIBUTORS
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/CONTRIBUTORS	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/CONTRIBUTORS	Sat Jul 13 21:25:56 2002
@@ -11,33 +11,50 @@
 
 	Andreas Kroomaa <andre at ml.ee>
 	Andrew Turner <turner at mint.net> (LAST consolidator)
+	Bernard Fischer <bfischer at syslog.ch> 64bit stuff and --alt-autoscale-max
 	Bill Fenner <fenner at research.att.com>
 	Blair Zajac <bzajac at geostaff.com>
 	Dan Dunn <dandunn at computer.org>
 	Hermann Hueni <hueni at glue.ch> (SunOS porting)
 	Jeff R. Allen <jeff.allen at acm.org> (autoconfigure, portability)  
+	Joel Becker <jlbec at raleigh.ibm.com> AIX
+	Joey Miller <joeym at inficad.com>	php3 and php4 bindings
 	Jost.Krieger <Jost.Krieger at ruhr-uni-bochum.de>
 	Larry Leszczynski <larryl at furph.com>
 	Otmar Lendl <O.Lendl at Austria.EU.net> (lots of bugfixes)
 	Paul Joslin <Paul.Joslin at sdrc.com>
 	Philippe.Simonet <Philippe.Simonet at swisscom.com> (NT porting)
+	Poul-Henning Kamp <phk at freebsd.org> CDEF enhancements
+	REIBENSCHUH Alfred <alfred.reibenschuh at it-austria.com> AIX
+        Roman Hoogant <rhoogant at ee.ethz.ch>
 	Russ Wright <rwwright at home.com>
 	Simon Leinen <simon at switch.ch>
+	Stefan Mueller <s.mueller at computer.org> HPUX 11
+	Steve Rader <rader at teak.wiscnet.net> (rrd_cgi debugging and LAST)
+        Terminator rAT <karl_schilke at eli.net>
+        Christophe VG <Christophe.VanGinneken at ubizen.com>
+        Shane O'Donnell <shaneo at opennms.org>
+        Tuc <ttsg at ttsg.com>
+        Mike Mitchell <mcm at unx.sas.com>
+	Ulrich Schilling <schilling at netz.uni-essen.de> AIX
 	Wrolf Courtney <wrolf at wrolf.net> (HP-UX)
         Alan Lichty <alan_lichty at eli.net>
         Alex van den Bogaerdt <alex at ergens.op.het.net> (rrd_resize.c and more)
+        Frank Strauss <strauss at escape.de> TCL bindings
+        Jakob Ilves <jilves at se.oracle.com> HPUX 11
         Jeremy Fischer <jeremy at pobox.com> (Makefile changes & RPM builds)
         Oleg Cherevko <olwi at icyb.kiev.ua>
+        Rainer Bawidamann <Rainer.Bawidamann at informatik.uni-ulm.de>
+        Selena M Brewington <smbrewin at ichips.intel.com> add_ds
         Steen Linden <Steen.Linden at ebone.net>
-        Tom Crawley <Tom.Crawley at hi.riotinto.com.au> (GCC&HP configuration)
-	Steve Rader <rader at teak.wiscnet.net> (rrd_cgi debugging and LAST)
         Steve Harris <steveh at wesley.com.au> AIX portability
-	Stefan Mueller <s.mueller at computer.org> HPUX 11
-	Ulrich Schilling <schilling at netz.uni-essen.de> AIX
-	Joel Becker <jlbec at raleigh.ibm.com> AIX
-	REIBENSCHUH Alfred <alfred.reibenschuh at it-austria.com> AIX
-        Selena M Brewington <smbrewin at ichips.intel.com> add_ds
-	Larry Leszczynski <larryl at furph.com>
+        Tom Crawley <Tom.Crawley at hi.riotinto.com.au> (GCC&HP configuration)
+	Albert Chin-A-Young <china at thewrittenword.com>
+	Sean McCreary mccreary at xoanon.colorado.edu
+	Bruce Campbell <bruce.campbell at apnic.net>
+	Sean Summers <sean at Fenstermaker.com> (RPM .spec)
+	Christophe Van Ginneken <Christophe.VanGinneken at ubizen.com> (--no-legend)
+
 
 Documentation
 
@@ -51,13 +68,20 @@
 	Tobias Weingartner <weingart at cs.ualberta.ca>
 	hendrik visage <hvisage at is.co.za>
 	Steve Rader <rader at teak.wiscnet.net>
+        Jesús Couto Fandiño
 
 Packaging
         Henri GOMEZ -- Redhat RPMs
         Philippe Simonet -- NT Binaries
 
+
 Internet Resources
-        LAN Services AG (www.lan.ch) for the http://rrdtool.eu.org domain reflector
+        LAN Services AG (www.lan.ch) 
+           for the http://rrdtool.eu.org domain reflector
+
+        Alexander Lucke (lucke at dns-net.de) 
+           and DNS:NET Internet Services (www.dns-net.de)
+              for http://rrdtool.org
 
 Further I would like to note, that rrdtool would not exist without
 the following free software products:

Modified: trunk/orca/packages/rrdtool-1.0.33/zlib-1.1.3/Makefile.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/zlib-1.1.3/Makefile.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/zlib-1.1.3/Makefile.in	Sat Jul 13 21:25:56 2002
@@ -70,15 +70,26 @@
 target_alias = @target_alias@
 target_triplet = @target@
 CC = @CC@
-CFLAGS = @CFLAGS@
 CGI_LIB_DIR = @CGI_LIB_DIR@
 COMP_PERL = @COMP_PERL@
 CPP = @CPP@
 GD_LIB_DIR = @GD_LIB_DIR@
 LIBTOOL = @LIBTOOL@
+NROFF = @NROFF@
 PERL = @PERL@
+PERLFLAGS = @PERLFLAGS@
+PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PNG_LIB_DIR = @PNG_LIB_DIR@
 RANLIB = @RANLIB@
+SO_EXT = @SO_EXT@
+TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
+TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
+TCL_PREFIX = @TCL_PREFIX@
+TCL_SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@
+TCL_SHLIB_LD = @TCL_SHLIB_LD@
+TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+TROFF = @TROFF@
+VERSION = @VERSION@
 ZLIB_LIB_DIR = @ZLIB_LIB_DIR@
 
 EXTRA_DIST = ChangeLog FAQ INDEX README README.rrdtool algorithm.txt zlib.dsp zlib.dsw zlib.3 
@@ -102,6 +113,7 @@
 librrd_z_la_OBJECTS =  adler32.lo compress.lo crc32.lo deflate.lo \
 gzio.lo infblock.lo infcodes.lo inffast.lo inflate.lo inftrees.lo \
 infutil.lo trees.lo uncompr.lo zutil.lo
+CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
@@ -110,7 +122,6 @@
 
 
 PACKAGE = @PACKAGE@
-VERSION = @VERSION@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
@@ -217,7 +228,7 @@
 	@for file in $(DISTFILES); do \
 	  d=$(srcdir); \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$/$$file $(distdir)/$$file; \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
 	    test -f $(distdir)/$$file \
 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdview/rrdview.cgi
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/rrdview/rrdview.cgi	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/rrdview/rrdview.cgi	Sat Jul 13 21:25:57 2002
@@ -0,0 +1,412 @@
+#!/usr/bin/perl -T -w
+
+use CGI::Carp qw(fatalsToBrowser carpout);
+use Time::Local;
+use File::Basename;
+use FileHandle;
+use POSIX;
+use RRDs;
+
+BEGIN {
+	carpout(\*STDOUT);
+};
+
+use strict;
+
+use vars qw($VERSION);
+my $rcs = ' $Id: rrdview.cgi,v 1.16 2000/09/22 23:20:40 gilles Exp $ ' ;
+$rcs =~ m/,v (\d+\.\d+)/;
+$VERSION = ($1) ? $1 : "UNKNOWN";
+
+my $mod_perl = (exists $ENV{MOD_PERL}) ? 1 : 0;
+my $self  = basename($0);
+my $imgErr; # global is good in that huge case.
+
+doit();
+
+sub doit {
+	
+	my $debug = 0;
+	my $cgi   = myCGI->new();
+	my $q     = $cgi->r();
+	my $now   = time();
+	
+	my $strftime = '%A %d %B %Y %H:%M:%S %Z';
+	
+	my ($minD,$hourD,$mdayD,$monD,$yearD) = (myLocaltime($now));
+	$cgi->paramDefault(
+			   'minE'  => $minD,
+			   'hourE' => $hourD,
+			   'mdayE' => $mdayD,
+			   'monE'  => $monD,
+			   'yearE' => $yearD,
+			  );
+	
+	($minD,$hourD,$mdayD,$monD,$yearD) = (myLocaltime($now - 86400));
+	
+	$cgi->paramDefault(
+			   'minS'  => $minD,
+			   'hourS' => $hourD,
+			   'mdayS' => $mdayD,
+			   'monS'  => $monD,
+			   'yearS' => $yearD,
+			  );
+	
+	
+	my ($minS,$hourS,$mdayS,$monS,$yearS) = 
+	  (
+	   $q->param(-Name => 'minS'),
+	   $q->param('hourS'),
+	   $q->param('mdayS'),
+	   $q->param('monS'),
+	   $q->param('yearS'),
+	  );
+	
+	my ($minE,$hourE,$mdayE,$monE,$yearE) = 
+	  (
+	   $q->param('minE'),
+	   $q->param('hourE'),
+	   $q->param('mdayE'),
+	   $q->param('monE'),
+	   $q->param('yearE'),
+	  );
+	
+	my $start = myTimelocal($minS,$hourS,$mdayS,$monS,$yearS);
+	my $end   = myTimelocal($minE,$hourE,$mdayE,$monE,$yearE);
+	
+	my $startString = strftime($strftime, localtime($start));
+	my $endString   = strftime($strftime, localtime($end));
+	
+	$q->param('start', $start);
+	$q->param('end', $end);
+	
+	$cgi->paramDefault(
+			   'hight'   => 150,
+			   'width'   => 600,
+			   'rrdfile' => 'foo.rrd',
+			  );
+	
+	my $width = $q->param(-Name=>'width');
+	my $hight = $q->param(-Name=>'hight');
+	my $owner = $q->param(-Name=>'owner') || "No Owner";
+	my $title = $q->param(-Name=>'title') || "No Title";
+	
+	my $rrdfile = $q->param("rrdfile");
+	
+	$debug and $cgi->saveparam("/tmp/rrdmon.out");
+	my $error = "";
+	my $rrdinfo;
+	my @dsname;
+	unless (-f $rrdfile) {
+		$error = "<big>File '$rrdfile' does not exist!</big><BR>\n";
+	}else{
+		$rrdinfo = RRDs::info $rrdfile;
+		if (my $ERR=RRDs::error) {
+			$error = "<big>" . $ERR . "</big><BR>\n";
+			@dsname = ('RRD ERROR');
+		}else{
+			foreach my $key (keys %$rrdinfo) {
+				if ($key =~ m/ds\[(\w+)\]\.value/) {
+					push(@dsname, $1);
+				}
+			}
+		}
+	};
+	
+	my $dsname  = $q->param("dsname") || $dsname[0] || "unknown";
+	
+	if (defined $q->param(-Name=>'child')) {
+		# cgi child
+		imagepage($q, 
+			  $cgi, 
+			  $debug, 
+			  $rrdfile, 
+			  $dsname,
+			  $owner,
+			  $hight,
+			  $width,
+			  $start,
+			  $end,
+			  $title,
+			 );
+	}else{
+		# cgi parent
+		mainpage($q, 
+			 $cgi, 
+			 $debug, 
+		 $dsname, 
+		 \@dsname, 
+		 $hight, 
+		 $width, 
+		 $error,
+		 $startString,
+		 $endString,
+		);
+	}
+}
+
+sub mainpage {
+	
+	my $q = shift;
+	my $cgi = shift;
+	my $debug = shift;
+	my $dsname = shift;
+	my $ldsname = shift;
+	my $hight = shift;
+	my $width =  shift;
+	my $error = shift;
+	my $startString = shift;
+	my $endString = shift;
+
+	my $queryChild = "child=yes&".$q->query_string();
+	my $cgiChild = myCGI->new($queryChild);
+	# CGI fork ! 
+	print 
+	  $q->header(),
+	  #$q->start_html($q->param('owner'). " " . $q->param('title') ),
+	  $q->start_html(
+			 -Title=>"RRDVIEW $VERSION",
+			 -Author=>'lamiral at mail.dotcom.fr',
+			 -Meta=>{'keywords'=>'monitoring rrdtool rrdmon rrdview',
+				 'copyright'=>'Copyleft GPL'},
+			 -BGCOLOR=>'lightblue',
+			),
+	    ($debug) ?                   "<tt>\n" : "",
+	    ($debug and $mod_perl) ?     "mod_perl PID $$<BR>\n" : "",
+	    ($debug and not $mod_perl) ? "PID=$$<BR>\n" : "",
+	    ($debug) ?                   "$cgi<BR>\n" : "",
+	    ($debug) ?                   "$q<BR>\n" : "",
+	    ($debug) ?                   "img=".\$imgErr."<BR>\n" : "",
+	    ($debug) ?                   "</tt>\n" : "",
+	    $q->startform(-Method=>'GET',
+			  #-Enctype=>'multipart/form-data',
+			 ),
+	    $q->textfield(-Name=>'rrdfile', 
+			-Default=>'Give me a file like foo.rrd',
+			-Size=>76),
+	  $q->br(),"\n",
+	  $q->popup_menu(-Name=>'dsname',
+			 -Values=>[@$ldsname],
+			 -Default=>$dsname,
+		    ),
+	  $q->textfield(-Name=>'hight', -Size=>length($hight)), "x",
+	  $q->textfield(-Name=>'width', -Size=>length($width)), " ",
+	  $q->br(),"\n",
+	  $q->image_button(-Name=>'Beautiful Image!',
+			   -Src=>"$self?$queryChild",
+			  ),
+	  $q->br(),"\n",
+	  $error,
+	  $q->tt(" From "),
+	  $q->textfield(-Name=>'yearS', -Size=>4),
+	  $q->textfield(-Name=>'monS',  -Size=>2),
+	  $q->textfield(-Name=>'mdayS', -Size=>2),
+	  " ",
+	  $q->textfield(-Name=>'hourS', -Size=>2),
+	  $q->textfield(-Name=>'minS',  -Size=>2),
+	  " $startString",
+	  $q->br(),"\n",
+	  $q->tt(" To", "&nbsp;" x 2),
+	  $q->textfield(-Name=>'yearE', -Size=>4),
+	  $q->textfield(-Name=>'monE',  -Size=>2),
+	  $q->textfield(-Name=>'mdayE', -Size=>2),
+	  " ",
+	  $q->textfield(-Name=>'hourE', -Size=>2),
+	  $q->textfield(-Name=>'minE',  -Size=>2),
+	  " $endString",
+	  $q->br(),"\n",
+	  $cgi->paramHidden(
+			    'title',
+			    'owner',
+			   ),
+  	    $q->endform(),
+	    ($debug) ? $q->dump(): "",
+	    $q->end_html(),
+	    "\n",
+	    ;
+}
+
+
+sub imagepage {
+
+	my $q = shift;
+	my $cgi = shift;
+	my $debug = shift;
+	my $rrdfile = shift;
+	my $dsname = shift;
+	my $owner  = shift;
+	my $hight = shift;
+	my $width = shift;
+	my $start = shift;
+	my $end = shift;
+	my $title = shift;
+	    
+	$debug and $cgi->saveparam("/tmp/png.out");
+	
+	my $output;
+	RRDs::last($rrdfile);
+	
+	print $q->header(
+			 -Type=>'image/png',
+			 -Expires=>'now'
+			);
+	
+	if($mod_perl) {
+                #carp("we're running under mod_perl");
+		$output = "/tmp/rrdmon.img.$$.png";
+		
+	}
+	else {
+                #we're NOT running under mod_perl
+		$output = "-";
+		
+	}
+
+	RRDs::graph($output,"--title", "$owner",
+		    "--imgformat", "PNG",
+		    "--height","$hight", "--width","$width",
+		    "--start",$start,"--end",$end,
+		    "DEF:value=$rrdfile:$dsname:AVERAGE",
+		    "AREA:value#00FF00:$title",
+		   );
+	
+	
+	if (my $ERROR = RRDs::error()) {
+		carp "ERROR: $ERROR\n";
+		my $rimgErr = loadImageErrorFromVar();
+		print $$rimgErr;
+		return();
+	}
+	if($mod_perl) {
+		my $fh = FileHandle->new($output, "r");
+		unless (defined($fh)){
+			carp("Could not open ",$output,"$!");
+			return undef;
+		}
+		local $/ = undef;
+		my $file = <$fh>;
+		$fh->close();
+		print $file;
+	}
+}
+
+
+sub myLocaltime {
+	my $time = shift;
+
+	my ($min,$hour,$mday,$mon,$year) 
+	  = (localtime($time))[1,2,3,4,5];
+
+	$min  = sprintf("%02s", $min);
+	$hour = sprintf("%02s", $hour);
+	$mday = sprintf("% 2s", $mday);
+	$mon  = sprintf("% 2s", $mon + 1);
+	
+	return($min,$hour,$mday,$mon,$year + 1900);	
+}
+
+sub myTimelocal {
+	my ($min,$hours,$mday,$mon,$year) = @_;
+	
+	my $time = timelocal(0,$min,$hours,$mday,
+			     $mon - 1,$year - 1900);
+	return($time);
+}
+
+sub loadImageErrorFromVar {
+	unless (defined ($main::imgErr)){
+		$main::imgErr = pack "h*", '9805e474d0a0a1a0000000d09484442500000069000000b480000000100cdc1195000000407614d4140010680a138e69f5000080769444144587adde959607357d51e37fdb7291b42b469cb0e51f283c26028d4ce2484034020129430947b0d24c01a30482e4a30c47b480cc00d2d47adcc47843186a094999423818201a10a9408c0d670360a50c18016316b3605cb8c6958d2b4a7fee7df1290b63bcb45818c8fef1947ed5d9bfd937fbb769bf818246801c204819525793f2746a31d92001110e2070a618aa8300032040c2f590000dbc54000d600b06c22b44ca728f88a7c3f2cbc6168a019d9d08910000ee9f02cbf08a1a381ba164f880211ead6a43a63aad41bb5f6df73074502c8d6db0b3a7866400af76c7844999afc9968ea68ecb6810a74481e1b65022af90888e8debf8e2e7abb57fd7a64d8e88e93776d2bd110b830bdb3ae4602edbb24c18fa08ad9e3d662024c322b4d5852152784fa4b901595259e1dca25483ac40f8f7addbb10fb9473d4aaaea475e5d31119444515711654de759be1c5bebe321380e54f3a2f37e92222eb7c37e9d73870de8f320005cad67eadf871f15c8c1a781dadabd237da20006ba4f1bc2b1006ad520e68e08fcea34f8a979b2db63a76690444467b219e378821ebd44ab61a262ad95c12eb7651752e972232aae9a44f0c68c91b46addeb7eaf2a8ede6f49e776e4f6665f0fc7443f015f78e25e70742a6ab4c7261bc7be7873ec0c96dbe7efaa56d4a6f659d4cfada9cefcb74b72cc8d971b5c5c93a7d3a95f72e6d771888826757decebfc0a26caf0ef69014efa9ff5f1379bd527f1c16c246f1d052faee9d3b7e428888b39fa3d5a728dfade7e8fbd4d50662227f9b7bf02cb9fe9c6b566e4c5aa404150418981736182e53af64c7ed25e008fadce2823ec93c1543af88be7a3ad904d8eccf24cfaf6d00fa6ba9a2f6d77faea2fc179f423753d100007524117008d191e404e2a5304d4c9ef3806fdbdcf47979f5d46d9a981768905ea015be025111115bbdf12644443ba068759bff5f5e3a44cbde7e3724c1617941c632750008f1b73414b7397445f9f57ed5f4eacd959a00082199f1ff7e9d65ce1f7b7ec6f73436ecd63d530efae75d5052a7abefbfc8b3a6abc8f9993a6ab2d4f712a6ab4596e7ab42f5ce8a73f7179e1850db55d24a45709eab2f2f5233f8d4e4397e7fa185a852847d7cbff75352f2e4d205fe31462d930b00d5f80a433af8e03d403fb235b76bfc465a0acbda91b70bfeccf02c5c62d177abddeee358f1fb224c34282c353c78d0bcf39e59957fe15758628fe442c34b990f3e75ebae79622968311193555b3dadcebef5cd5397073dacb13b7988486c39797ea988804c88f9eda7648f3d86f385c2827da5d07adb9f2dd397b!
f8f7cc653dcec292e6d786479d37e40f7b5d989df8ab00cb7fe1eaec1dd4953b1c2d99f57dd38a405d31d69c74cbfb9f2fc5df53000bc0e71d87d0c18ddab23b99d8f1208973fe47ac4c31189cb7dd44e14abc934678f4055aafe97e9eb41b56c108c3ee76c1cf9f728303febb9b3fb3282febf3e2f8fe9987bc3892cb8c3e18247e246444cda36811b2da0b111d923cb11311a8931c7e4377db5c14444a0cb5bcad8560111949d74412238ca019257faae24a0a04037287bdb93a686e5ed29a322e4ed5afa88134444c6deec55de6f57363e98a95d3d34802afcf0ed74741c4df375d5ef06c76991d0aa30e1be7a81db7b607825253533fb000b97e5861ade67228be24583004bd68a60fa39d32a7565af6e4dfebd7d0d954a5f5aef2edbe89bd5fc71a72aaa52a793d4e7af464fa6396983170aec910d57fe5d1d779a98300bee0d09ee4e2e8b975097a3677b97b8f995c33e7fdc77dd62a836663e0c97e77d17b4b7f72c5fbceee117b04a822bce4ea3dcde78c26656e9cb0de131906926f6d63b89babea1cad4dae454693ff5f70557bb16133429273adc8110657cbfbaa15538c46a4fcc173831d46885ead4de7835aad1c0b8d2d957d0b45959ce85a569426f5e696bfe34d625bdbd1cab6acb83a729bf87db424fb2a22620361eab1fe4a572ccccafcf8a3afb30a21744e8b5251c407c7a5bdfc505036c2c2b6cf86d90f0fef35b5a054260292d2f3e28663758488efe030c800619065c4e7ae99dc1f2011194326571aff934e53bbe3aa681a86151aa41798a264407438d44db14b267ed8c9ca8a4516073fe0b53b38b06c4b8903f091182c17bcf6176953ef259cb697c880c898ed9b86aa4efd26bd635341f2b147aa1d22bcf7f5dad2d9394d2b7fda3fc81f4bf5f391b4448693478cc536552f69dc2db71b8da52ed0201c175f0f1c37dc42231febfdd8fe54814f7f986784c43ad5a0c8decfaef6fcec25dee4dd8f4be8188816a77cf175d1f54b77b5acb6f4a6c6c60f022243deadc7e4c2c9f9779edd79a275e0164444695bbdf9d5d94f9ff5f085435cfb82ec0d03625c801692fc882cc62affba5ee8772d78de3938abc57eea11a5de0f2fecb4809ffd52ad1168bf7fafaba6e6ef1b1a07b6d9c08be0c833eb2e97d9153375b37f8e2f494a7eff1d0274ae1ab57db172e9803fe6ccfd406a159bd1a4070cb1f3aa3499df8576ed21b0eb3aeb86c55335debe36ff3785756f3a431984539616c69f11797e48905db4ff2505eb96642a81992f00ab9a028136168f713219a2b26df50a30d8c90aae43626c573d36c866a61cd834d2e95e493b7d71d699caee630480dd50802254143e9abe75aaf6a49034746e42a7e8e8bbd1a238fb9ceeabe012da3b6a496ce3efeef1a1b437442a6f3171539fa52222278bcdf4db09add60419b!
d4614ce60657c9fa77ea05bec49117eaf277a597afc9939b211113a0438a9bacdaec0f3734acab9ef6e6cda52f0b1bef39a814b2e78a1222218129e9dcdee3cc9ea47c4ec80619bf4443f9374a72be4d20328ba5e8db3519bfa71b44ea345e9bb023cfefa7179c1d16f65940c9b27e58f0f31b82252fca9d9b2973eac53d765ccd696f55eb94171ec1c27d6d46e019248bbc1d50f4eb14d55fd9c68c8f75708e1fc01ee1a6f570ea646006d00ca10857fa1caff107d7f7057eba98065000000009454e444ea240628';
+	}
+	return(\$main::imgErr);
+}
+
+
+package myCGI;
+
+use CGI;
+
+sub new {
+	my $proto = shift;
+	my $class = ref($proto) || $proto;
+	my $self  = {};
+	$self->{'CGI'} = CGI->new(shift);
+	bless ($self, $class);
+	return $self;
+}
+
+sub r {
+	my $self = shift;
+	return($self->{'CGI'});
+}
+
+sub DESTROY {
+	my $self = shift;
+
+}
+
+sub paramDefault {
+	my $self    = shift;
+	my %param   = @_;
+	
+	foreach my $param (keys(%param)) {
+		unless (defined($self->r->param(-Name=>$param))) {
+			$self->r->param(-Name=>$param, -Value=>$param{$param});
+		}
+	}
+	return values(%param);
+}
+
+sub paramHidden {
+	my $self    = shift;
+	my @hidden = @_;
+
+	my @result;
+	foreach my $param (@hidden) {
+		push(@result, $self->r->hidden(-Name=>$param));
+	}
+	return(@result);
+}
+
+sub saveparam {
+	my $self = shift;
+	my $savefile = shift;
+	my $fh = FileHandle->new($savefile, "w");
+	defined($fh) || confess("Error opening $savefile (w): $!");
+	$self->r->save($fh);
+	$fh->close();
+	chmod 0777, $savefile;
+}
+
+
+=head1 NAME
+
+rrdview.cgi - Perl CGI software to graph rrd image online
+
+=head1 SYNOPSIS
+
+Put it on any cgi-bin/ directory, use a browser, click and fill in an
+rrd file in the first textfield (replacing foo.rrd). The file belongs
+to the web server. 
+
+=head1 DESCRIPTION
+
+Just another rrd viewer. 
+
+=head1 TODO
+
+ . An upload textfield to allow graphing client rrd files.
+ . Deal with LAST, MAX, MIN RRA.
+
+=head1 AUTHOR
+
+Gilles LAMIRAL 
+lamiral at mail.dotcom.fr
+
+=head1 SEE ALSO
+
+rrdtool(1), perl(1).
+
+=cut
+
+
+

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdview/README
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/rrdview/README	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/rrdview/README	Sat Jul 13 21:25:57 2002
@@ -0,0 +1,63 @@
+User Contributed Perl Documentation                RRDVIEW.CGI(1)
+
+
+
+NNNNAAAAMMMMEEEE
+     rrdview.cgi - Perl CGI software to graph rrd image online
+
+SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+     Put it on any cgi-bin/ directory, use a browser, click and
+     fill in an rrd file in the first textfield (replacing
+     foo.rrd). The file belongs to the web server.
+
+DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+     Just another rrd viewer.
+
+TTTTOOOODDDDOOOO
+      . An upload textfield to allow graphing client rrd files.
+      . Deal with LAST, MAX, MIN RRA.
+
+
+AAAAUUUUTTTTHHHHOOOORRRR
+     Gilles LAMIRAL lamiral at mail.dotcom.fr
+
+SSSSEEEEEEEE AAAALLLLSSSSOOOO
+     _r_r_d_t_o_o_l(1), _p_e_r_l(1).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2000-09-23          Last change: perl v5.6.0                    1
+
+
+

Modified: trunk/orca/packages/rrdtool-1.0.33/contrib/Makefile.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/Makefile.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/Makefile.in	Sat Jul 13 21:25:57 2002
@@ -64,21 +64,32 @@
 target_alias = @target_alias@
 target_triplet = @target@
 CC = @CC@
-CFLAGS = @CFLAGS@
 CGI_LIB_DIR = @CGI_LIB_DIR@
 COMP_PERL = @COMP_PERL@
 CPP = @CPP@
 GD_LIB_DIR = @GD_LIB_DIR@
 LIBTOOL = @LIBTOOL@
+NROFF = @NROFF@
 PERL = @PERL@
+PERLFLAGS = @PERLFLAGS@
+PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PNG_LIB_DIR = @PNG_LIB_DIR@
 RANLIB = @RANLIB@
+SO_EXT = @SO_EXT@
+TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
+TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
+TCL_PREFIX = @TCL_PREFIX@
+TCL_SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@
+TCL_SHLIB_LD = @TCL_SHLIB_LD@
+TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+TROFF = @TROFF@
+VERSION = @VERSION@
 ZLIB_LIB_DIR = @ZLIB_LIB_DIR@
 
-SUBDIRS = log2rrd rrd-file-icon trytime rrdproc rrdlastds add_ds killspike rrdfetchnames
-
+SUBDIRS = trytime
 contribdir = $(prefix)/contrib
 contrib_DATA = README
+EXTRA_DIST = rrdview log2rrd rrd-file-icon rrdproc rrdlastds add_ds killspike rrdfetchnames snmpstats rrdexplorer php3 php4
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
 CONFIG_HEADER = ../config/config.h
 CONFIG_CLEAN_FILES = 
@@ -88,7 +99,6 @@
 
 
 PACKAGE = @PACKAGE@
-VERSION = @VERSION@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
@@ -220,7 +230,7 @@
 	@for file in $(DISTFILES); do \
 	  d=$(srcdir); \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$/$$file $(distdir)/$$file; \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
 	    test -f $(distdir)/$$file \
 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdfetchnames/rrdfetchnames.pl
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/rrdfetchnames/rrdfetchnames.pl	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/rrdfetchnames/rrdfetchnames.pl	Sat Jul 13 21:25:57 2002
@@ -0,0 +1,30 @@
+#!/usr/bin/perl
+
+use strict;
+
+#makes things work when run without install
+use lib qw( ../../perl-shared/blib/lib ../../perl-shared/blib/arch );
+
+#makes programm work AFTER install
+use lib qw( /usr/local/rrdtool-1.0.30/lib/perl ../lib/perl );
+
+use vars qw(@ISA $loaded);
+
+use RRDs;
+
+my $NAME = $ARGV[ 0];
+my $SEPARATOR = " ";
+my $CF = "AVERAGE";
+
+my ($start,$step,$names,$data) = RRDs::fetch "$NAME", "$CF", "--start", "now","--end","start+1";
+
+if ( my $ERR = RRDs::error){
+	die "ERROR while fetching data from $NAME $ERR\n";
+}
+
+print join( $SEPARATOR, @$names), "\n";
+
+sub usage{
+	print "usage: rrdfetchnames filename";
+};
+

Deleted: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdfetchnames/Makefile.in

Deleted: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdfetchnames/Makefile.am

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/killspike/killspike.pl
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/killspike/killspike.pl	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/killspike/killspike.pl	Sat Jul 13 21:25:58 2002
@@ -0,0 +1,137 @@
+#! /usr/sepp/bin/perl -w
+
+# $Id: killspike.pl,v 1.3 2000/06/11 22:08:08 bertd Exp $
+# $Source: /cvs-mis/local/support/killspike/killspike.pl,v $
+
+# This script will read an XML file produced by
+#	rrdtool dump foo.rrd >in.xml
+# and look at the $maxspike highest samples per datasource. It then finds
+# the records with the most hits and ditches the data. The resulting file
+# can be read back into the RRD database with the command
+#	rrdtool restore out.xml foo.rrd
+#
+# The whole idea is to find and eradicate "spikes" caused by erroneous
+# readings affecting entire records.
+#
+# This tool is not for the faint of heart, will require tweaking per case
+# (even though that should just be picking values for cutoff and to a lesser
+# extent, maxspike). It will cause data loss, for obvious reasons.
+#
+# THIS SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT IS USEFUL, AND COMES WITH
+# NO WARRANTY. USE AT YOUR OWN RISK!
+#
+#			Bert Driehuis <driehuis at playbeing.org>
+
+use strict;
+
+my $maxspike = 25;	# How many top samples to consider per datasource
+my $cutoff = 20;	# How many records to ditch
+my $debug = 1;
+my $file = "in.xml";
+my $outfile = "out.xml";
+
+my $nds = 0;
+my @dsl = ();
+my @dsi = ();
+my @topindx = ();
+my @botindx = ();
+my @dsname = ();
+my $i;
+my $j;
+
+# Count the number of data sources
+open(IN, $file) || die;
+while(<IN>) {
+	if (/<name>\s*(\w+)\s*/) {
+		$dsname[$nds] = $1;
+		$nds++;
+	}
+}
+close IN;
+
+print "Found $nds datasources\n" if $debug;
+
+# Set up the list of lists for the datasource data
+for ($i = 0; $i < $nds; $i++) {
+	my @dsdata = ();
+	push @dsl, \@dsdata;
+	my @dsindex = ();
+	push @dsi, \@dsindex;
+	my @top = ();
+	push @topindx, \@top;
+	my @bot = ();
+	push @botindx, \@bot;
+}
+
+# Slurp all datasource fields into the @dsl Lol
+my $recno = -1;
+open(IN, $file) || die;
+while(<IN>) {
+	next if !/<row>/;
+	$recno++;
+	my @data = split(/ /);
+	die "Malformed input" if $data[5] ne "<row><v>";
+	die "Malformed record" if $data[5 + ($nds * 2)] ne "</v></row>\n";
+	for ($i = 0; $i < $nds; $i++) {
+		my $sample = $data[($i * 2) + 6];
+		#print "$sample\n";
+		push @{$dsl[$i]}, $sample;
+	}
+}
+close IN;
+
+# Set up a LoL with indexes, and ditch the values that represent NaN's
+for ($i = 0; $i < $nds; $i++) {
+	@{$dsi[$i]} = grep { ${$dsl[$i]}[$_] ne "NaN" } (0..$recno);
+	print "$dsname[$i] has $#{$dsi[$i]} valid samples\n" if $debug;
+}
+
+sub sortit {
+	${$dsl[$i]}[$a] <=> ${$dsl[$i]}[$b];
+}
+my %indexes;
+for ($i = 0; $i < $nds; $i++) {
+	next if ($#{$dsi[$i]} < $maxspike);
+	@{$dsi[$i]} = sort sortit @{$dsi[$i]};
+	@{$botindx[$i]} = @{$dsi[$i]};
+	@{$topindx[$i]} = splice(@{$botindx[$i]}, -$maxspike);
+	print "$dsname[$i] top $maxspike: ".join(' ', @{$topindx[$i]})."\n";
+	for($j = 0; $j < $maxspike; $j++) {
+		$indexes{${$topindx[$i]}[$j]} = 0 if
+				!defined($indexes{${$topindx[$i]}[$j]});
+		$indexes{${$topindx[$i]}[$j]}++;
+		printf "%1.1e ", ${$dsl[$i]}[${$topindx[$i]}[$j]];
+	}
+	print "\n";
+}
+
+# Report on the hit rate of the records to be dumped, and a few for
+# reference.
+$j = 0;
+my %ditch;
+foreach $i (sort {$indexes{$b} <=> $indexes{$a}} keys %indexes) {
+	print "Record index $i: $indexes{$i} hits\n";
+	$ditch{$i} = 1 if $j < $cutoff;
+	print "----------\n" if $j + 1 == $cutoff;
+	last if $j++ > $maxspike;
+}
+
+# Okay, so we start ditching the records. You can always re-run the script
+# if the results don't suit you after adjusting $cutoff or $maxspike.
+$recno = -1;
+open(IN, $file) || die;
+open(OUT, ">$outfile") || die;
+while(<IN>) {
+	print OUT if !/<row>/;
+	next if !/<row>/;
+	$recno++;
+	print OUT if !defined($ditch{$recno});
+	next if !defined($ditch{$recno});
+	my @data = split(/ /);
+	for ($i = 0; $i < $nds; $i++) {
+		$data[($i * 2) + 6] = "NaN";
+	}
+	print OUT join(' ', @data);
+}
+close IN;
+close OUT;

Modified: trunk/orca/packages/rrdtool-1.0.33/contrib/killspike/killspike.pl.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/killspike/killspike.pl.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/killspike/killspike.pl.in	Sat Jul 13 21:25:58 2002
@@ -1,6 +1,6 @@
 #! @PERL@ -w
 
-# $Id: killspike.pl,v 1.2 2000/01/14 01:56:59 bertd Exp $
+# $Id: killspike.pl,v 1.3 2000/06/11 22:08:08 bertd Exp $
 # $Source: /cvs-mis/local/support/killspike/killspike.pl,v $
 
 # This script will read an XML file produced by
@@ -35,13 +35,17 @@
 my @dsi = ();
 my @topindx = ();
 my @botindx = ();
+my @dsname = ();
 my $i;
 my $j;
 
 # Count the number of data sources
 open(IN, $file) || die;
 while(<IN>) {
-	$nds++ if /<name>\s*ds/;
+	if (/<name>\s*(\w+)\s*/) {
+		$dsname[$nds] = $1;
+		$nds++;
+	}
 }
 close IN;
 
@@ -79,7 +83,7 @@
 # Set up a LoL with indexes, and ditch the values that represent NaN's
 for ($i = 0; $i < $nds; $i++) {
 	@{$dsi[$i]} = grep { ${$dsl[$i]}[$_] ne "NaN" } (0..$recno);
-	print "Ds$i has $#{$dsi[$i]} valid samples\n" if $debug;
+	print "$dsname[$i] has $#{$dsi[$i]} valid samples\n" if $debug;
 }
 
 sub sortit {
@@ -87,10 +91,11 @@
 }
 my %indexes;
 for ($i = 0; $i < $nds; $i++) {
+	next if ($#{$dsi[$i]} < $maxspike);
 	@{$dsi[$i]} = sort sortit @{$dsi[$i]};
 	@{$botindx[$i]} = @{$dsi[$i]};
 	@{$topindx[$i]} = splice(@{$botindx[$i]}, -$maxspike);
-	print "ds$i top $maxspike: ".join(' ', @{$topindx[$i]})."\n";
+	print "$dsname[$i] top $maxspike: ".join(' ', @{$topindx[$i]})."\n";
 	for($j = 0; $j < $maxspike; $j++) {
 		$indexes{${$topindx[$i]}[$j]} = 0 if
 				!defined($indexes{${$topindx[$i]}[$j]});

Deleted: trunk/orca/packages/rrdtool-1.0.33/contrib/killspike/Makefile.in

Deleted: trunk/orca/packages/rrdtool-1.0.33/contrib/killspike/Makefile.am

Deleted: trunk/orca/packages/rrdtool-1.0.33/contrib/rrd-file-icon/Makefile.in

Deleted: trunk/orca/packages/rrdtool-1.0.33/contrib/rrd-file-icon/Makefile.am

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/snmpstats/SNMPstats.pl
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/snmpstats/SNMPstats.pl	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/snmpstats/SNMPstats.pl	Sat Jul 13 21:25:59 2002
@@ -0,0 +1,363 @@
+#!/usr/bin/perl -w
+
+# Q: Who wrote this?
+# Bill Nash - billn at billn.net / billn at gblx.net
+#
+# Q: Why?
+# SNMP retrieval and storage of interface utilization, ala MRTG.
+#
+# Q: Is this a supported utility?
+# Barely. That means if there's a serious problem with it, you can email me. I'll take feature requests
+# provided they're presented in an intelligent manner. I will NOT write scripts for you. There's a plethora
+# of information available to you, stop being lazy and do it yourself. Mostly, I wrote this for myself. I
+# released it to the community at large because it's useful. Your mileage may vary. This code carries no 
+# warranty and I'm not responsible if you do something stupid with it.
+#
+# Q: Why does the author sound like a grumpy curmudgeon?
+# Because I'm releasing a utility to the public, and I detest people. I read the MRTG lists. I know what you 
+# people are and are not capable of. I could jump up on my soapbox and rant about the general laziness of people,
+# but no one will care. The user base at large is full of lazy bastards who just want someone else to create something
+# that does exactly what they want, with as little effort required on their part.
+#
+# Q: Is it safe to ask questions about this utility?
+# I will be more than happy to entertain discussions about this utility, provided:
+#	It's a discussion of perl mechanics, and the person asking the question knows something about Perl.
+#	It's a discussion of SNMP mechanics, and the person asking the question isn't asking where to find Mibs/objects.
+#	You're a Playboy Bunny and you'd like to meet me for dinner.
+#
+# Q: Your code sucks, billn, why does this do [such and such], and why didn't you do condense [this and this]?
+# This is intended to be a simple utility. No fancy obsfucation, no serious attention to efficiency. The only real creative 
+# parts are using ifDescr/ifName as an interface basis (which offsets the nasty ifIndex shift problem by using ifIndex has a 
+# value of the key, ifDescr/ifName, instead of vice versa. The ifIndex can change all it wants. Don't go saying 'Well, what if 
+# interface name changes?', because I'll just say "Then it's a new interface. Cope."
+# Also, by NOT obfuscating functions and keeping things simple, I'd hope people looking at this script that aren't fully versed
+# in the intricacies and foibles of SNMP, PERL and RRD will have an easier time grasping the concepts, and maybe learn a bit from 
+# this. Much of the code contained in here is interchangable, data sources can be substituted left and right, and I fully expect
+# someone to hack this into a shining pearl of relative usefulness on a regular basis. It's not the end all, be all of SNMP pollers,
+# but I expect it'll find widespread use.
+
+$local_dir = "/usr/local/rrdtool-1.0.28";	# Where this script lives
+$rrd_store = "$local_dir/rrd";		# Where to keep our rrd datastores
+
+$debug = 0;
+
+# This is Net::SNMP-2.00. It's not included with this script. Try CPAN.
+use Net::SNMP;
+
+# RRD Perl module. If you don't have it, why are you here?
+use RRDs;
+
+# This piece can be ripped out and subbed for any number of data storage methods. This is a simple method
+# that works for those handling only a few devices. IP addresses are important because I don't use hostname
+# matches for the SNMP calls. This eliminates DNS dependancies, but does require you to maintain your code or
+# host registries.
+
+$devices{"Hades"}{'ip_address'} = "10.0.0.254"; # my switch
+$devices{"Hades"}{'snmp_read'} = "public";
+$devices{"Bifrost"}{'ip_address'} = "10.0.0.253"; # my router
+$devices{"Bifrost"}{'snmp_read'} = "public";
+
+# Standard SNMP mib2 jazz. Feel free to edit. YMMV.
+
+# Variables from the %oids hash we'll be referencing later. It's easier to call them by a name.
+# What, you think I'm gonna memorize SNMP oids? =P
+
+ at poll_int = (
+		"ifDescr",
+		"ifOperStatus",
+		"ifAlias",
+		"ifInErrors",
+		"ifInOctets",
+		"ifOutErrors",
+		"ifOutOctets",
+		"ifSpeed"
+);
+
+%oids = (
+	sysDescr              => "1.3.6.1.2.1.1.1.0",
+	sysName               => "1.3.6.1.2.1.1.5.0",
+	sysUptime             => "1.3.6.1.2.1.1.3.0",
+	ifNumber              => "1.3.6.1.2.1.2.1.0",
+	#ifDescr               => "1.3.6.1.2.1.2.2.1.2",
+	ifType                => "1.3.6.1.2.1.2.2.1.3",
+	ifSpeed               => "1.3.6.1.2.1.2.2.1.5",
+	ifPhysAddress         => "1.3.6.1.2.1.2.2.1.6",
+	ifAdminStatus         => "1.3.6.1.2.1.2.2.1.7", 
+	ifOperStatus          => "1.3.6.1.2.1.2.2.1.8",
+	ifAlias               => "1.3.6.1.2.1.31.1.1.1.18",
+	ifInErrors            => "1.3.6.1.2.1.2.2.1.14",
+	ifInOctets            => "1.3.6.1.2.1.2.2.1.10",
+	ifInUnkProtos         => "1.3.6.1.2.1.2.2.1.15",
+	ifLastChange          => "1.3.6.1.2.1.2.2.1.19",
+	ifDescr                => "1.3.6.1.2.1.31.1.1.1.1", # was ifXName, subbed for ifDescr
+	ifOutDiscards         => "1.3.6.1.2.1.2.2.1.19",
+	ifOutErrors           => "1.3.6.1.2.1.2.2.1.20",
+	ifOutOctets           => "1.3.6.1.2.1.2.2.1.16"
+);
+
+while(1) {
+	$start = time;
+
+	foreach $device_name (keys %devices) {
+		undef(%ifAdmin);
+		# Establish an snmp session with the device
+        	my($session, $error) = Net::SNMP->session(
+                                            Hostname  => $devices{$device_name}{'ip_address'},
+                                            Community => $devices{$device_name}{'snmp_read'},
+                                            Translate => 1,
+                                            VerifyIP  => 1
+        	);
+
+	# This example may seem a bit long and drawn out, but it's better for a clear view of how the procedure works
+	# It's entirely possible (and more efficient) to restructure this into a tight bundle of reusable code.
+        	if ($session) {
+                	print "$device_name: SNMP Session established ($device_name, $devices{$device_name}{'ip_address'})\n" if ($debug);
+
+		# First step, find all the administratively active interfaces. Typically, this should be the ONLY
+		# table that takes a walk across all interfaces. If you're doing smart and clean device management,
+		# all unused/undesignated interfaces should be admin'd down and scrubbed of configs. If you don't
+		# maintain this kind of device policy, don't cry to me because things take longer than you expect.
+
+		# For the sake of efficiency, I should note here that this set of data doesn't HAVE to be generated with an SNMP poll
+		# You can have an entirely external management system here that dictates what interfaces are tracked. You can rip this
+		# chunk out and replace it with something else entirely.
+
+		#print "Retrieving ifAdminStatus table: $oids{'ifAdminStatus'}\n" if ($debug);
+                	$response = $session->get_table($oids{'ifAdminStatus'});
+                	if($error_message = $session->error) {
+                        	if($error_message eq "Requested table is empty" ||
+                           		$error_message eq "Recieved SNMP noSuchName(2) error-status at error-index 1") {}
+                        	else {
+                                	print STDERR "ifAdmin table get failed ($device_name: $oids{'ifAdminStatus'}): $error_message\n"
+                        	}	# end if
+				next; # Can't get an ifAdminStatus table? No active interfaces or a borked SNMP engine. Next!
+                	} # end if
+
+                	%array = %{$response};
+                	foreach $key (keys %array) {
+
+				$ifIndex = $key;
+				$ifIndex =~ s/^$oids{'ifAdminStatus'}.//g;
+
+			# Hash the ifAdminStatus data if the status is 1. We aren't going to bother with any 
+			# interfaces that aren't set active.
+			# For the curious, possible values here are:
+			# @OperStatus=("null", "Up", "Down", "Looped", "null", "Dormant", "Missing");
+
+                       		$ifAdmin{$ifIndex} = $array{$key};
+				#print "$device_name: ifIndex $ifIndex, ifAdmin $array{$key} $ifAdmin{$ifIndex}\n" if ($debug);
+                	} #end foreach
+
+			# Cycle through all The admin'd active interfaces, by ifIndex
+			foreach $ifIndex (keys %ifAdmin) {
+				undef(@interface_rrd);
+				next if ($ifAdmin{$ifIndex} != 1);
+			# Cycle through all the objects we want to track for each interface. This 
+			# is a highly reusable set of code, set up to perform the same task repeatedly for 
+			# (potentially long) lists of variables.
+				foreach $object (@poll_int) {
+				# get the numeric oid values from the oids table
+					$object_id = $oids{$object};
+
+				# go get the object.
+	                		$response = $session->get_request("$object_id.$ifIndex");
+      	         			if($error_message = $session->error) {
+						if($error_message eq "Recieved SNMP noSuchName(2) error-status at error-index 1") {
+						# It's a common occurence to poll an interface for an object that it
+						# doesn't support, so we'll just U the object.
+							$data{$device_name}{$ifIndex}{$object} = "U";
+						} #end if
+
+					# Whatever the object was, it didn't want to be 'gotten', so screw it.
+       	                			print STDERR "Object get failed ($device_name: $object_id.$ifIndex):$error_message\n" if ($debug);
+						next;
+                			} #end if
+
+                			%array = %{$response};
+
+				# Shucks, got data, get to work. This chunk of code is pretty generic, and you'll 
+				# recognize it from up above. I *could* use a single iteration here, but better save
+				# in case the snmp engine did something hokey, or we used a table base variable in the get.
+				# The multilayer hash prolly makes some of you twitch to see, but hey, if you don't like it,
+				# why are you reading my code to begin with? It works, take a hike.
+				# Anyway, it's an extensible memory structure that doesn't care what you're stuffing into it.
+
+                			foreach $key (keys %array) {
+		                        	$ifIndex = $key;
+               			        	$ifIndex =~ s/^$oids{$object}.//g;
+
+                        			$data{$device_name}{$ifIndex}{$object} = $array{$key};
+						#print "$device_name: ifIndex $ifIndex, $object = $data{$device_name}{$ifIndex}{$object}\n";
+                			} #end foreach
+				} #end foreach
+			} #end foreach
+
+		# Alright, so at this point, we should have a full set of data (whatever we requested) for 
+		# each active interface.
+		# This whole next section is all about what we do with any given piece of data, so if you're doing
+		# customization beyond what I've included, here's your sandbox, here's your shovel. Go build me a Buick.
+
+		# My primary goal for this utility is low overhead interface utilization tracking for my router and switch.
+		# In combination with RRDtool's graphing abilities, poof, it's a skimpy but solid (and extensible) replacement
+		# for MRTG. Don't get me wrong, I like MRTG, but RRDtool a lot easier to do flexible things with. The fact
+		# that this whole piece is in Perl provides a working template for bigger and crazier things, like using 
+		# a real SQL db for tracking port data, or real time data feeds to Linus knows what. With these things in
+		# mind, let's start tossing some data.
+
+		#        ifSpeed               => "1.3.6.1.2.1.2.2.1.5",
+		# Since we're doing traffic graphing, it's helpful to know the size of the pipe we're tracking.
+
+        	#	ifOperStatus          => "1.3.6.1.2.1.2.2.1.8",
+		# If the interface is down for some reason, it'd be good to have a way to represent that.
+
+        	#	ifAlias               => "1.3.6.1.2.1.31.1.1.1.18",
+		# ifAlias is usually a human supplied interface description. 
+
+		#       ifInErrors            => "1.3.6.1.2.1.2.2.1.14",
+		#       ifInOctets            => "1.3.6.1.2.1.2.2.1.10",
+		#       ifInUnkProtos         => "1.3.6.1.2.1.2.2.1.15",
+		#       ifOutDiscards         => "1.3.6.1.2.1.2.2.1.19",
+		#       ifOutErrors           => "1.3.6.1.2.1.2.2.1.20",
+		#       ifOutOctets           => "1.3.6.1.2.1.2.2.1.16"
+		# These should be pretty obvious. No, that's not short for Uncle Protos.
+
+		#       ifDescr               => "1.3.6.1.2.1.2.2.1.2",
+		# This is usually the name for an interface. Very important variable.
+		# Since I'm testing with a cisco catalyst, I've switched ifDescr for ifName/ifXName, up top. Less pain.
+
+		# We need a place to store this stuff, so let's check out storage structures
+
+			foreach $device_name (keys %data) {
+				#print "Generating/feeding data for $device_name\n";
+				foreach $ifIndex (keys %{$data{$device_name}}) {
+
+					$ifDescr = $data{$device_name}{$ifIndex}{'ifDescr'};
+					if ($ifDescr eq "") {
+						#print "$device_name ifIndex $ifIndex apparantly has a null ifDescr -> [$ifDescr], skipping\n";
+						next;
+					} # end if
+
+			# If you recognize where I stole these from, you may already know me as '[tHUg]Heartless'
+			# I prefer the Aug and the TMP, and I fear no AWP. =)
+			# This set of regexp's is for scrubbing potentially exciting characters from interface names before 
+			# using them as the basis for storing files. Some OS's and file systems may object to some of these 
+			# characters, so, better safe than annoyed.
+			# You'll note I don't provide facilities for reverting this. I just collect the stuff. Display is your problem.
+
+			    		$ifDescr =~ s/ /_/g;
+			    		$ifDescr =~ s/\=/\[EQUAL\]/g;
+			    		$ifDescr =~ s/\,/\[CMA\]/g;
+			    		$ifDescr =~ s/;/\[SMICLN\]/g;
+			   	 	$ifDescr =~ s/:/\[CLN\]/g;
+			  	  	$ifDescr =~ s/\"/\[DBLQT\]/g;
+			 	   	$ifDescr =~ s/\'/\[SNGLQT\]/g;
+				    	$ifDescr =~ s/\{/\[LB2\]/g;
+				    	$ifDescr =~ s/\}/\[RB2\]/g;
+				    	$ifDescr =~ s/\+/\[PLS\]/g;
+				    	$ifDescr =~ s/\-/\[DSH\]/g;
+				    	$ifDescr =~ s/\(/\[LPRN\]/g;
+				    	$ifDescr =~ s/\)/\[RPRN\]/g;
+				    	$ifDescr =~ s/\*/\[STR\]/g;
+				    	$ifDescr =~ s/\&/\[AND\]/g;
+				    	$ifDescr =~ s/\|/\[PIPE\]/g;
+				    	$ifDescr =~ s/\\/\[BSLSH\]/g;
+				    	$ifDescr =~ s/\//\[FSLSH\]/g;
+				    	$ifDescr =~ s/\?/\[QUESTN\]/g;
+				    	$ifDescr =~ s/\</\[LT\]/g;
+				    	$ifDescr =~ s/\>/\[GT\]/g;
+				    	$ifDescr =~ s/\./\[DOT\]/g;
+				    	$ifDescr =~ s/\!/\[XCLM\]/g;
+				    	$ifDescr =~ s/\@/\[AT\]/g;
+				    	$ifDescr =~ s/\#/\[PND\]/g;
+				    	$ifDescr =~ s/\$/\[DLLR\]/g;
+				    	$ifDescr =~ s/\%/\[\PRCNT\]/g;
+				    	$ifDescr =~ s/\^/\[CRT\]/g;
+		
+					if ( -e "$rrd_store/$device_name-$ifDescr.rrd") {
+					# Uh, hey, it's there. Don't worry, be happy.
+					}
+					else {  # Oh, damn, it isn't, better create it.
+				
+			# Knowing the speed of the interface, generally reported by SNMP in bits per second,
+			# we can fairly accurately determine how long it could take that counter to roll over,
+			# if it's a 32 bit counter.
+			# So, we'll use that info in creating the interface data. You may recognize these variables
+			# from the RRD tutorial docs, which were further derived from MRTG. I reuse them both because
+			# I'm lazy and so people will recognize what to hack on if they've beat up MRTG before.
+
+						if ($speed = $data{$device_name}{$ifIndex}{'ifSpeed'}) {
+							print "$device_name: Found $speed speed for $ifIndex\n";
+						}
+						else {
+							$speed = "U";
+						}
+	
+						@interface_rrd = (
+						"DS:InBits:COUNTER:600:0:$speed",
+						"DS:OutBits:COUNTER:600:0:$speed",
+						"RRA:AVERAGE:0.5:1:600",
+						"RRA:AVERAGE:0.5:6:700",
+						"RRA:AVERAGE:0.5:24:775",
+						"RRA:AVERAGE:0.5:288:797",
+						"RRA:MAX:0.5:1:600",
+						"RRA:MAX:0.5:6:700",
+						"RRA:MAX:0.5:24:775",
+						"RRA:MAX:0.5:288:797"
+						);
+	
+			# I feed the array to the create argument here, so it's easier to alter the rrd
+			# creation by just changing entries in the array above. Generic and reusable.
+
+						if(RRDs::create ("$rrd_store/$device_name-$ifDescr.rrd",
+							 "--step=300", 
+							 @interface_rrd)) {
+							print "Built RRd for $ifDescr\n";
+						}
+						else {
+							$ERR=RRDs::error;
+							print "RRd build for $ifDescr appears to have failed: $ERR\n";
+							next;
+						}
+					}
+
+
+			# Do some calculations.
+
+					$data{$device_name}{$ifIndex}{InBits} = $data{$device_name}{$ifIndex}{ifInOctets} * 8;
+					$data{$device_name}{$ifIndex}{OutBits} = $data{$device_name}{$ifIndex}{ifOutOctets} * 8;
+
+			# Feed the RRD our data.
+
+					$rrdfeed = join ":", ("N", 
+						$data{$device_name}{$ifIndex}{InBits},
+#      		                          	$data{$device_name}{$ifIndex}{IfInErrors},
+       		                         	$data{$device_name}{$ifIndex}{OutBits},
+#      		                          	$data{$device_name}{$ifIndex}{IfOutErrors},
+					);
+
+					RRDs::update ("$rrd_store/$device_name-$ifDescr.rrd",
+						"--template", "InBits:OutBits", 
+						"$rrdfeed"); 
+
+					if($ERR=RRDs::error) {
+						print STDERR "$rrd_store/$device_name-$ifDescr.rrd update failed: $ERR\n";
+					}
+					else {
+						#print "$rrd_store/$device_name-$ifDescr.rrd updated\n" if ($debug);
+					}
+				}
+			}	# yeah, it's sloppy, sue me.
+        	}
+        	else {
+		# Abort abort abort, no go no go. uNF. =)
+                	print STDERR "$device_name: SNMP Session failed: $error\n";
+        	}
+	}
+
+	$end = time;
+
+	$duration = $end - $start;
+	$sleep_period = 300 - $duration;
+	if($sleep_period > 0) { sleep($sleep_period) }
+	undef(%data);
+}

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/snmpstats/README
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/snmpstats/README	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/snmpstats/README	Sat Jul 13 21:25:59 2002
@@ -0,0 +1,43 @@
+SNMPstats.pl is a moderately simple and quick perl SNMP poller for simple
+interface traffic and other counters. It's written with flexible and easy
+hacking in mind, and is commented appropriately.
+
+It requires Net::SNMP version 2, available from CPAN.
+
+For the sake of simplicity, device names, IPs, and SNMP read strings are
+hard coded, but this can be easily substituted with something more
+dynamic. Structure for the devices hash is:
+
+$devices{<Canonical device name>}{'ip_address'} = <target ip address>
+				 {'snmp_read'}  = <SNMP read community>
+
+SNMP objects are stored in %oids. SNMP objects polled during device sweeps
+are stored in @poll_int, using named references to the object names used
+as key variables in %oids.
+
+Interface stats are only collected for interfaces that have an
+ifAdminStatus of 1. This cuts down on SNMP load quite a bit, given devices
+are properly managed. Your mileage will vary based on device policies.
+
+RRDs are only created for interfaces with ifAdminStatus of 1. This gives
+you some amount of scale control. Interfaces are checked for an existing
+RRD on each collection pass, and RRDs created as needed. They are NOT
+removed if you admin down an interface, so stale RRD cleanup is your
+problem.
+
+One caveat to note is that RRDs are created with upper limits based on
+ifSpeed. For autosensing 10/100 switches, this is a problem. In an effort
+to keep this utility simple, I formally declare it to be 'your
+problem'.
+
+This utility runs as a recurring loop, so it's meant to be run in the
+background like a daemon. You can strip the while/sleep sets and stuff it
+in cron, if you're so inclined. YMMV. 
+
+The script itself is heavily commented, explaining what I do as I go. Be a
+good user, read the code before you run it. It's simple and
+straightforward, and it's a good idea to understand how it works,
+especially if you're a novice user.
+
+Bill Nash
+billn at billn.net / billn at gblx.net

Modified: trunk/orca/packages/rrdtool-1.0.33/contrib/trytime/Makefile.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/trytime/Makefile.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/trytime/Makefile.in	Sat Jul 13 21:25:59 2002
@@ -64,15 +64,26 @@
 target_alias = @target_alias@
 target_triplet = @target@
 CC = @CC@
-CFLAGS = @CFLAGS@
 CGI_LIB_DIR = @CGI_LIB_DIR@
 COMP_PERL = @COMP_PERL@
 CPP = @CPP@
 GD_LIB_DIR = @GD_LIB_DIR@
 LIBTOOL = @LIBTOOL@
+NROFF = @NROFF@
 PERL = @PERL@
+PERLFLAGS = @PERLFLAGS@
+PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PNG_LIB_DIR = @PNG_LIB_DIR@
 RANLIB = @RANLIB@
+SO_EXT = @SO_EXT@
+TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
+TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
+TCL_PREFIX = @TCL_PREFIX@
+TCL_SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@
+TCL_SHLIB_LD = @TCL_SHLIB_LD@
+TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+TROFF = @TROFF@
+VERSION = @VERSION@
 ZLIB_LIB_DIR = @ZLIB_LIB_DIR@
 
 INCLUDES = -I../../src -I../../gd1.3
@@ -95,6 +106,7 @@
 trytime_OBJECTS =  trytime.o
 trytime_DEPENDENCIES =  ../../src/librrd.la
 trytime_LDFLAGS = 
+CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
@@ -105,7 +117,6 @@
 
 
 PACKAGE = @PACKAGE@
-VERSION = @VERSION@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
@@ -118,7 +129,7 @@
 .SUFFIXES:
 .SUFFIXES: .S .c .lo .o .s
 $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-	cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps contrib/trytime/Makefile
+	cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps contrib/trytime/Makefile
 
 Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
 	cd $(top_builddir) \
@@ -248,7 +259,7 @@
 	@for file in $(DISTFILES); do \
 	  d=$(srcdir); \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$/$$file $(distdir)/$$file; \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
 	    test -f $(distdir)/$$file \
 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
@@ -256,8 +267,8 @@
 	  fi; \
 	done
 trytime.o: trytime.c ../../src/getopt.h ../../src/rrd_tool.h \
-	../../config/config.h ../../src/parsetime.h \
-	../../src/rrd_format.h ../../gd1.3/gd.h
+	../../config/config.h ../../src/rrd.h ../../src/rrd_format.h \
+	../../gd1.3/gd.h
 
 info-am:
 info: info-am

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/rrdlastds.pl.in.rej
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/rrdlastds.pl.in.rej	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/rrdlastds.pl.in.rej	Sat Jul 13 21:25:59 2002
@@ -0,0 +1,13 @@
+***************
+*** 161,166 ****
+    }
+    return $i;
+  }
+- 
+- 
+  
+--- 189,192 ----
+    }
+    return $i;
+  }
+  

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/rrdlastds.pl.in.orig
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/rrdlastds.pl.in.orig	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/rrdlastds.pl.in.orig	Sat Jul 13 21:26:00 2002
@@ -0,0 +1,164 @@
+#! @PERL@
+#
+# rrdlastds - report the latest DS values from the RRA with
+# the shortest time resolution
+#
+# steve rader
+# <rader at wiscnet.net>
+# Jan 8th, 2000
+#
+# $Id: rrdlastds.in,v 1.12 2000/01/10 16:29:18 rader Exp $
+#
+
+#makes things work when run without install
+use lib qw( ../../perl-shared/blib/lib ../../perl-shared/blib/arch );
+# this is for after install
+use lib qw( @prefix@/lib/perl ../lib/perl );
+
+use RRDs;
+
+%scale_symbols = qw( -18 a -15 f -12 p -9 n -6 u -3 m 
+  3 k 6 M 9 G 12 T 15 P 18 E );
+
+#----------------------------------------
+
+while ( $ARGV[0] =~ /^-/ ) {
+  switch: {
+    if ( $ARGV[0] eq '--autoscale' || $ARGV[0] =~ /^-a/ ) {
+      $scale = 1;
+      last switch;
+    }
+    if ( $ARGV[0] eq '--conversion' || $ARGV[0] =~ /^-c/ ) {
+      shift @ARGV;
+      $conversion = $ARGV[0];
+      if ( $conversion !~ /^\d+$|^\d+\.\d+$|^\.\d+$/ ) {
+        print "rrdlastds: bad conversion factor \"$conversion\"\n";
+        exit 1;
+      }
+      last switch;
+    }
+    if ( $ARGV[0] eq '--label' || $ARGV[0] =~ /^-l/ ) {
+      shift @ARGV;
+      $label = $ARGV[0];
+      last switch;
+    }
+    if ( $ARGV[0] eq '--start' || $ARGV[0] =~ /^-s/ ) {
+      shift @ARGV;
+      $start = $ARGV[0]; 
+      if ( $start =~ /^\d+$/ ) {
+        $end = $start+1;
+      } else {
+        $end = "${start}+1sec";
+      }
+      last switch;
+    }
+    if ( $ARGV[0] eq '--verbose' || $ARGV[0] =~ /^-v/ ) {
+      $verbose = 1;
+      last switch;
+    }
+    print "rrdlastds: unknown option \"$ARGV[0]\"\n";
+    exit 1;
+  }
+  shift @ARGV;
+}
+
+if ( $#ARGV != 0 ) {
+  print <<_EOT_;
+usage: rrdlastds [-v] [-a] [-c num] [-l label] [-s stamp] some.rrd
+  -v        print the start and end times (also --verbose)
+  -a        autoscale DS values (also --autoscale)
+  -c num    convert DS values by "num" (also --conversion)
+  -l label  label DS values with "label" (also --label)
+  -s time   report about DS values at the time "time" (also --start)
+
+  The -s option supports the traditional "seconds since the Unix epoch"
+  and the AT-STYLE time specification (see man rrdfetch)
+_EOT_
+  exit 1;
+}
+
+if ( ! -f "$ARGV[0]" ) {
+  print "rrdlastds: can't find \"$ARGV[0]\"\n";
+  exit 1;
+} 
+
+#----------------------------------------
+
+if ( $start ) {
+  @fetch = ( "$ARGV[0]", '-s', "$start", '-e', "$end", 'AVERAGE' );
+} else {
+  @fetch = ( "$ARGV[0]", '-s', '-1sec', 'AVERAGE' );
+}
+($start,$step,$names,$data) = RRDs::fetch @fetch;
+
+if ( $error = RRDs::error ) {
+  print "rrdlastds: rrdtool fetch failed: \"$error\"\n";
+  exit 1;
+}
+
+#----------------------------------------
+
+if ( $verbose ) {
+  print scalar localtime($start), ' through ', 
+    scalar localtime($start+$step), "\naverage";
+} else {
+  print scalar localtime($start);
+}
+
+$line = $$data[0];
+for $i (0 .. $#$names) {
+  if ( $conversion ) {
+    $$line[$i] = $$line[$i] * $conversion;
+  }
+  if ( $scale ) {
+    ($val, $units) = autoscale($$line[$i]);
+  } else {
+    $val = $$line[$i];
+  }
+  printf "  %.2f$units$label %s", $val, $$names[$i];
+}
+print "\n";
+
+exit 0;
+
+#==================================================================
+
+sub autoscale {
+  local($value) = @_;
+  local($floor, $mag, $index, $symbol, $new_value);
+
+  if ( $value =~ /^\s*[0]+\s*$/ || 
+       $value =~ /^\s*[0]+.[0]+\s*$/ || 
+       $value =~ /^\s*NaN\s*$/ ) {
+    return $value, ' ';
+  }
+
+  $floor = &floor($value);
+  $mag = int($floor/3);
+  $index = $mag * 3;
+  $symbol = $scale_symbols{$index};
+  $new_value = $value / (10 ** $index);
+  return $new_value, " $symbol";
+}
+
+#------------------------------------------------------------------
+
+sub floor {
+  local($value) = @_;
+  local($i) = 0;
+
+  if ( $value > 1.0 ) {
+    # scale downward...
+    while ( $value > 10.0 ) {
+      $i++;
+      $value /= 10.0;
+    }
+  } else {
+    while ( $value < 10.0 ) {
+      $i--;
+      $value *= 10.0;
+    }
+  }
+  return $i;
+}
+

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/rrdlastds.pl
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/rrdlastds.pl	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/rrdlastds.pl	Sat Jul 13 21:26:00 2002
@@ -0,0 +1,192 @@
+#! /usr/sepp/bin/perl
+#
+# rrdlastds - report the latest DS values from the RRA with
+# the shortest time resolution
+#
+# steve rader
+# <rader at wiscnet.net>
+# Jan 8th, 2000
+#
+# $Id: rrdlastds.in,v 1.15 2000/01/27 21:35:16 rader Exp $
+#
+
+#makes things work when run without install
+use lib qw( ../../perl-shared/blib/lib ../../perl-shared/blib/arch );
+# this is for after install
+use lib qw( /usr/local/rrdtool-1.0.30/lib/perl ../lib/perl );
+
+use RRDs;
+
+%scale_symbols = qw( -18 a -15 f -12 p -9 n -6 u -3 m 
+  3 k 6 M 9 G 12 T 15 P 18 E );
+
+#----------------------------------------
+
+while ( $ARGV[0] =~ /^-/ ) {
+  switch: {
+    if ( $ARGV[0] eq '--autoscale' || $ARGV[0] =~ /^-a/ ) {
+      $scale = 1;
+      last switch;
+    }
+    if ( $ARGV[0] eq '--conversion' || $ARGV[0] =~ /^-c/ ) {
+      shift @ARGV;
+      $conversion = $ARGV[0];
+      if ( $conversion !~ /^\d+$|^\d+\.\d+$|^\.\d+$/ ) {
+        print "rrdlastds: bad conversion factor \"$conversion\"\n";
+        exit 1;
+      }
+      last switch;
+    }
+    if ( $ARGV[0] eq '--label' || $ARGV[0] =~ /^-l/ ) {
+      shift @ARGV;
+      $label = $ARGV[0];
+      last switch;
+    }
+    if ( $ARGV[0] eq '--start' || $ARGV[0] =~ /^-s/ ) {
+      shift @ARGV;
+      $start = $ARGV[0]; 
+      if ( $start =~ /^\d+$/ ) {
+        $end = $start+1;
+      } else {
+        $end = "${start}+1sec";
+      }
+      last switch;
+    }
+    if ( $ARGV[0] eq '--verbose' || $ARGV[0] =~ /^-v/ ) {
+      $verbose = 1;
+      last switch;
+    }
+    if ( $ARGV[0] eq '--debug' || $ARGV[0] =~ /^-d/ ) {
+      $debug = 1;
+      last switch;
+    }
+    print "rrdlastds: unknown option \"$ARGV[0]\"\n";
+    exit 1;
+  }
+  shift @ARGV;
+}
+
+if ( $#ARGV != 0 ) {
+  print <<_EOT_;
+usage: rrdlastds [-v] [-a] [-c num] [-l label] [-s stamp] some.rrd
+  -v        print the start and end times (also --verbose)
+  -a        autoscale DS values (also --autoscale)
+  -c num    convert DS values by "num" (also --conversion)
+  -l label  label DS values with "label" (also --label)
+  -s time   report about DS values at the time "time" (also --start)
+
+  The -s option supports the traditional "seconds since the Unix epoch"
+  and the AT-STYLE time specification (see man rrdfetch)
+_EOT_
+  exit 1;
+}
+
+if ( ! -f "$ARGV[0]" ) {
+  print "rrdlastds: can't find \"$ARGV[0]\"\n";
+  exit 1;
+} 
+
+#----------------------------------------
+
+if ( $start ) {
+  @fetch = ("$ARGV[0]", "-s", "$start", "-e", "$end", "AVERAGE");
+} else {
+  @fetch = ("$ARGV[0]", "-s", "-1sec", "AVERAGE");
+}
+if ( $debug ) {
+  print "rrdfetch ", join(' ', at fetch), "\n";
+}
+
+($start,$step,$names,$data) = RRDs::fetch @fetch;
+
+if ( $error = RRDs::error ) {
+  print "rrdlastds: rrdtool fetch failed: \"$error\"\n";
+  exit 1;
+}
+
+#----------------------------------------
+
+if ( $debug ) {
+  $d_start = $start;
+  print "Start:       ", scalar localtime($d_start), " ($d_start)\n";
+  print "Step size:   $step seconds\n";
+  print "DS names:    ", join (", ", @$names)."\n";
+  print "Data points: ", $#$data + 1, "\n";
+  print "Data:\n";
+  foreach $line (@$data) {
+    print "  ", scalar localtime($d_start), " ($d_start) ";
+    $d_start += $step;
+    foreach $val (@$line) {
+      printf "%12.1f ", $val;
+    }
+    print "\n";
+  }
+  print "\n";
+}
+   
+#----------------------------------------
+
+if ( $verbose ) {
+  print scalar localtime($start), ' through ', 
+    scalar localtime($start+$step), "\naverage";
+} else {
+  print scalar localtime($start);
+}
+
+$line = $$data[0];
+for $i (0 .. $#$names) {
+  if ( $conversion ) {
+    $$line[$i] = $$line[$i] * $conversion;
+  }
+  if ( $scale ) {
+    ($val, $units) = autoscale($$line[$i]);
+  } else {
+    $val = $$line[$i];
+  }
+  printf "  %.2f$units$label %s", $val, $$names[$i];
+}
+print "\n";
+
+exit 0;
+
+#==================================================================
+
+sub autoscale {
+  local($value) = @_;
+  local($floor, $mag, $index, $symbol, $new_value);
+
+  if ( $value =~ /^\s*[0]+\s*$/ || 
+       $value =~ /^\s*[0]+.[0]+\s*$/ || 
+       $value =~ /^\s*NaN\s*$/ ) {
+    return $value, ' ';
+  }
+
+  $floor = &floor($value);
+  $mag = int($floor/3);
+  $index = $mag * 3;
+  $symbol = $scale_symbols{$index};
+  $new_value = $value / (10 ** $index);
+  return $new_value, " $symbol";
+}
+
+#------------------------------------------------------------------
+
+sub floor {
+  local($value) = @_;
+  local($i) = 0;
+
+  if ( $value > 1.0 ) {
+    # scale downward...
+    while ( $value > 10.0 ) {
+      $i++;
+      $value /= 10.0;
+    }
+  } else {
+    while ( $value < 10.0 ) {
+      $i--;
+      $value *= 10.0;
+    }
+  }
+  return $i;
+}
+

Deleted: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/Makefile.in

Deleted: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdlastds/Makefile.am

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdexplorer/png.cgi
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/rrdexplorer/png.cgi	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/rrdexplorer/png.cgi	Sat Jul 13 21:26:01 2002
@@ -0,0 +1,56 @@
+#!/usr/bin/perl
+# Create rrdtool graph ... 
+
+use CGI::Carp;
+use CGI;
+use POSIX;
+use lib qw( /usr/local/rrdtool/lib/perl );
+use RRDs;
+
+my $query = new CGI;
+
+# Get params from URL
+$rrd = $query->param("rrd"); # RRD absolute path
+$start = $query->param("start"); # start time
+$end = $query->param("end"); # end time
+$hight = $query->param("hight"); # Image sizes
+$width = $query->param("width");
+$use = $query->param("use"); # which DS shal I print
+
+# List of colors for graphs
+ at color = ("#FF0000","#00FF00","#FFFF00","#0000FF","#FF00FF","#00FFFF","#FFFFFF",
+	  "#800000","#008000","#808000","#000080","#800080","#008080","#808080");
+
+# title of graph with start / end time
+$title = $rrd.": ".scalar(localtime($start))." / ".scalar(localtime($end));
+
+# Formated date(now)
+$expiredate = strftime "%a, %e %b %Y %H:%M:%S GMT", gmtime(time);
+
+print "Content-type: image/png\n"; # Use html
+print "Cache-Control: no-cache\n"; # Ensure no cashing of page
+print "Expires: $expiredate\n\n"; # Expire now
+
+$root = $ENV{"DOCUMENT_ROOT"};
+# see rrdfetchnames
+($begin,$step,$names,$data) = RRDs::fetch "$root$rrd", "AVERAGE", "--start", "now","--end","start+1";
+if ( my $ERR = RRDs::error) {
+  die "ERROR while fetching data from $NAME $ERR\n";
+}
+ at names = @$names; # list of def's "@$name"
+$j = @names; # how many DS's
+
+# Append DEF's see examples/shared-demp.pl
+for ($i = 0; $i < $j; $i++) {
+  $val = substr($use, $i, 1);
+  if ( $val == "1" ) {
+    @options = (@options, "DEF:l$i=$root$rrd:@names[$i]:AVERAGE","LINE2:l$i at color[$i]:@names[$i]");
+  }
+}
+
+# Draw the graph to std.out ("-")
+($avg,$xsize,$ysize) = RRDs::graph "-","--title", "$title","--height","$hight","--width",
+  "$width","--start",$start,"--end",$end,"-a","PNG", at options;
+if ($ERROR = RRDs::error) {
+  print "ERROR: $ERROR\n";
+}

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdexplorer/README.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/rrdexplorer/README.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/rrdexplorer/README.txt	Sat Jul 13 21:26:01 2002
@@ -0,0 +1,29 @@
+From: "Claus Norrbohm" <james at type-this.com>
+
+RRD-Explorer (formally known as clickable rrd graphs) is a
+general tool for exploring RRD-files. It eliminates the need
+for creating individual RRDs cgi-scripts to show your RRD
+graphs, just plug these 4 lines into your httpd.conf (thanks
+to Alex van den Bogaerdt):
+
+   # rrd files
+   AddIcon /icons/rrd.png .rrd
+   AddDescription "Round Robin Database" .rrd
+
+   # rrdtool handler
+   AddHandler rrd-handler rrd
+   Action rrd-handler /cgi-bin/map.cgi
+
+Last line must be modified to match your system...
+
+If your placed map.cgi & png.cgi - change owner to reflect
+your cgi-bin user and make the scripts executable ex.:
+
+   chown root.root map.cgi png.cgi
+   chmod a+rx map.cgi png.cgi
+
+Now place your RRD-files in a directory below your "DocumentRoot"
+where they can be seen, i.e. "Options Indexes" must be set for
+the directory.
+
+Enjoy, Claus

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdexplorer/map.cgi
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/rrdexplorer/map.cgi	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/rrdexplorer/map.cgi	Sat Jul 13 21:26:01 2002
@@ -0,0 +1,121 @@
+#!/usr/bin/perl
+# Explore rrd via clickable graphs by. james at type-this.com (Claus Norrbohm)
+
+# Basic idea: click high -> zoom out, click low -> zoom in,
+# click left -> back history, click right -> forward history
+
+use CGI::Carp;
+use CGI;
+use POSIX;
+use lib qw( /usr/local/rrdtool/lib/perl );
+use RRDs;
+
+my $query = new CGI;
+
+# modify as needed
+$hight = 300; # Image size
+$width = 600;
+$refresh = 3600;
+$expiredate = strftime "%a, %e %b %Y %H:%M:%S GMT", gmtime(time); # Format date(now)
+$root = $ENV{"DOCUMENT_ROOT"}; # Location of rrd
+
+print "Content-type: text/html\n"; # Use html
+print "Cache-Control: no-cache\n"; # Ensure no cashing of page
+print "Expires: $expiredate\n"; # Expire now
+print "Refresh: $refresh\n\n";
+
+print $query->start_html("Clickable rrd-graph"); # Title of html page
+
+if ($query->param()) { # the form has already been filled out
+
+  $rrd = $query->param("rrd"); # which rrd file are we tracking
+  $start = $query->param("start"); # Start time
+  $end = $query->param("end"); # End time
+  $x = $query->param("img.x"); # x/y cordinates of click
+  $y = $query->param("img.y");
+
+  # see contrib/rrdfetchnames
+  my ($begin,$step,$name,$data) = RRDs::fetch "$root$rrd","AVERAGE","--start","now","--end","start+1";
+  if ( my $ERR = RRDs::error) {
+    die "ERROR while fetching data from $NAME $ERR\n";
+  }
+  @names = @$name; # list of DS's "@$name"
+  $j = @names;
+  $esu = "";
+
+  for ($i = 0; $i < $j; $i++) { # here we find which DS we are curently tracking
+    if ($query->param("@names[$i]") == "1") {
+      @use[$i] = 1;
+      $esu .= "1"; # DS included
+    } else {
+      @use[$i] = 0;
+      $esu .= "0"; # DS not included
+    }
+  }
+
+  $intv = $end - $start; # Last used interval
+  $zoom = ($hight + 100 - $y) / $hight; # Find zoom factor + 100 because hight is not exact
+  $center = $start + $intv * $x / $width;  # Find time corresponding to click
+
+  $start = int($center - $intv * $zoom); # Calc new start
+  $end = int($center + $intv * $zoom); # Calc new end
+
+} else { # first time through, so present clean form
+
+  $rrd = $ENV{"REQUEST_URI"}; # Location of rrd
+
+  $end = time(); # use now for end
+  $start = $end - 86400; # and go back 24 hours
+
+  # see rrdfetchnames
+  my ($begin,$step,$name,$data) = RRDs::fetch "$root$rrd","AVERAGE","--start","now","--end","start+1";
+  if ( my $ERR = RRDs::error) {
+    die "ERROR while fetching data from $NAME $ERR\n";
+  }
+  @names = @$name; # list of DS's "@$name"
+  $j = @names;
+  $esu = "";
+
+  for ($i = 0; $i < $j; $i++) { # All DS is included first time
+    @use[$i] = 1;
+    $esu .= "1";
+  }
+
+}
+
+# Create a form with clickable image see page xxx in: Wallace, Shawn P.
+# Programming Web Graphics with Perl
+# and GNU Software
+# O'Reilly UK,1999, UK, Paperback
+
+print "<FORM ACTION=\"$rrd\">\n";
+
+print "<TABLE border=\"0\">\n";
+print "<TR><TD colspan=\"3\" align=\"center\">Click on top to zoom out</TD></TR>\n";
+print "<TR><TD align=\"right\">Click<BR>left<BR>to<BR>go<BR>back<BR>in<BR>time</TD>";
+print "<TD>\n";
+# png.cgi prints the rrd graph, by printing to std.out (browser)
+print "<INPUT TYPE=\"image\" NAME=\"img\" SRC=\"/cgi-bin/png.cgi?rrd=$rrd&start=$start&end=$end&hight=$hight&width=$width&use=$esu\">\n";
+print "<INPUT TYPE=\"hidden\" NAME=\"start\" VALUE=\"$start\">\n";
+print "<INPUT TYPE=\"hidden\" NAME=\"end\" VALUE=\"$end\">\n";
+print "<INPUT TYPE=\"hidden\" NAME=\"rrd\" VALUE=\"$rrd\">\n";
+print "</TD>";
+print "<TD align=\"left\">Click<BR>right<BR>to<BR>go<BR>forward<BR>in<BR>time</TD></TR>\n";
+print "<TR><TD colspan=\"3\" align=\"center\">Click on bottom to zoom in</TD></TR>\n";
+print "</TABLE>\n";
+
+print "<BR><HR><BR><TABLE border=\"0\"></TD><TD>Select / Deselect DS: </TD>\n";
+for ($i = 0; $i < $j; $i++) { # present user with list of DS to select / deselect
+  if (@use[$i] == 0) {
+    print "<TD><INPUT TYPE=\"checkbox\" NAME=\"@names[$i]\" VALUE=1>@names[$i] </TD>\n";
+  } else {
+    print "<TD><INPUT TYPE=\"checkbox\" NAME=\"@names[$i]\" VALUE=1 CHECKED>@names[$i] </TD>\n";
+  }
+}
+print "</TR></TABLE>\n";
+
+print "</FORM>\n";
+
+print "<P ALIGN=\"RIGHT\">Created by - Claus Norrbohm - <A HREF=\"mailto:james\@type-this.com\">james\@type-this.com</A></P>";
+
+print $query->end_html(); # lmth ....

Modified: trunk/orca/packages/rrdtool-1.0.33/contrib/Makefile.am
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/Makefile.am	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/Makefile.am	Sat Jul 13 21:26:01 2002
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 
-SUBDIRS = log2rrd rrd-file-icon trytime rrdproc rrdlastds add_ds killspike rrdfetchnames
-
+SUBDIRS = trytime
 contribdir = $(prefix)/contrib
 contrib_DATA = README
+EXTRA_DIST =  rrdview log2rrd rrd-file-icon rrdproc rrdlastds add_ds killspike rrdfetchnames snmpstats rrdexplorer php3 php4

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php3/php3_rrdtool.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php3/php3_rrdtool.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php3/php3_rrdtool.c	Sat Jul 13 21:26:01 2002
@@ -0,0 +1,416 @@
+/*
+ *
+ * php3_rrdtool.c
+ *
+ *	PHP interface to RRD Tool.
+ *
+ *
+ *       Joey Miller, <joeym at inficad.com> 
+ *          SkyLynx / Inficad Communications
+ *          2/12/2000
+ *
+ *
+ * See README, INSTALL, and USAGE files for more details.
+ *
+ */
+
+#include "dl/phpdl.h"
+#include "rrd_tool.h"
+#include "php3_rrdtool.h"
+
+
+/* {{{ proto string rrd_error(void)
+   Get the error message set by the last rrd tool function call */
+
+void php3_rrd_error(INTERNAL_FUNCTION_PARAMETERS)
+{
+    char *msg;
+
+    if ( rrd_test_error() )
+    {
+        msg = rrd_get_error();        
+
+        RETVAL_STRING(msg, 1);
+        rrd_clear_error();
+    }
+    else
+        return;
+}
+/* }}} */
+
+
+
+/* {{{ proto void rrd_clear_error(void)
+   Clear the error set by the last rrd tool function call */
+
+void php3_rrd_clear_error(INTERNAL_FUNCTION_PARAMETERS)
+{
+    if ( rrd_test_error() )
+        rrd_clear_error();
+
+    return;
+}
+/* }}} */
+
+
+
+/* {{{ proto int rrd_update(string file, string opt) 
+   Update an RRD file with values specified */
+
+void php3_rrd_update(INTERNAL_FUNCTION_PARAMETERS)
+{
+    pval *file, *opt;
+    char **argv;
+
+    if ( rrd_test_error() )
+        rrd_clear_error();
+
+    if ( ARG_COUNT(ht) == 2 && 
+         getParameters(ht, 2, &file, &opt) == SUCCESS )
+    {
+        convert_to_string(file);
+        convert_to_string(opt);
+
+        argv = (char **) emalloc(4 * sizeof(char *));
+
+        argv[0] = "dummy";
+        argv[1] = estrdup("update");
+        argv[2] = estrdup(file->value.str.val);
+        argv[3] = estrdup(opt->value.str.val);
+
+        optind = 0; opterr = 0;
+        if ( rrd_update(3, &argv[1]) != -1 )
+        {
+            RETVAL_TRUE;
+        }
+        else
+        {
+            RETVAL_FALSE;
+        }
+        efree(argv[1]); efree(argv[2]); efree(argv[3]);
+        efree(argv);
+    }
+    else
+    {
+        WRONG_PARAM_COUNT;
+    }
+    return;
+}
+/* }}} */
+
+
+
+/* {{{ proto int rrd_last(string file)
+   Gets last update time of an RRD file */
+
+void php3_rrd_last(INTERNAL_FUNCTION_PARAMETERS)
+{
+    pval *file;
+    unsigned long retval;
+
+    char **argv = (char **) emalloc(3 * sizeof(char *));
+    
+    if ( rrd_test_error() )
+        rrd_clear_error();
+    
+    if (getParameters(ht, 1, &file) == SUCCESS)
+    {
+        convert_to_string(file);
+
+        argv[0] = "dummy";
+        argv[1] = estrdup("last");
+        argv[2] = estrdup(file->value.str.val);
+
+        optind = 0; opterr = 0;
+        retval = rrd_last(2, &argv[1]);
+
+        efree(argv[1]);  efree(argv[2]);
+        efree(argv);
+        RETVAL_LONG(retval);
+    }
+    else
+    {
+        WRONG_PARAM_COUNT;
+    }
+    return;
+}
+/* }}} */
+
+
+/* {{{ proto int rrd_create(string file, array args_arr, int argc)
+   Create an RRD file with the options passed (passed via array) */ 
+
+void php3_rrd_create(INTERNAL_FUNCTION_PARAMETERS)
+{
+    pval *file, *args_arr, *p_argc;
+    pval *entry;
+    char **argv;
+    int argc, i;
+
+    if ( rrd_test_error() )
+        rrd_clear_error();
+
+    if ( ARG_COUNT(ht) == 3 && getParameters(ht, 3, &file, &args_arr, &p_argc) == SUCCESS )
+    {
+        if ( args_arr->type != IS_ARRAY )
+        { 
+            php3_error(E_WARNING, "2nd Variable passed to rrd_create is not an array!\n");
+            RETURN_FALSE;
+        }
+
+        convert_to_long(p_argc);
+        convert_to_string(file);
+
+        argc = p_argc->value.lval + 3;
+        argv = (char **) emalloc(argc * sizeof(char *));
+
+        argv[0] = "dummy";
+        argv[1] = estrdup("create");
+        argv[2] = estrdup(file->value.str.val);
+
+        for (i = 3; i < argc; i++) 
+        {
+            if ( _php3_hash_get_current_data(args_arr->value.ht, (void **) &entry) == FAILURE )
+                continue;
+
+            if ( entry->type != IS_STRING )
+                convert_to_string(entry);
+
+            argv[i] = estrdup(entry->value.str.val);
+
+            if ( i < argc )
+                _php3_hash_move_forward(args_arr->value.ht);
+        }
+  
+        optind = 0;  opterr = 0;
+
+        if ( rrd_create(argc-1, &argv[1]) != -1 )
+        {
+            RETVAL_TRUE;
+        }
+        else
+        {
+            RETVAL_FALSE;
+        }
+        for (i = 1; i < argc; i++)
+            efree(argv[i]);
+
+        efree(argv);
+    }
+    else
+    {
+        WRONG_PARAM_COUNT;
+    }
+    return;
+}
+/* }}} */
+
+
+
+/* {{{ proto mixed rrd_graph(string file, array args_arr, int argc)
+   Creates a graph based on options passed via an array */
+
+void php3_rrd_graph(INTERNAL_FUNCTION_PARAMETERS)
+{
+    pval *file, *args_arr, *p_argc;
+    pval *entry, p_calcpr;
+    int i, xsize, ysize, argc;
+    char **argv, **calcpr;
+    
+    if ( rrd_test_error() )
+        rrd_clear_error();
+    
+    if ( ARG_COUNT(ht) == 3 && 
+         getParameters(ht, 3, &file, &args_arr, &p_argc) == SUCCESS)
+    {
+        if ( args_arr->type != IS_ARRAY )
+        { 
+            php3_error(E_WARNING, "2nd Variable passed to rrd_graph is not an array!\n");
+            RETURN_FALSE;
+        }
+        
+        convert_to_long(p_argc);
+        convert_to_string(file);
+
+        argc = p_argc->value.lval + 3;
+        argv = (char **) emalloc(argc * sizeof(char *));
+ 
+        argv[0] = "dummy";
+        argv[1] = estrdup("graph");
+        argv[2] = estrdup(file->value.str.val);
+
+        for (i = 3; i < argc; i++) 
+        {
+            if ( _php3_hash_get_current_data(args_arr->value.ht, (void **) &entry) == FAILURE 
+                 || entry->type != IS_STRING )
+            {  
+                continue;
+            }
+            argv[i] = estrdup(entry->value.str.val);
+
+            if ( i < argc )
+                _php3_hash_move_forward(args_arr->value.ht);
+        }
+   
+        optind = 0; opterr = 0; 
+        if ( rrd_graph(argc-1, &argv[1], &calcpr, &xsize, &ysize) != -1 )
+        {
+            array_init(return_value);
+            add_assoc_long(return_value, "xsize", xsize);
+            add_assoc_long(return_value, "ysize", ysize);
+
+            array_init(&p_calcpr);
+    
+            if (calcpr)
+            {
+                for (i = 0; calcpr[i]; i++)
+                {
+                    add_next_index_string(&p_calcpr, calcpr[i], 1);
+                    free(calcpr[i]);
+                }
+                free(calcpr);
+            }
+            _php3_hash_update(return_value->value.ht, "calcpr", sizeof("calcpr"), 
+                              &p_calcpr, sizeof(pval), NULL);
+        }
+        else
+        {
+            RETVAL_FALSE;
+        }
+        for (i = 1; i < argc; i++)
+            efree(argv[i]);
+
+        efree(argv);
+    }
+    else
+    { 
+        WRONG_PARAM_COUNT;
+    }
+    return;
+}
+/* }}} */
+
+
+
+/* {{{ proto mixed rrd_fetch(string file, array args_arr, int p_argc)
+   Fetch info from an RRD file */
+
+void php3_rrd_fetch(INTERNAL_FUNCTION_PARAMETERS)
+{
+    pval *file, *args_arr, *p_argc;
+    pval *entry;
+    pval *p_start, *p_end, *p_step, *p_ds_cnt, p_ds_namv, p_data;
+    int i, argc;
+    time_t start, end;
+    unsigned long step, ds_cnt;
+    char **argv, **ds_namv; 
+    rrd_value_t *data, *datap;
+    
+    if ( rrd_test_error() )
+        rrd_clear_error();
+    
+    if ( ARG_COUNT(ht) == 3 && 
+         getParameters(ht, 3, &file, &args_arr, &p_argc) == SUCCESS)
+    {
+        if ( args_arr->type != IS_ARRAY )
+        { 
+            php3_error(E_WARNING, "2nd Variable passed to rrd_fetch is not an array!\n");
+            RETURN_FALSE;
+        }
+        
+        convert_to_long(p_argc);
+        convert_to_string(file);
+
+        argc = p_argc->value.lval + 3;
+        argv = (char **) emalloc(argc * sizeof(char *));
+ 
+        argv[0] = "dummy";
+        argv[1] = estrdup("fetch");
+        argv[2] = estrdup(file->value.str.val);
+
+        for (i = 3; i < argc; i++) 
+        {
+            if ( _php3_hash_get_current_data(args_arr->value.ht, (void **) &entry) == FAILURE 
+                 || entry->type != IS_STRING )
+            {  
+                continue;
+            }
+            argv[i] = estrdup(entry->value.str.val);
+
+            if ( i < argc )
+                _php3_hash_move_forward(args_arr->value.ht);
+        }
+  
+        optind = 0; opterr = 0; 
+
+        if ( rrd_fetch(argc-1, &argv[1], &start,&end,&step,&ds_cnt,&ds_namv,&data) != -1 )
+        {
+            array_init(return_value);
+            add_assoc_long(return_value, "start", start);
+            add_assoc_long(return_value, "end", end);
+            add_assoc_long(return_value, "step", step);
+            add_assoc_long(return_value, "ds_cnt", ds_cnt);
+
+            array_init(&p_ds_namv);
+            array_init(&p_data);
+   
+            if (ds_namv)
+            {
+                for (i = 0; i < ds_cnt; i++)
+                {
+                    add_next_index_string(&p_ds_namv, ds_namv[i], 1);
+                    free(ds_namv[i]);
+                }
+                free(ds_namv);
+            }
+
+            if (data)
+            {
+                datap = data;
+ 
+                for (i = start; i <= end; i += step)
+                    add_next_index_double(&p_data, *(datap++));
+ 
+                free(data);
+            }
+
+            _php3_hash_update(return_value->value.ht, "ds_namv", sizeof("ds_namv"), 
+                              &p_ds_namv, sizeof(pval), NULL);
+            _php3_hash_update(return_value->value.ht, "data", sizeof("data"), 
+                              &p_data, sizeof(pval), NULL);
+        }
+        else
+        {
+            RETVAL_FALSE;
+        }
+        for (i = 1; i < argc; i++)
+            efree(argv[i]);
+
+        efree(argv);
+    }
+    else
+    { 
+        WRONG_PARAM_COUNT;
+    }
+    return;
+}
+/* }}} */
+
+
+function_entry rrdtool_functions[] = {
+        {"rrd_error", php3_rrd_error, NULL},
+        {"rrd_clear_error", php3_rrd_clear_error, NULL},
+	{"rrd_graph", php3_rrd_graph, NULL},
+	{"rrd_last", php3_rrd_last, NULL},
+	{"rrd_fetch", php3_rrd_fetch, NULL},
+        {"rrd_update", php3_rrd_update, NULL},
+        {"rrd_create", php3_rrd_create, NULL},
+	{NULL, NULL, NULL}
+};
+
+
+php3_module_entry rrdtool_module_entry = {
+	"RRDTool", rrdtool_functions, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, NULL
+};
+
+php3_module_entry *get_module(void) { return &rrdtool_module_entry; }

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php3/USAGE
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php3/USAGE	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php3/USAGE	Sat Jul 13 21:26:01 2002
@@ -0,0 +1,156 @@
+--------------------------------------------------
+Usage:
+
+
+  To use the 'php3_rrdtool.so' module, you need to load it in your
+PHP script before you call any of the rrd_* functions.
+
+This can be achieved with a simple command:
+
+    <?   dl("/path/to/php3_rrdtool.so");  ?>
+
+After this is loaded, you have access to all the rrd_* commands 
+contained in 'php3_rrdtool.so'.
+
+
+
+API:
+
+--------------------------------------------------------------------
+string rrd_error()
+
+	rrd_error takes no arguments.
+
+	Use this function to retrieve the error message from
+the last rrd_* function that was called and failed.
+
+	If an error was set, a string will be returned.  
+
+	If no error was set, a blank string will be returned.
+
+
+
+
+--------------------------------------------------------------------
+int rrd_last(string filename)
+
+	rrd_last takes only one argument, a filename of an RRD
+file.  
+
+	If rrd_last is successful in obtaining the last modifiation
+time of the file, a date will be returned in the form of the
+number of seconds from the unix epoch (Jan 1, 1970, 00:00:00).
+You can then use any of php's excellent time functions on this
+value.
+
+	If rrd_last is not sucessful, a value of 0 will be returned,
+and the internal rrd error will be set.  You can access this error
+message via the rrd_error() function (if one was set).
+ 
+
+--------------------------------------------------------------------
+int rrd_update(string filename, string options)
+
+	rrd_update takes 2 arguments, a filename of an RRD file
+and a string with options to fill the RRD file with.
+
+	It has been designed to work similary to the rrd_update
+call in the RRDs perl library.
+
+Example:  $result = rrd_update("/some.rrd", "N:123:9873:235");
+ 
+	If rrd_update is successful, 1 is returned. 
+
+	If rrd_update is not successful, 0 is returned, and an
+error message should be obtainable by called 'rrd_error()'.
+
+
+--------------------------------------------------------------------
+int rrd_create(string filename, array options, int num_of_elements)
+
+	rrd_create takes 3 arguments, a filename of an RRD file to
+create, an array of options (exactly like you would pass in the RRDs 
+perl library, or on the command line to 'rrdtool'), and the last 
+argument is the number of elements in the array of options.  This 
+can be obtained by simply calling " count($opt_array) ".  See the 
+example scripts for a more clear example.
+
+	If rrd_update is successful, 1 is returned. 
+
+	If rrd_update is not successful, 0 is returned, and an
+error message should be obtainable by called 'rrd_error()'.
+
+
+
+--------------------------------------------------------------------
+mixed rrd_graph(string filename, array options, int num_of_elements) 
+
+	rrd_graph takes 3 arguments, a filename of an RRD file,
+an array of options (exactly like you would pass in the RRDs perl
+library, or on the command line to 'rrdtool'), and the last argument
+is the number of elements in the array of options.  This can be 
+obtained by simply calling " count($opt_array) ".  See the example
+scripts for a more clear example.
+
+
+	If rrd_graph is successful, an array is returned.  The
+array is an associate array with 3 values:
+
+$array[xsize]  -  The size of the image along the X axis.
+$array[ysize]  -  The size of the image along the Y axis.
+$array[calcpr] -  This is actually another array, that will contain
+                  the results of any PRINT statements.
+
+
+	If rrd_graph is not successful, a 0 is returned.
+
+IMPORTANT NOTE:  In order for php not to complain about mis-using
+the return value, it is important that you check the type of the
+return value.  use the " is_array() " function to check if the 
+returned value is an array (in which case rrd_graph was successful),
+or not an array (meaning rrd_graph was NOT successful).  See the
+examples for an illustration of this.
+
+
+--------------------------------------------------------------------
+mixed rrd_fetch(string filename, array options, int num_of_elements) 
+
+	rrd_fetch takes 3 arguments, a filename of an RRD file,
+an array of options (exactly like you would pass in the RRDs perl
+library, or on the command line to 'rrdtool'), and the last argument
+is the number of elements in the array of options.  This can be 
+obtained by simply calling " count($opt_array) ".  See the example
+scripts for a more clear example.
+
+
+	If rrd_fetch is successful, an array is returned.  The
+array is an associate array with 5 values:
+
+$array[start]   -  This is the start time of the data returned 
+                   (unix epoch timestamp format)
+$array[end]     -  This is the end time of the data returned
+                   (unix epoch timestamp format)
+$array[step]    -  This is the step interval of the data returned,
+                   in number of seconds.
+$array[ds_cnt]  -  This is the number of DS's returned from the
+                   RRD file.
+$array[ds_namv] -  This is an array with the names of the DS's
+                   returned from the RRD file.
+$array[data]    -  This is an array with all the values fetch'd
+                   from the rrd file by rrd_fetch.
+
+(This is very similar to the way rrd_fetch() in the RRDs
+perl library works, as well as the C function rrd_fetch()).
+
+	If rrd_fetch is not successful, a 0 is returned.
+
+IMPORTANT NOTE:  In order for php not to complain about mis-using
+the return value, it is important that you check the type of the
+return value.  use the " is_array() " function to check if the 
+returned value is an array (in which case rrd_fetch was successful),
+or not an array (meaning rrd_fetch was NOT successful).  See the
+examples for an illustration of this.
+
+
+--------------------------------------------------------------------
+

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php3/VERSION
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php3/VERSION	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php3/VERSION	Sat Jul 13 21:26:02 2002
@@ -0,0 +1 @@
+0.9.0

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php3/php3_rrdtool.h
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php3/php3_rrdtool.h	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php3/php3_rrdtool.h	Sat Jul 13 21:26:02 2002
@@ -0,0 +1,31 @@
+#ifndef _PHP3_RRDTOOL_H
+#define _PHP3_RRDTOOL_H
+
+#if COMPILE_DL
+#undef HAVE_RRDTOOL
+#define HAVE_RRDTOOL 1
+#endif
+#ifndef DLEXPORT
+#define DLEXPORT
+#endif
+
+#if HAVE_RRDTOOL
+
+extern php3_module_entry rrdtool_module_entry;
+#define snmp_module_ptr &rrdtool_module_entry
+
+extern DLEXPORT void php3_rrd_error(INTERNAL_FUNCTION_PARAMETERS);
+extern DLEXPORT void php3_rrd_clear_error(INTERNAL_FUNCTION_PARAMETERS);
+extern DLEXPORT void php3_rrd_update(INTERNAL_FUNCTION_PARAMETERS);
+extern DLEXPORT void php3_rrd_last(INTERNAL_FUNCTION_PARAMETERS);
+extern DLEXPORT void php3_rrd_create(INTERNAL_FUNCTION_PARAMETERS);
+extern DLEXPORT void php3_rrd_graph(INTERNAL_FUNCTION_PARAMETERS);
+extern DLEXPORT void php3_rrd_fetch(INTERNAL_FUNCTION_PARAMETERS);
+
+#else
+
+#define rrdtool_module_ptr NULL
+
+#endif /* HAVE_RRDTOOL */
+
+#endif  /* _PHP3_RRDTOOL_H */

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php3/INSTALL
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php3/INSTALL	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php3/INSTALL	Sat Jul 13 21:26:02 2002
@@ -0,0 +1,16 @@
+Installation:
+
+  You'll want to have the following sources available somewhere:
+        php
+        rrdtool
+        apache (if you built php as a DSO)
+
+  Edit the *INCLUDE and *LIB variables in the Makefile to indicate
+the correct locations for your files.
+
+  After php3_rrdtool.so builds correctly, copy this file to wherever
+you'd like.  Possibly APACHE_ROOT/libexec/ .
+
+
+
+After you install, you should probably read README and API.

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php3/Makefile
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php3/Makefile	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php3/Makefile	Sat Jul 13 21:26:02 2002
@@ -0,0 +1,72 @@
+# code by Joey Miller <joeym at inficad.com>
+#
+#
+# BEFORE COMPILING YOU MUST SET THE VARIABLES BELOW
+# TO INDICATE THE CORRECT DIRECTORIES!!!!!!!!!!!!!!!!!!!!!
+#
+#
+# USE AT YOUR OWN RISK!
+#
+
+## begin configurable vars
+
+## PHPINCLUDE -- the directory where php is untarred
+##
+PHPINCLUDE =  -I/usr/home/joeym/apache_build/php-3.0.14
+
+## PHPLIBS -- the directory where you can find some of the PHP objects
+## and compiled libs (the directory where php is untarred, and
+## has already been compiled!
+##
+PHPLIBS    =  /usr/home/joeym/apache_build/php-3.0.14
+
+## RRDINCLUDE, GDINCLUDE -- where to find some of the header
+## files needed by rrdtool and it's libs
+##
+RRDINCLUDE =  -I/usr/home/joeym/newshit/rrdtool-1.0.10/src
+GDINCLUDE  =  -I/usr/home/joeym/newshit/rrdtool-1.0.10/gd1.3
+
+## RRDLIB -- where to find librrd.a (usually /usr/local/rrdtool-1.0.10/lib)
+RRDLIB	   =	/usr/local/rrdtool-1.0.10/lib
+
+#
+# if php is compiled as an apache module
+#
+APACHEINC = -I/var/www/include
+
+
+
+###### end primary config vars  .. change the vars below only
+###### if you need to
+######
+
+
+
+
+CFLAGS	= -O -fpic
+CC	= gcc
+
+CXX	= g++
+CXXFLAGS= $(CFLAGS)
+
+LD	= cc
+LDFLAGS	= -shared
+
+RM	= /bin/rm
+
+OBJS    =  php3_rrdtool.o
+CFLAGS	:= $(CFLAGS) -I../lib $(PHPINCLUDE) $(APACHEINC) $(RRDINCLUDE) $(GDINCLUDE)
+CXXFLAGS:= $(CXXFLAGS) -I../lib $(PHPINCLUDE) $(APACHEINC) $(RRDINCLUDE) $(GDINCLUDE)
+LIBS	:= -L$(RRDLIB) -L$(PHPLIBS) -lrrd 
+
+all: php3_rrdtool.so
+
+php3_rrdtool.so: $(OBJS)
+	$(LD) $(LDFLAGS) $(OBJS) -o $@ $(LIBS)
+
+clean:
+	$(RM) *.o
+	$(RM) *.so
+	
+veryclean: clean
+	$(RM) *~

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php3/README
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php3/README	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php3/README	Sat Jul 13 21:26:02 2002
@@ -0,0 +1,43 @@
+
+PHP bindings for RRD Tool.
+
+	Contained herein are bindings to allow you to interface
+php scripts with RRD tool directly via RRD tool's 'librrd' library,
+thus avoiding the need to use system() calls to the rrdtool binary.
+
+	RRD Tool is an AMAZING package of tools to faciliate
+the easy storage, retrieval, and graphing of statistics (usually
+but not limited to bit/byte counts from routers, switches, and 
+hubs).  It was written by the author of MRTG, Tobias Oetiker
+(oetiker at ee.ethz.ch).  The primary web site for RRD Tool is:
+http://www.caida.org/Tools/RRDtool
+
+
+Reason I wrote this:  Wanted to use PHP to create fairly real-time / 
+dynamic web pages w/ RRD tool, but the only way was to use system()
+and popen() with PHP, since there was no direct interface to RRD
+Tool from PHP.  The fork()ing would have been slow and tedious
+so that was pretty much out of the question.  I could have used the 
+Perl library (RRDs) to interface ePerl, or mod_perl, or even 
+'rrdcgi', but I didn't really want to.  I wanted to use PHP and
+there was nothing to change my mind.
+
+
+You are free to redistribute the source provided my name is
+kept at the top of the source files as credit for the original
+author.  I make no warranties to the usability of this software,
+nor I am responsible if your machine explodes (although it 
+shouldn't).
+
+
+BUGS:
+     There might be some.  Let me know: joeym at inficad.com.  
+Patches to fix bugs you find are more welcome than simple
+reports of bugs (I don't have a lot of time to maintain
+this code).
+
+
+http://netmon.inficad.com/php3_rrdtool/
+
+Joey Miller, <joeym at inficad.com>, SkyLynx / Inficad Communications,
+2/12/2000

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_update.php
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_update.php	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_update.php	Sat Jul 13 21:26:03 2002
@@ -0,0 +1,19 @@
+<?
+
+ dl("/tmp/php3_rrdtool.so");
+
+ ##
+ ## demonstration of the rrd_update() command
+ ##
+
+  $ret = rrd_update("/some/file.rrd", "N:1245:98344");
+
+  if ( $ret == -1 )
+  {
+      $err = rrd_error();
+      echo "ERROR occurred: $err\n";
+  }
+ /* else rrd_update() was successful */
+
+
+?>

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_last.php
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_last.php	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_last.php	Sat Jul 13 21:26:03 2002
@@ -0,0 +1,22 @@
+<?
+
+ dl("/tmp/php3_rrdtool.so");
+
+ ##
+ ## demonstration of the rrd_last() command
+ ##
+
+ $ret = rrd_last("/some/path/some-router-fe2.rrd");
+
+ if ( $ret != - 1 )
+ {
+     printf("Last update time:  %s\n", strftime("%m/%d/%Y %H:%M:%S");
+ }
+ else
+ {
+     $err_msg = rrd_error();
+     echo "Error occurred:  $err_msg\n";
+ }
+
+
+?>

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_create.php
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_create.php	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_create.php	Sat Jul 13 21:26:03 2002
@@ -0,0 +1,27 @@
+<?
+
+ dl("/tmp/php3_rrdtool.so");
+
+ ##
+ ## demonstration of the rrd_create() command
+ ##
+
+  $_opts = array( "--step", "300", "--start", 0,
+                 "DS:input:COUNTER:900:0:U",
+                 "DS:output:COUNTER:900:0:U",
+                 "RRA:AVERAGE:0.5:1:1000",
+                 "RRA:MIN:0.5:1:1000",
+                 "RRA:MAX:0.5:1:1000"
+               );
+
+  $ret = rrd_create("/tmp/test.rrd", $_opts, count($_opts));
+
+  if ( $ret == -1 )
+  {
+      $err = rrd_error();
+      echo "Create error: $err\n";
+  }
+  /*  else rrd_create was successful  */
+
+
+?>

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_fetch.php
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_fetch.php	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_fetch.php	Sat Jul 13 21:26:03 2002
@@ -0,0 +1,51 @@
+<?
+
+ dl("/tmp/php3_rrdtool.so");
+
+ ##
+ ## demonstration of the rrd_fetch() command
+ ##
+
+
+
+  $opts = array ( "AVERAGE", "--start", "-1h" );
+
+  $ret = rrd_fetch("/dir/router-port2.rrd", $opts, count($opts));
+ 
+  ##
+  ## if $ret is an array, rrd_fetch() succeeded
+  ## 
+  if ( is_array($ret) )
+  {
+      echo "Start time    (epoch): $ret[start]\n";
+      echo "End time      (epoch): $ret[end]\n";
+      echo "Step interval (epoch): $ret[step]\n";
+
+      ##
+      ## names of the DS's (data sources) will be 
+      ## contained in the array $ret[ds_namv][..]
+      ##
+      for($i = 0; $i < count($ret[ds_namv]); $i++)
+      {
+          $tmp = $ret[ds_namv][$i];
+          echo "$tmp \n";
+      }
+
+      ##
+      ## all data will be packed into the
+      ## $ret[data][..]  array
+      ##
+      for($i = 0; $i < count($ret[data]); $i++)
+      {
+          $tmp = $ret[data][$i];
+          echo "$hi\n";
+      }
+  }
+  else
+  {
+      $err = rrd_error();
+      echo "fetch() ERROR: $err\n";
+  }
+
+
+?>

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_graph.php
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_graph.php	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php3/examples/rrd_graph.php	Sat Jul 13 21:26:03 2002
@@ -0,0 +1,43 @@
+<?
+
+ dl("/tmp/php3_rrdtool.so");
+
+ ##
+ ## demonstration of the rrd_graph() command
+ ##
+
+   $opts = array( "--start", "-4d", 
+                  "DEF:in=/dir/router-port2.rrd:input:AVERAGE",
+                  "DEF:out=/dir/router-port2.rrd:output:AVERAGE",
+                  "LINE2:in#0000ff:Incoming Traffic Avg.",
+                  "PRINT:in:AVERAGE:incoming\: %1.2lf b/s",
+                  "PRINT:in:AVERAGE:incoming2\: %1.2lf b/s"
+                );
+
+
+   $ret = rrd_graph("/some-dir/router-port2.gif", $opts, count($opts));
+
+   ##
+   ## if $ret is an array, then rrd_graph was successful
+   ##
+   if ( is_array($ret) )
+   {
+       echo "Image size:  $ret[xsize] x $ret[ysize]\n";
+       
+
+       ##
+       ## all results from any PRINT commands will be
+       ## in the array $ret[calcpr][..]
+       ##
+       echo "rrd_graph1 print results: \n";
+
+       for ($i = 0; $i < count($ret[calcpr]); $i++)
+           echo $ret[calcpr][$i] . "\n";
+   }
+   else
+   {
+       $err = rrd_error();
+       echo "rrd_graph() ERROR: $err\n";
+   }
+
+?>

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/log2rrd/log2rrd.pl
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/log2rrd/log2rrd.pl	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/log2rrd/log2rrd.pl	Sat Jul 13 21:26:04 2002
@@ -0,0 +1,231 @@
+#! /usr/sepp/bin/perl
+#
+# Log 2 RRD.  This script translates a MRTG 2.x log file
+# into a RRD archive.  The original version was written by
+# Wrolf Courtney <wrolf at concentric.net> and
+# Russ Wright <wright at LBL.Gov> with an early test version
+# of RRDTOOL (mrtg-19980526.08) and has been modified to match
+# the parameters of rrdtool version 99.23 by Alan Lichty at
+# Electric Lightwave, Inc. <alichty at eli.net>.
+#
+# this script optimized for being called up by another script
+# that cycles through a list of routers and invokes this for each
+# interface.  It can be run just as easily from a command line for
+# small numbers of logfiles.
+#
+# The RRD we create looks like the following:  Note
+# that we have to use type GAUGE in order to have RRDTOOL
+# populate the new rr archive correctly.  Otherwise RRDTOOL will try 
+# to interpet the data as new octet counts instead of existing
+# data rate averages.
+#
+# DS:GAUGE:86400:U:U	        # in counter
+# DS:GAUGE:86400:U:U	        # out counter
+# RRA:AVERAGE:0.5:1:600	        # 5 minute samples
+# RRA:MAX:0.5:1:600		# 5 minute samples
+# RRA:AVERAGE:0.5:6:600	        # 30 minute samples
+# RRA:MAX:0.5:6:600		# 30 minute samples
+# RRA:AVERAGE:0.5:24:600	        # 2 hour samples
+# RRA:MAX:0.5:24:600		# 2 hour samples
+# RRA:AVERAGE:0.5:288:732	# 1 day samples
+# RRA:MAX:0.5:288:732            # 1 day samples
+#
+# 
+
+use English;
+use strict;
+
+require "ctime.pl";
+
+use RRDs;
+
+my $DEBUG=0;
+
+&main;
+
+sub main {
+
+    my($inBytes, $outBytes);
+    my($lastRunDate, $firstRunDate);
+    my($i, $dataFile, $firstRun);
+    my($oldestRun, $lastRun);
+    my($curTime, $oldestTime, $totRec);
+    my($avgIn, $avgOut, $maxIn, $maxOut);
+    my(@lines, @finalRecs);
+    my($RRD, $START, $destDir, $dsType);
+
+#
+# get the logfile name to process
+# the default is to strip out the .log extension and create
+# a new file with the extension .rrd
+#
+
+    $dataFile=$ARGV[0];
+
+    $destDir = $ARGV[1];
+
+#
+# strip off .log from file name - complain and die if no .log
+# in the filename
+#
+
+    if ($dataFile =~ /(.*)\.log$/) {
+	$RRD = "$1";
+    }
+
+    if ($RRD eq "") {
+	printf("Usage: log2rrd [log file] [destination dir]\n");
+	exit;
+    }
+
+#
+# strip out path info (if present) to get at just the filename
+#
+
+    if ($RRD =~ /(.*)\/(.*)$/){
+	$RRD = "$2";
+    }
+
+#
+# add the destination path (if present) and .rrd suffix
+#
+
+    if ($destDir){
+	$RRD = "$destDir/$RRD.rrd";
+
+    }else{
+	$RRD = "$RRD.rrd";
+    }
+
+    open(IN,"$dataFile") || die ("Couldn't open $dataFile");
+
+#
+# Get first line - has most current sample
+#
+
+    $_ = <IN>;
+    chop;
+    ($lastRun, $inBytes, $outBytes) = split;
+    $lastRunDate = &ctime($lastRun);
+    chop $lastRunDate;
+
+    $firstRun = $lastRun;
+    $i=2;
+
+#
+# start w/line 2 and read them into the lines array
+# (2nd line is in position 2)
+#
+    while (<IN>) {
+	chop;
+	$lines[$i++] = $_;
+	($curTime) = split;
+	if ($curTime < $firstRun) {
+	    $firstRun = $curTime;
+	}
+    }
+    close(IN);
+
+#
+#  Let's say source start time is 5 minutes before 1st sample
+#
+
+    $START=$firstRun - 300;
+    print STDERR "\$START = $START\n" if $DEBUG>1;
+
+    $firstRunDate = &ctime($firstRun);
+    chop $firstRunDate;
+
+    printf("Data from $firstRunDate\n       to $lastRunDate\n") if $DEBUG>0;
+
+    $oldestTime=$lastRun;
+#
+# OK- sort through the data and put it in a new array.
+# This gives us a chance to find errors in the log files and
+# handles any overlap of data (there shouldn't be any)
+#
+# NOTE: We start w/ record # 3, not #2 since #2 could be partial
+#
+
+    for ($i=3; $i <= 2533; $i++) {
+
+	($curTime, $avgIn, $avgOut, $maxIn, $maxOut) = split(/\s+/, $lines[$i]);
+
+	if ($curTime < $oldestTime) {
+
+#
+# only add data if older than anything already in array
+# this should always be true, just checking
+#
+
+	    $oldestTime = $curTime;
+	    $finalRecs[$totRec++]=$lines[$i];
+	}
+    }
+
+
+    PopulateRRD($totRec, $RRD, $START, \@finalRecs);
+
+#
+# if you know that most of your MRTG logfiles are using
+# counter data, uncomment the following lines to automatically
+# run rrdtune and change the data type.
+#
+#    my(@tuneparams) = ("$RRD", "-d", "ds0:COUNTER", "-d", "ds1:COUNTER");
+#    RRDs::tune(@tuneparams);
+
+
+}
+
+sub PopulateRRD {
+
+    my($totRec, $RRD, $START, $finalRecs) = @_;
+    my($i, $curTime, $avgIn, $avgOut, $maxIn, $maxOut);
+    my($saveReal, $line);
+    my($createret, $updret);
+
+    print "* Creating RRD $RRD\n\n" if $DEBUG>0;
+
+#
+# We'll create RRAs for both AVG and MAX. MAX isn't currently filled but 
+# may be later
+#
+
+    RRDs::create ("$RRD", "-b", $START, "-s", 300,
+    "DS:ds0:GAUGE:86400:U:U",
+    "DS:ds1:GAUGE:86400:U:U",
+    "RRA:AVERAGE:0.5:1:600",
+    "RRA:MAX:0.5:1:600",
+    "RRA:AVERAGE:0.5:6:600",
+    "RRA:MAX:0.5:6:600",
+    "RRA:AVERAGE:0.5:24:600",
+    "RRA:MAX:0.5:24:600",
+    "RRA:AVERAGE:0.5:288:600",
+    "RRA:MAX:0.5:288:600");
+
+    if (my $error = RRDs::error()) {
+	print "Cannot create $RRD: $error\n";
+    }
+
+
+    print "* Adding entries to $RRD\n\n" if $DEBUG>0;
+
+    for ($i=$totRec - 1; $i >= 0; $i--) {
+
+	($curTime, $avgIn, $avgOut, $maxIn, $maxOut) = split(/\s+/, @$finalRecs[$i]);
+
+        RRDs::update ("$RRD", "$curTime:$avgIn:$avgOut");
+
+	if (my $error = RRDs::error()) {
+	    print "Cannot update $RRD: $error\n";
+	}
+
+  
+# NOTE: Need to add checking on RRDread and include the Max values
+# print status every now and then
+#	print $i if $i % 25 && $DEBUG>0;
+#	print "$i\n";
+
+    }
+
+}

Deleted: trunk/orca/packages/rrdtool-1.0.33/contrib/log2rrd/Makefile.in

Deleted: trunk/orca/packages/rrdtool-1.0.33/contrib/log2rrd/Makefile.am

Deleted: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdproc/Makefile.in

Deleted: trunk/orca/packages/rrdtool-1.0.33/contrib/rrdproc/Makefile.am

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/mkinstalldirs
==============================================================================

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/configure
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/configure	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/configure	Sat Jul 13 21:26:05 2002
@@ -0,0 +1,2281 @@
+#! /bin/sh
+
+
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST EXT_STATIC"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST EXT_SHARED"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST EXT_LIBS"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST EXT_LTLIBS"
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# serial 40 AC_PROG_LIBTOOL
+
+
+
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+
+
+
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+
+
+# AC_CHECK_LIBM - check for math library
+
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+
+
+
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+  --with-php-config=[PATH]"
+ac_default_prefix=
+ac_help="$ac_help
+  --with-rrdtool[=DIR]      Include RRDTool support.  DIR is the rrdtool
+                          install directory."
+ac_help="$ac_help
+  --enable-shared[=PKGS]  build shared libraries [default=yes]"
+ac_help="$ac_help
+  --enable-static[=PKGS]  build static libraries [default=yes]"
+ac_help="$ac_help
+  --enable-fast-install[=PKGS]  optimize for fast installation [default=yes]"
+ac_help="$ac_help
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+  --disable-libtool-lock  avoid locking (might break parallel builds)"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=Makefile.in
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi at caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='	'
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+
+abs_srcdir=`(cd $srcdir && pwd)`
+
+php_always_shared=yes
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:662: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:692: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:743: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:775: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 786 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:791: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:817: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:822: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:831: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:850: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+if test "x$CC" != xcc; then
+  echo $ac_n "checking whether $CC and cc understand -c and -o together""... $ac_c" 1>&6
+echo "configure:883: checking whether $CC and cc understand -c and -o together" >&5
+else
+  echo $ac_n "checking whether cc understands -c and -o together""... $ac_c" 1>&6
+echo "configure:886: checking whether cc understands -c and -o together" >&5
+fi
+set dummy $CC; ac_cc="`echo $2 |
+		       sed -e 's/[^a-zA-Z0-9_]/_/g' -e 's/^[0-9]/_/'`"
+if eval "test \"`echo '$''{'ac_cv_prog_cc_${ac_cc}_c_o'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'foo(){}' > conftest.c
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='${CC-cc} -c conftest.c -o conftest.o 1>&5'
+if { (eval echo configure:898: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
+   test -f conftest.o && { (eval echo configure:899: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+then
+  eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+  if test "x$CC" != xcc; then
+    # Test first that cc exists at all.
+    if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:904: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+      ac_try='cc -c conftest.c -o conftest.o 1>&5'
+      if { (eval echo configure:906: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
+	 test -f conftest.o && { (eval echo configure:907: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+      then
+        # cc works too.
+        :
+      else
+        # cc exists but doesn't like -o.
+        eval ac_cv_prog_cc_${ac_cc}_c_o=no
+      fi
+    fi
+  fi
+else
+  eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+  cat >> confdefs.h <<\EOF
+#define NO_MINUS_C_MINUS_O 1
+EOF
+
+fi
+
+
+
+  # Check whether --with-php-config or --without-php-config was given.
+if test "${with_php_config+set}" = set; then
+  withval="$with_php_config"
+  
+  PHP_CONFIG=$withval
+
+else
+  
+  PHP_CONFIG=php-config
+
+fi
+
+
+  prefix=`$PHP_CONFIG --prefix 2>/dev/null`
+  INCLUDES=`$PHP_CONFIG --includes 2>/dev/null`
+  EXTENSION_DIR=`$PHP_CONFIG --extension-dir`
+ 
+  if test -z "$prefix"; then
+    { echo "configure: error: Cannot find php-config. Please use --with-php-config=PATH" 1>&2; exit 1; }
+  fi
+  echo $ac_n "checking for PHP prefix""... $ac_c" 1>&6
+echo "configure:956: checking for PHP prefix" >&5
+  echo "$ac_t""$prefix" 1>&6
+  echo $ac_n "checking for PHP includes""... $ac_c" 1>&6
+echo "configure:959: checking for PHP includes" >&5
+  echo "$ac_t""$INCLUDES" 1>&6
+  echo $ac_n "checking for PHP extension directory""... $ac_c" 1>&6
+echo "configure:962: checking for PHP extension directory" >&5
+  echo "$ac_t""$EXTENSION_DIR" 1>&6
+
+
+
+
+
+
+
+echo $ac_n "checking for RRDTool support""... $ac_c" 1>&6
+echo "configure:972: checking for RRDTool support" >&5
+# Check whether --with-rrdtool or --without-rrdtool was given.
+if test "${with_rrdtool+set}" = set; then
+  withval="$with_rrdtool"
+  PHP_RRDTOOL=$withval
+else
+  PHP_RRDTOOL=no
+fi
+
+
+case "$PHP_RRDTOOL" in
+shared,*)
+  ext_output="yes, shared"
+  ext_shared=yes
+  PHP_RRDTOOL=`echo $ac_n "$PHP_RRDTOOL$ac_c"|sed s/^shared,//`
+  ;;
+shared)
+  ext_output="yes, shared"
+  ext_shared=yes
+  PHP_RRDTOOL=yes
+  ;;
+no)
+  ext_output="no"
+  ext_shared=no
+  ;;
+*)
+  ext_output="yes"
+  ext_shared=no
+  ;;
+esac
+
+if test "$php_always_shared" = "yes"; then
+  ext_output="yes, shared"
+  ext_shared=yes
+  test "$PHP_RRDTOOL" = "no" && PHP_RRDTOOL=yes
+fi
+
+echo "$ac_t""$ext_output" 1>&6
+
+
+
+
+if test "$PHP_RRDTOOL" != "no"; then
+  for i in /usr/local /usr /opt/rrdtool /usr/local/rrdtool $PHP_RRDTOOL; do
+    if test -f $i/include/rrd.h; then
+      RRDTOOL_DIR=$i
+    fi
+  done
+
+  if test -z "$RRDTOOL_DIR"; then
+    { echo "configure: error: Please reinstall rrdtool" 1>&2; exit 1; }
+  fi
+  
+  if test "$RRDTOOL_DIR/include" != "/usr/include"; then
+    
+  if test -z "$RRDTOOL_DIR/include" || echo "$RRDTOOL_DIR/include" | grep '^/' >/dev/null ; then
+    ai_p="$RRDTOOL_DIR/include"
+  else
+    
+    ep_dir="`echo $RRDTOOL_DIR/include|sed 's%/*[^/][^/]*$%%'`"
+    
+    ep_realdir="`(cd \"$ep_dir\" && pwd)`"
+    ai_p="$ep_realdir/`basename \"$RRDTOOL_DIR/include\"`"
+  fi
+
+    
+  
+  unique=`echo $ai_p|sed 's/[^a-zA-Z0-9]/_/g'`
+  
+  cmd="echo $ac_n \"\$INCLUDEPATH$unique$ac_c\""
+  if test -n "$unique" && test "`eval $cmd`" = "" ; then
+    eval "INCLUDEPATH$unique=set"
+    
+      INCLUDES="$INCLUDES -I$ai_p"
+    
+  fi
+
+  fi
+
+  
+
+  if test "$ext_shared" = "yes"; then
+    RRDTOOL_SHARED_LIBADD="-lrrd $RRDTOOL_SHARED_LIBADD"
+    if test -n "$RRDTOOL_DIR/lib"; then
+      
+  if test "$RRDTOOL_DIR/lib" != "/usr/lib"; then
+    
+  if test -z "$RRDTOOL_DIR/lib" || echo "$RRDTOOL_DIR/lib" | grep '^/' >/dev/null ; then
+    ai_p="$RRDTOOL_DIR/lib"
+  else
+    
+    ep_dir="`echo $RRDTOOL_DIR/lib|sed 's%/*[^/][^/]*$%%'`"
+    
+    ep_realdir="`(cd \"$ep_dir\" && pwd)`"
+    ai_p="$ep_realdir/`basename \"$RRDTOOL_DIR/lib\"`"
+  fi
+
+    if test "$ext_shared" = "yes" && test -n "RRDTOOL_SHARED_LIBADD"; then
+      RRDTOOL_SHARED_LIBADD="-R$RRDTOOL_DIR/lib -L$RRDTOOL_DIR/lib $RRDTOOL_SHARED_LIBADD"
+    else
+      
+  
+  unique=`echo $ai_p|sed 's/[^a-zA-Z0-9]/_/g'`
+  
+  cmd="echo $ac_n \"\$LIBPATH$unique$ac_c\""
+  if test -n "$unique" && test "`eval $cmd`" = "" ; then
+    eval "LIBPATH$unique=set"
+    
+        test -n "$ld_runpath_switch" && LDFLAGS="$LDFLAGS $ld_runpath_switch$ai_p"
+        LDFLAGS="$LDFLAGS -L$ai_p"
+        PHP_RPATHS="$PHP_RPATHS $ai_p"
+      
+  fi
+
+    fi
+  fi
+
+    fi
+  else
+    
+
+  if test -n "$RRDTOOL_DIR/lib"; then
+    
+  if test "$RRDTOOL_DIR/lib" != "/usr/lib"; then
+    
+  if test -z "$RRDTOOL_DIR/lib" || echo "$RRDTOOL_DIR/lib" | grep '^/' >/dev/null ; then
+    ai_p="$RRDTOOL_DIR/lib"
+  else
+    
+    ep_dir="`echo $RRDTOOL_DIR/lib|sed 's%/*[^/][^/]*$%%'`"
+    
+    ep_realdir="`(cd \"$ep_dir\" && pwd)`"
+    ai_p="$ep_realdir/`basename \"$RRDTOOL_DIR/lib\"`"
+  fi
+
+    if test "$ext_shared" = "yes" && test -n ""; then
+      ="-R$RRDTOOL_DIR/lib -L$RRDTOOL_DIR/lib $"
+    else
+      
+  
+  unique=`echo $ai_p|sed 's/[^a-zA-Z0-9]/_/g'`
+  
+  cmd="echo $ac_n \"\$LIBPATH$unique$ac_c\""
+  if test -n "$unique" && test "`eval $cmd`" = "" ; then
+    eval "LIBPATH$unique=set"
+    
+        test -n "$ld_runpath_switch" && LDFLAGS="$LDFLAGS $ld_runpath_switch$ai_p"
+        LDFLAGS="$LDFLAGS -L$ai_p"
+        PHP_RPATHS="$PHP_RPATHS $ai_p"
+      
+  fi
+
+    fi
+  fi
+
+  fi
+  
+ case "rrd" in
+ c|c_r|pthread*) ;;
+ *)
+
+   
+  
+  unique=`echo rrd|sed 's/[^a-zA-Z0-9]/_/g'`
+  
+  cmd="echo $ac_n \"\$LIBRARY$unique$ac_c\""
+  if test -n "$unique" && test "`eval $cmd`" = "" ; then
+    eval "LIBRARY$unique=set"
+    
+     
+  LIBS="-lrrd $LIBS"
+
+   
+  fi
+
+
+  ;;
+  esac
+
+
+
+  fi
+
+
+  
+  PHP_VAR_SUBST="$PHP_VAR_SUBST RRDTOOL_SHARED_LIBADD"
+  
+
+
+  cat >> confdefs.h <<\EOF
+#define HAVE_RRDTOOL 1
+EOF
+
+
+  
+  EXT_SUBDIRS="$EXT_SUBDIRS rrdtool"
+  
+  if test -d "$abs_srcdir/ext/rrdtool"; then
+    ext_builddir="ext/rrdtool"
+    ext_srcdir="$abs_srcdir/ext/rrdtool"
+  else
+    ext_builddir="."
+    ext_srcdir="$abs_srcdir"
+  fi
+
+  if test "$ext_shared" != "shared" && test "$ext_shared" != "yes"; then
+    
+  lib_makefile="$ext_builddir/libs.mk"
+  lib_target=""
+  
+  $php_shtool mkdir -p $ext_builddir
+  cat >$lib_makefile<<EOF
+LTLIBRARY_OBJECTS = \$(LTLIBRARY_SOURCES:.c=.lo)
+LTLIBRARY_SHARED_OBJECTS = \$(LTLIBRARY_OBJECTS:.lo=.slo)
+EOF
+
+  if test "" = "shared" || test "" = "yes"; then
+    lib_build_shared=yes
+    if test -n ""; then
+      
+  lib_target="\$(LTLIBRARY_NAME)"
+  cat >>$lib_makefile<<EOF
+\$(LTLIBRARY_NAME): \$(LTLIBRARY_SHARED_OBJECTS) \$(LTLIBRARY_DEPENDENCIES)
+	\$(SHARED_LIBTOOL) --mode=link \$(CCLD) \$(CFLAGS) \$(EXTRA_CFLAGS) \$(LDFLAGS) -o \$@ \$(LTLIBRARY_LDFLAGS) \$(LTLIBRARY_OBJECTS) \$(LTLIBRARY_SHARED_LIBADD)
+
+EOF
+
+    else
+      
+  lib_target="\$(LTLIBRARY_SHARED_NAME)"
+  cat >>$lib_makefile<<EOF
+\$(LTLIBRARY_SHARED_NAME): \$(LTLIBRARY_SHARED_OBJECTS) \$(LTLIBRARY_DEPENDENCIES)
+	\$(SHARED_LIBTOOL) --mode=link \$(CCLD) \$(CFLAGS) \$(EXTRA_CFLAGS) \$(LDFLAGS) -o \$@ -avoid-version -module -rpath \$(phplibdir) \$(LTLIBRARY_LDFLAGS) \$(LTLIBRARY_OBJECTS) \$(LTLIBRARY_SHARED_LIBADD)
+	\$(SHARED_LIBTOOL) --mode=install cp \$@ \$(phplibdir)
+
+EOF
+
+    fi
+  else
+    
+  lib_target="\$(LTLIBRARY_NAME)"
+  cat >>$lib_makefile<<EOF
+\$(LTLIBRARY_NAME): \$(LTLIBRARY_OBJECTS) \$(LTLIBRARY_DEPENDENCIES)
+	\$(LINK) \$(LTLIBRARY_LDFLAGS) \$(LTLIBRARY_OBJECTS) \$(LTLIBRARY_LIBADD)
+
+EOF
+
+  fi
+
+  if test -n "$lib_target"; then
+    cat >>$lib_makefile<<EOF
+targets = $lib_target
+EOF
+  fi
+
+    EXT_LTLIBS="$EXT_LTLIBS $ext_builddir/librrdtool.la"
+    EXT_STATIC="$EXT_STATIC rrdtool"
+  else 
+    
+  lib_makefile="$ext_builddir/libs.mk"
+  lib_target=""
+  
+  $php_shtool mkdir -p $ext_builddir
+  cat >$lib_makefile<<EOF
+LTLIBRARY_OBJECTS = \$(LTLIBRARY_SOURCES:.c=.lo)
+LTLIBRARY_SHARED_OBJECTS = \$(LTLIBRARY_OBJECTS:.lo=.slo)
+EOF
+
+  if test "yes" = "shared" || test "yes" = "yes"; then
+    lib_build_shared=yes
+    if test -n ""; then
+      
+  lib_target="\$(LTLIBRARY_NAME)"
+  cat >>$lib_makefile<<EOF
+\$(LTLIBRARY_NAME): \$(LTLIBRARY_SHARED_OBJECTS) \$(LTLIBRARY_DEPENDENCIES)
+	\$(SHARED_LIBTOOL) --mode=link \$(CCLD) \$(CFLAGS) \$(EXTRA_CFLAGS) \$(LDFLAGS) -o \$@ \$(LTLIBRARY_LDFLAGS) \$(LTLIBRARY_OBJECTS) \$(LTLIBRARY_SHARED_LIBADD)
+
+EOF
+
+    else
+      
+  lib_target="\$(LTLIBRARY_SHARED_NAME)"
+  cat >>$lib_makefile<<EOF
+\$(LTLIBRARY_SHARED_NAME): \$(LTLIBRARY_SHARED_OBJECTS) \$(LTLIBRARY_DEPENDENCIES)
+	\$(SHARED_LIBTOOL) --mode=link \$(CCLD) \$(CFLAGS) \$(EXTRA_CFLAGS) \$(LDFLAGS) -o \$@ -avoid-version -module -rpath \$(phplibdir) \$(LTLIBRARY_LDFLAGS) \$(LTLIBRARY_OBJECTS) \$(LTLIBRARY_SHARED_LIBADD)
+	\$(SHARED_LIBTOOL) --mode=install cp \$@ \$(phplibdir)
+
+EOF
+
+    fi
+  else
+    
+  lib_target="\$(LTLIBRARY_NAME)"
+  cat >>$lib_makefile<<EOF
+\$(LTLIBRARY_NAME): \$(LTLIBRARY_OBJECTS) \$(LTLIBRARY_DEPENDENCIES)
+	\$(LINK) \$(LTLIBRARY_LDFLAGS) \$(LTLIBRARY_OBJECTS) \$(LTLIBRARY_LIBADD)
+
+EOF
+
+  fi
+
+  if test -n "$lib_target"; then
+    cat >>$lib_makefile<<EOF
+targets = $lib_target
+EOF
+  fi
+
+    cat >> confdefs.h <<EOF
+#define COMPILE_DL_RRDTOOL 1
+EOF
+
+  fi
+
+  
+  PHP_FAST_OUTPUT_FILES="$PHP_FAST_OUTPUT_FILES $ext_builddir/Makefile"
+
+
+fi
+
+
+enable_static=no
+enable_shared=yes
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval="$enable_static"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+  enableval="$enable_fast_install"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_fast_install=yes
+fi
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:1390: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:1411: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+  case $nonopt in
+  NONE) build_alias=$host_alias ;;
+  *) build_alias=$nonopt ;;
+  esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1431: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval="$with_gnu_ld"
+  test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1470: checking for ld used by GCC" >&5
+  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+  case "$ac_prog" in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1494: checking for GNU ld" >&5
+else
+  echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1497: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -z "$LD"; then
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+	test "$with_gnu_ld" != no && break
+      else
+	test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  echo "$ac_t""$LD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1533: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1549: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  ac_cv_path_NM="$NM"
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+	ac_cv_path_NM="$ac_dir/nm -B"
+	break
+      elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+	ac_cv_path_NM="$ac_dir/nm -p"
+	break
+      else
+	ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+	continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1586: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+  rm -f conftestdata
+  ac_cv_prog_LN_S="ln -s"
+else
+  ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval="$enable_libtool_lock"
+  :
+fi
+
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 1630 "configure"' > conftest.$ac_ext
+  if { (eval echo configure:1631: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:1652: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1657 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1664: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  lt_cv_cc_needs_belf=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+SHARED_LIBTOOL='$(LIBTOOL)'
+PHP_COMPILE='$(LIBTOOL) --mode=compile $(COMPILE) -c $<'
+phplibdir="`pwd`/modules"
+
+test "$prefix" = "NONE" && prefix="/usr/local"
+test "$exec_prefix" = "NONE" && exec_prefix='$(prefix)'
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST prefix"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST exec_prefix"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST libdir"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST prefix"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST phplibdir"
+  
+
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST PHP_COMPILE"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST CC"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST CFLAGS"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST CPP"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST CPPFLAGS"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST CXX"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST DEFS"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST EXTENSION_DIR"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST EXTRA_LDFLAGS"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST EXTRA_LIBS"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST INCLUDES"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST LEX"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST LEX_OUTPUT_ROOT"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST LFLAGS"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST SHARED_LIBTOOL"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST LIBTOOL"
+  
+
+
+  PHP_VAR_SUBST="$PHP_VAR_SUBST SHELL"
+  
+
+
+
+  PHP_FAST_OUTPUT_FILES="$PHP_FAST_OUTPUT_FILES Makefile"
+
+
+
+  
+  echo $ac_n "checking for working mkdir -p""... $ac_c" 1>&6
+echo "configure:1870: checking for working mkdir -p" >&5
+if eval "test \"`echo '$''{'ac_cv_mkdir_p'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+    test -d conftestdir && rm -rf conftestdir
+    mkdir -p conftestdir/somedir >/dev/null 2>&1
+    if test -d conftestdir/somedir; then
+      ac_cv_mkdir_p=yes
+    else
+      ac_cv_mkdir_p=no
+    fi
+    rm -rf conftestdir
+  
+fi
+
+echo "$ac_t""$ac_cv_mkdir_p" 1>&6
+
+  echo creating config_vars.mk
+  > config_vars.mk
+  for i in $PHP_VAR_SUBST; do
+    eval echo "$i = \$$i" >> config_vars.mk
+  done
+
+
+  $SHELL $srcdir/build/fastgen.sh $srcdir $ac_cv_mkdir_p $PHP_FAST_OUTPUT_FILES
+
+
+test -d modules || mkdir modules
+touch .deps
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo " php_config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@EXT_SUBDIRS@%$EXT_SUBDIRS%g
+s%@EXT_STATIC@%$EXT_STATIC%g
+s%@EXT_SHARED@%$EXT_SHARED%g
+s%@EXT_LIBS@%$EXT_LIBS%g
+s%@EXT_LTLIBS@%$EXT_LTLIBS%g
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CC@%$CC%g
+s%@RRDTOOL_SHARED_LIBADD@%$RRDTOOL_SHARED_LIBADD%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@RANLIB@%$RANLIB%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
+s%@LN_S@%$LN_S%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@phplibdir@%$phplibdir%g
+s%@PHP_COMPILE@%$PHP_COMPILE%g
+s%@CPP@%$CPP%g
+s%@CXX@%$CXX%g
+s%@EXTENSION_DIR@%$EXTENSION_DIR%g
+s%@EXTRA_LDFLAGS@%$EXTRA_LDFLAGS%g
+s%@EXTRA_LIBS@%$EXTRA_LIBS%g
+s%@INCLUDES@%$INCLUDES%g
+s%@LEX@%$LEX%g
+s%@LEX_OUTPUT_ROOT@%$LEX_OUTPUT_ROOT%g
+s%@LFLAGS@%$LFLAGS%g
+s%@SHARED_LIBTOOL@%$SHARED_LIBTOOL%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-""}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
+ac_dB='\([ 	][ 	]*\)[^ 	]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_uB='\([ 	]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="php_config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ 	]*#[ 	]*undef[ 	][ 	]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/php_rrdtool.h
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/php_rrdtool.h	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/php_rrdtool.h	Sat Jul 13 21:26:05 2002
@@ -0,0 +1,46 @@
+/*
+ * php_rrdtool.h
+ *
+ * php4 rrdtool module.  
+ *
+ * Joe Miller, <joeym at inficad.com>,<joeym at ibizcorp.com>, 7/19/2000
+ *
+ * $Id: php_rrdtool.h,v 1.1 2000/07/19 17:24:08 joeym Exp joeym $
+ *
+ */
+
+#ifndef _PHP4_RRDTOOL_H
+#define _PHP4_RRDTOOL_H
+
+#if COMPILE_DL
+#undef HAVE_RRDTOOL
+#define HAVE_RRDTOOL 1
+#endif
+#ifndef DLEXPORT
+#define DLEXPORT
+#endif
+
+#if HAVE_RRDTOOL
+
+PHP_MINFO_FUNCTION(rrdtool);
+
+extern zend_module_entry rrdtool_module_entry;
+#define rrdtool_module_ptr &rrdtool_module_entry
+#define phpext_rrdtool_ptr rrdtool_module_ptr
+
+PHP_FUNCTION(rrd_error);
+PHP_FUNCTION(rrd_clear_error);
+PHP_FUNCTION(rrd_update);
+PHP_FUNCTION(rrd_last);
+PHP_FUNCTION(rrd_create);
+PHP_FUNCTION(rrd_graph);
+PHP_FUNCTION(rrd_fetch);
+
+#else
+
+#define phpext_rrdtool_ptr NULL
+
+
+#endif /* HAVE_RRDTOOL */
+
+#endif  /* _PHP4_RRDTOOL_H */

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/Makefile.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/Makefile.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/Makefile.in	Sat Jul 13 21:26:05 2002
@@ -0,0 +1,8 @@
+# $Id: Makefile.in,v 1.1 2000/07/19 17:22:46 joeym Exp joeym $
+
+LTLIBRARY_NAME        = librrdtool.la
+LTLIBRARY_SOURCES     = rrdtool.c
+LTLIBRARY_SHARED_NAME = rrdtool.la
+LTLIBRARY_SHARED_LIBADD = $(RRDTOOL_SHARED_LIBADD)
+
+include $(top_srcdir)/build/dynlib.mk

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/config.m4
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/config.m4	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/config.m4	Sat Jul 13 21:26:06 2002
@@ -0,0 +1,24 @@
+dnl $Id: config.m4,v 1.1 2000/07/19 17:23:35 joeym Exp joeym $
+
+PHP_ARG_WITH(rrdtool, for RRDTool support,
+[  --with-rrdtool[=DIR]      Include RRDTool support.  DIR is the rrdtool
+                          install directory.])
+
+if test "$PHP_RRDTOOL" != "no"; then
+  for i in /usr/local /usr /opt/rrdtool /usr/local/rrdtool $PHP_RRDTOOL; do
+    if test -f $i/include/rrd.h; then
+      RRDTOOL_DIR=$i
+    fi
+  done
+
+  if test -z "$RRDTOOL_DIR"; then
+    AC_MSG_ERROR(Please reinstall rrdtool, or specify a directory - I cannot find rrd.h)
+  fi
+  AC_ADD_INCLUDE($RRDTOOL_DIR/include)
+  AC_ADD_LIBRARY_WITH_PATH(rrd, $RRDTOOL_DIR/lib, RRDTOOL_SHARED_LIBADD)
+  PHP_SUBST(RRDTOOL_SHARED_LIBADD)
+
+  AC_DEFINE(HAVE_RRDTOOL,1,[ ])
+
+  PHP_EXTENSION(rrdtool, $ext_shared)
+fi

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/configure.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/configure.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/configure.in	Sat Jul 13 21:26:06 2002
@@ -0,0 +1,86 @@
+
+AC_INIT(Makefile.in)
+
+AC_DEFUN(PHP_WITH_PHP_CONFIG,[
+  AC_ARG_WITH(php-config,
+[  --with-php-config=[PATH]],[
+  PHP_CONFIG=$withval
+],[
+  PHP_CONFIG=php-config
+])
+
+  prefix=`$PHP_CONFIG --prefix 2>/dev/null`
+  INCLUDES=`$PHP_CONFIG --includes 2>/dev/null`
+  EXTENSION_DIR=`$PHP_CONFIG --extension-dir`
+ 
+  if test -z "$prefix"; then
+    AC_MSG_ERROR(Cannot find php-config. Please use --with-php-config=[PATH])
+  fi
+  AC_MSG_CHECKING(for PHP prefix)
+  AC_MSG_RESULT($prefix)
+  AC_MSG_CHECKING(for PHP includes)
+  AC_MSG_RESULT($INCLUDES)
+  AC_MSG_CHECKING(for PHP extension directory)
+  AC_MSG_RESULT($EXTENSION_DIR)
+])
+
+abs_srcdir=`(cd $srcdir && pwd)`
+
+php_always_shared=yes
+
+AC_PROG_CC
+AC_PROG_CC_C_O
+
+PHP_WITH_PHP_CONFIG
+
+AC_PREFIX_DEFAULT()
+
+sinclude(config.m4)
+
+enable_static=no
+enable_shared=yes
+
+AC_PROG_LIBTOOL
+
+SHARED_LIBTOOL='$(LIBTOOL)'
+PHP_COMPILE='$(LIBTOOL) --mode=compile $(COMPILE) -c $<'
+phplibdir="`pwd`/modules"
+
+test "$prefix" = "NONE" && prefix="/usr/local"
+test "$exec_prefix" = "NONE" && exec_prefix='$(prefix)'
+
+PHP_SUBST(prefix)
+PHP_SUBST(exec_prefix)
+PHP_SUBST(libdir)
+PHP_SUBST(prefix)
+PHP_SUBST(phplibdir)
+
+PHP_SUBST(PHP_COMPILE)
+PHP_SUBST(CC)
+PHP_SUBST(CFLAGS)
+PHP_SUBST(CPP)
+PHP_SUBST(CPPFLAGS)
+PHP_SUBST(CXX)
+PHP_SUBST(DEFS)
+PHP_SUBST(EXTENSION_DIR)
+PHP_SUBST(EXTRA_LDFLAGS)
+PHP_SUBST(EXTRA_LIBS)
+PHP_SUBST(INCLUDES)
+PHP_SUBST(LEX)
+PHP_SUBST(LEX_OUTPUT_ROOT)
+PHP_SUBST(LFLAGS)
+PHP_SUBST(SHARED_LIBTOOL)
+PHP_SUBST(LIBTOOL)
+PHP_SUBST(SHELL)
+
+PHP_FAST_OUTPUT(Makefile)
+
+PHP_GEN_CONFIG_VARS
+PHP_GEN_MAKEFILES
+
+test -d modules || mkdir modules
+touch .deps
+
+AC_CONFIG_HEADER(php_config.h)
+
+AC_OUTPUT()

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/config.guess
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/config.guess	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/config.guess	Sat Jul 13 21:26:06 2002
@@ -0,0 +1,1087 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999
+#   Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# 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.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner at cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+# Please send patches to the Autoconf mailing list <autoconf at gnu.org>.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# Use $HOST_CC if defined. $CC may point to a cross-compiler
+if test x"$CC_FOR_BUILD" = x; then
+  if test x"$HOST_CC" != x; then
+    CC_FOR_BUILD="$HOST_CC"
+  else
+    if test x"$CC" != x; then
+      CC_FOR_BUILD="$CC"
+    else
+      CC_FOR_BUILD=cc
+    fi
+  fi
+fi
+
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi at noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    alpha:OSF1:*:*)
+	if test $UNAME_RELEASE = "V4.0"; then
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+	fi
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	cat <<EOF >$dummy.s
+	.globl main
+	.ent main
+main:
+	.frame \$30,0,\$26,0
+	.prologue 0
+	.long 0x47e03d80 # implver $0
+	lda \$2,259
+	.long 0x47e20c21 # amask $2,$1
+	srl \$1,8,\$2
+	sll \$2,2,\$2
+	sll \$0,3,\$0
+	addl \$1,\$0,\$0
+	addl \$2,\$0,\$0
+	ret \$31,(\$26),1
+	.end main
+EOF
+	$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+	if test "$?" = 0 ; then
+		./$dummy
+		case "$?" in
+			7)
+				UNAME_MACHINE="alpha"
+				;;
+			15)
+				UNAME_MACHINE="alphaev5"
+				;;
+			14)
+				UNAME_MACHINE="alphaev56"
+				;;
+			10)
+				UNAME_MACHINE="alphapca56"
+				;;
+			16)
+				UNAME_MACHINE="alphaev6"
+				;;
+		esac
+	fi
+	rm -f $dummy.s $dummy
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-cbm-sysv4
+	exit 0;;
+    amiga:NetBSD:*:*)
+      echo m68k-cbm-netbsd${UNAME_RELEASE}
+      exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    arc64:OpenBSD:*:*)
+	echo mips64el-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hkmips:OpenBSD:*:*)
+	echo mips-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mips-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    arm32:NetBSD:*:*)
+	echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	exit 0 ;;
+    SR2?01:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:NetBSD:*:*)
+	echo m68k-atari-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor 
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    sun3*:NetBSD:*:*)
+	echo m68k-sun-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3*:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:NetBSD:*:*)
+	echo m68k-apple-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:NetBSD:*:*)
+        echo powerpc-apple-netbsd${UNAME_RELEASE}
+        exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD $dummy.c -o $dummy \
+	  && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && rm $dummy.c $dummy && exit 0
+	rm -f $dummy.c $dummy
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+        if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
+	if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+	     -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	fi
+        else echo i586-dg-dgux${UNAME_RELEASE}
+        fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i?86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+		rm -f $dummy.c $dummy
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:4)
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=4.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC NetBSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+              sed 's/^              //' << EOF >$dummy.c
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+	($CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+	rm -f $dummy.c $dummy
+	esac
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+	rm -f $dummy.c $dummy
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i?86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    hppa*:OpenBSD:*:*)
+	echo hppa-unknown-openbsd
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+	echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE}
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE}
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo t3e-cray-unicosmk${UNAME_RELEASE}
+	exit 0 ;;
+    CRAY-2:*:*:*)
+	echo cray2-cray-unicos
+        exit 0 ;;
+    F300:UNIX_System_V:*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    F301:UNIX_System_V:*:*)
+       echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+       exit 0 ;;
+    hp3[0-9][05]:NetBSD:*:*)
+	echo m68k-hp-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    i?86:BSD/386:*:* | i?86:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	if test -x /usr/bin/objformat; then
+	    if test "elf" = "`/usr/bin/objformat`"; then
+		echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'`
+		exit 0
+	    fi
+	fi
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    *:NetBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i386-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    *:Linux:*:*)
+	# uname on the ARM produces all sorts of strangeness, and we need to
+	# filter it out.
+	case "$UNAME_MACHINE" in
+	  armv*)		      UNAME_MACHINE=$UNAME_MACHINE ;;
+	  arm* | sa110*)	      UNAME_MACHINE="arm" ;;
+	esac
+
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	ld_help_string=`cd /; ld --help 2>&1`
+	ld_supported_emulations=`echo $ld_help_string \
+			 | sed -ne '/supported emulations:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported emulations: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_emulations" in
+	  i?86linux)  echo "${UNAME_MACHINE}-pc-linux-gnuaout"      ; exit 0 ;;
+	  i?86coff)   echo "${UNAME_MACHINE}-pc-linux-gnucoff"      ; exit 0 ;;
+	  sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+	  armlinux)   echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+	  m68klinux)  echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+	  elf32ppc)
+		# Determine Lib Version
+		cat >$dummy.c <<EOF
+#include <features.h>
+#if defined(__GLIBC__)
+extern char __libc_version[];
+extern char __libc_release[];
+#endif
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#if defined(__GLIBC__)
+  printf("%s %s\n", __libc_version, __libc_release);
+#else
+  printf("unkown\n");
+#endif
+  return 0;
+}
+EOF
+		LIBC=""
+		$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
+		if test "$?" = 0 ; then
+			./$dummy | grep 1\.99 > /dev/null
+			if test "$?" = 0 ; then
+				LIBC="libc1"
+			fi
+		fi	
+		rm -f $dummy.c $dummy
+		echo powerpc-unknown-linux-gnu${LIBC} ; exit 0 ;;
+	esac
+
+	if test "${UNAME_MACHINE}" = "alpha" ; then
+		sed 's/^	//'  <<EOF >$dummy.s
+		.globl main
+		.ent main
+	main:
+		.frame \$30,0,\$26,0
+		.prologue 0
+		.long 0x47e03d80 # implver $0
+		lda \$2,259
+		.long 0x47e20c21 # amask $2,$1
+		srl \$1,8,\$2
+		sll \$2,2,\$2
+		sll \$0,3,\$0
+		addl \$1,\$0,\$0
+		addl \$2,\$0,\$0
+		ret \$31,(\$26),1
+		.end main
+EOF
+		LIBC=""
+		$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+		if test "$?" = 0 ; then
+			./$dummy
+			case "$?" in
+			7)
+				UNAME_MACHINE="alpha"
+				;;
+			15)
+				UNAME_MACHINE="alphaev5"
+				;;
+			14)
+				UNAME_MACHINE="alphaev56"
+				;;
+			10)
+				UNAME_MACHINE="alphapca56"
+				;;
+			16)
+				UNAME_MACHINE="alphaev6"
+				;;
+			esac
+
+			objdump --private-headers $dummy | \
+			  grep ld.so.1 > /dev/null
+			if test "$?" = 0 ; then
+				LIBC="libc1"
+			fi
+		fi
+		rm -f $dummy.s $dummy
+		echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+	elif test "${UNAME_MACHINE}" = "mips" ; then
+	  cat >$dummy.c <<EOF
+#ifdef __cplusplus
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __MIPSEB__
+  printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+  printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+	  $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+	  rm -f $dummy.c $dummy
+	else
+	  # Either a pre-BFD a.out linker (linux-gnuoldld)
+	  # or one that does not give us useful --help.
+	  # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+	  # If ld does not provide *any* "supported emulations:"
+	  # that means it is gnuoldld.
+	  echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+	  test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+	  case "${UNAME_MACHINE}" in
+	  i?86)
+	    VENDOR=pc;
+	    ;;
+	  *)
+	    VENDOR=unknown;
+	    ;;
+	  esac
+	  # Determine whether the default compiler is a.out or elf
+	  cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+	  $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+	  rm -f $dummy.c $dummy
+	fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.  earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+    i?86:DYNIX/ptx:4*:*)
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i?86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+	fi
+	exit 0 ;;
+    i?86:*:5:7*)
+	UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+	(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+	(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) && UNAME_MACHINE=i586
+	(/bin/uname -X|egrep '^Machine.*Pent.*II' >/dev/null) && UNAME_MACHINE=i686
+	(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) && UNAME_MACHINE=i585
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}${UNAME_VERSION}-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    i?86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    pc:*:*:*)
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    M68*:*:R3V[567]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                           # says <Richard.M.Bartel at ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes at openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf at swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:*:6*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+  printf ("vax-dec-bsd\n"); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/README
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/README	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/README	Sat Jul 13 21:26:06 2002
@@ -0,0 +1,71 @@
+$Id: README,v 1.4 2000/08/28 23:24:08 joeym Exp joeym $
+
+UPDATES for php4:
+
+    This version of the module will only build for php4/zend.  It will
+not build for php3.  Get php3_rrdtool from the rrdtool distribution
+if you need the rrd_* functions in php3.  
+
+    The module now contains two ways to install.  The first is as
+a self-contained extension (much like the php3_rrdtool module),
+and the second is as a php4 embedded extension.  See the INSTALL
+file for instructions on how to install in both ways.
+
+    Also fixed some of the scripts in the 'examples' directory. 
+A few of them were checking the return value for -1 on some
+of the rrd_* function calls.  Most calls will return 0 or 1 to
+indicate failure or success, not -1.  Sorry about that.
+
+
+
+------------------------------------
+
+PHP bindings for RRD Tool.
+
+    Contained herein are bindings to allow you to interface
+php scripts with RRD tool directly via RRD tool's 'librrd' library,
+thus avoiding the need to use system() calls to the rrdtool binary.
+
+    RRD Tool is an AMAZING package of tools to faciliate
+the easy storage, retrieval, and graphing of statistics (usually
+but not limited to bit/byte counts from routers, switches, and 
+hubs).  It was written by the author of MRTG, Tobias Oetiker
+(oetiker at ee.ethz.ch).  The primary web site for RRD Tool is:
+http://www.caida.org/Tools/RRDtool
+
+
+Reason I wrote this:  Wanted to use PHP to create fairly real-time / 
+dynamic web pages w/ RRD tool, but the only way was to use system()
+and popen() with PHP, since there was no direct interface to RRD
+Tool from PHP.  The fork()ing would have been slow and tedious
+so that was pretty much out of the question.  I could have used the 
+Perl library (RRDs) to interface ePerl, or mod_perl, or even 
+'rrdcgi', but I didn't really want to.  I wanted to use PHP and
+there was nothing to change my mind.
+
+
+You are free to redistribute the source provided my name is
+kept at the top of the source files as credit for the original
+author.  I make no warranties to the usability of this software,
+nor I am responsible if your machine explodes (although it 
+shouldn't).
+
+
+BUGS:
+     There might be some.  Let me know: joeym at inficad.com.  
+Patches to fix bugs you find are more welcome than simple
+reports of bugs (I don't have a lot of time to maintain
+this code).
+
+	You must include OS, apache version, and method of use
+(embedded or self-contained extension) in bug reports.  This
+info is important.  Also, give as much detail and examples 
+as possible so I can figure out what is wrong =)
+
+THANKS:
+	I'd like to thank Jeroen Roodnat for generously helping 
+debug the PHP4/Zend version of this module.  
+
+
+Joe Miller, <joeym at inficad.com>,<joeym at ibizcorp.com>,
+2/12/2000  (updated: 8/28/2000)

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/ltmain.sh
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/ltmain.sh	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/ltmain.sh	Sat Jul 13 21:26:06 2002
@@ -0,0 +1,4088 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun ltconfig.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+#
+# 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.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell, and then maybe $echo will work.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.3.3-freebsd-ports
+TIMESTAMP=" (1.385.2.181 1999/07/02 15:49:11)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+SP2NL='tr \040 \012'
+NL2SP='tr \015\012 \040\040'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+  save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+  echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  echo "$modename: not configured to build any kind of library" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+  arg="$1"
+  shift
+
+  case "$arg" in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case "$prev" in
+    execute_dlfiles)
+      eval "$prev=\"\$$prev \$arg\""
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case "$arg" in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+    exit 0
+    ;;
+
+  --config)
+    sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0
+    exit 0
+    ;;
+
+  --debug)
+    echo "$progname: enabling shell trace mode"
+    set -x
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+    exit 0
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --quiet | --silent)
+    show=:
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+fi
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    case "$nonopt" in
+    *cc | *++ | gcc* | *-gcc*)
+      mode=link
+      for arg
+      do
+	case "$arg" in
+	-c)
+	   mode=compile
+	   break
+	   ;;
+	esac
+      done
+      ;;
+    *db | *dbx | *strace | *truss)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+	if test -n "$nonopt"; then
+	  $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+	else
+	  $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+	fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case "$mode" in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    lastarg=
+    srcfile="$nonopt"
+    suppress_output=
+
+    user_target=no
+    for arg
+    do
+      # Accept any command-line options.
+      case "$arg" in
+      -o)
+	if test "$user_target" != "no"; then
+	  $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+	  exit 1
+	fi
+	user_target=next
+	;;
+
+      -static)
+	build_old_libs=yes
+	continue
+	;;
+      esac
+
+      case "$user_target" in
+      next)
+	# The next one is the -o target name
+	user_target=yes
+	continue
+	;;
+      yes)
+	# We got the output file
+	user_target=set
+	libobj="$arg"
+	continue
+	;;
+      esac
+
+      # Accept the current argument as the source file.
+      lastarg="$srcfile"
+      srcfile="$arg"
+
+      # Aesthetically quote the previous argument.
+
+      # Backslashify any backslashes, double quotes, and dollar signs.
+      # These are the only characters that are still specially
+      # interpreted inside of double-quoted scrings.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly in scan
+      # sets, so we specify it separately.
+      case "$lastarg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	lastarg="\"$lastarg\""
+	;;
+      esac
+
+      # Add the previous argument to base_compile.
+      if test -z "$base_compile"; then
+	base_compile="$lastarg"
+      else
+	base_compile="$base_compile $lastarg"
+      fi
+    done
+
+    case "$user_target" in
+    set)
+      ;;
+    no)
+      # Get the name of the library object.
+      libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+      ;;
+    *)
+      $echo "$modename: you must specify a target with \`-o'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    xform='[cCFSfmso]'
+    case "$libobj" in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case "$libobj" in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $libobj"
+    else
+      removelist="$libobj"
+    fi
+
+    $run $rm $removelist
+    trap "$run $rm $removelist; exit 1" 1 2 15
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+      removelist="$removelist $output_obj $lockfile"
+      trap "$run $rm $removelist; exit 1" 1 2 15
+    else
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until ln "$0" "$lockfile" 2>/dev/null; do
+	$show "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+	echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit 1
+      fi
+      echo $srcfile > "$lockfile"
+    fi
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      # All platforms use -DPIC, to notify preprocessed assembler code.
+      command="$base_compile $pic_flag -DPIC $srcfile"
+      if test "$build_old_libs" = yes; then
+	lo_libobj="$libobj"
+	dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+	if test "X$dir" = "X$libobj"; then
+	  dir="$objdir"
+	else
+	  dir="$dir/$objdir"
+	fi
+	libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+
+	if test -d "$dir"; then
+	  $show "$rm $libobj"
+	  $run $rm $libobj
+	else
+	  $show "$mkdir $dir"
+	  $run $mkdir $dir
+	  status=$?
+	  if test $status -ne 0 && test ! -d $dir; then
+	    exit $status
+	  fi
+	fi
+      fi
+      if test "$compiler_o_lo" = yes; then
+	output_obj="$libobj"
+	command="$command -o $output_obj"
+      elif test "$compiler_c_o" = yes; then
+	output_obj="$obj"
+	command="$command -o $output_obj"
+      fi
+
+      $run $rm "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+	test -n "$output_obj" && $run $rm $removelist
+	exit 1
+      fi
+
+      if test "$need_locks" = warn &&
+	 test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+	echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit 1
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test x"$output_obj" != x"$libobj"; then
+	$show "$mv $output_obj $libobj"
+	if $run $mv $output_obj $libobj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # If we have no pic_flag, then copy the object into place and finish.
+      if test -z "$pic_flag" && test "$build_old_libs" = yes; then
+	# Rename the .lo from within objdir to obj
+	if test -f $obj; then
+	  $show $rm $obj
+	  $run $rm $obj
+	fi
+
+	$show "$mv $libobj $obj"
+	if $run $mv $libobj $obj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+
+	# Now arrange that obj and lo_libobj become the same file
+	$show "$LN_S $obj $lo_libobj"
+	if $run $LN_S $obj $lo_libobj; then
+	  exit 0
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # Allow error messages only from the first compilation.
+      suppress_output=' >/dev/null 2>&1'
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      command="$base_compile $srcfile"
+      if test "$compiler_c_o" = yes; then
+	command="$command -o $obj"
+	output_obj="$obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      $run $rm "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+	$run $rm $removelist
+	exit 1
+      fi
+
+      if test "$need_locks" = warn &&
+	 test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+	echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit 1
+      fi
+
+      # Just move the object if needed
+      if test x"$output_obj" != x"$obj"; then
+	$show "$mv $output_obj $obj"
+	if $run $mv $output_obj $obj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # Create an invalid libtool object if no PIC, so that we do not
+      # accidentally link it into a program.
+      if test "$build_libtool_libs" != yes; then
+	$show "echo timestamp > $libobj"
+	$run eval "echo timestamp > \$libobj" || exit $?
+      else
+	# Move the .lo from within objdir
+	$show "$mv $libobj $lo_libobj"
+	if $run $mv $libobj $lo_libobj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+    fi
+
+    # Unlock the critical section if it was locked
+    if test "$need_locks" != no; then
+      $rm "$lockfile"
+    fi
+
+    exit 0
+    ;;
+
+  # libtool link mode
+  link)
+    modename="$modename: link"
+    C_compiler="$CC" # save it, to compile generated C sources
+    CC="$nonopt"
+    case "$host" in
+    *-*-cygwin* | *-*-mingw* | *-*-os2*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invokation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+
+      # This is a source program that is used to create dlls on Windows
+      # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# #  ifdef __CYGWIN32__
+# #    define __CYGWIN__ __CYGWIN32__
+# #  endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+#   __hDllInstance_base = hInst;
+#   return TRUE;
+# }
+# /* ltdll.c ends here */
+      # This is a source program that is used to create import libraries
+      # on Windows for dlls which lack them. Don't remove nor modify the
+      # starting and closing comments
+# /* impgen.c starts here */
+# /*   Copyright (C) 1999 Free Software Foundation, Inc.
+# 
+#  This file is part of GNU libtool.
+# 
+#  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.
+#  */
+# 
+#  #include <stdio.h>		/* for printf() */
+#  #include <unistd.h>		/* for open(), lseek(), read() */
+#  #include <fcntl.h>		/* for O_RDONLY, O_BINARY */
+#  #include <string.h>		/* for strdup() */
+# 
+#  static unsigned int
+#  pe_get16 (fd, offset)
+#       int fd;
+#       int offset;
+#  {
+#    unsigned char b[2];
+#    lseek (fd, offset, SEEK_SET);
+#    read (fd, b, 2);
+#    return b[0] + (b[1]<<8);
+#  }
+# 
+#  static unsigned int
+#  pe_get32 (fd, offset)
+#      int fd;
+#      int offset;
+#  {
+#    unsigned char b[4];
+#    lseek (fd, offset, SEEK_SET);
+#    read (fd, b, 4);
+#    return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+#  }
+# 
+#  static unsigned int
+#  pe_as32 (ptr)
+#       void *ptr;
+#  {
+#    unsigned char *b = ptr;
+#    return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+#  }
+# 
+#  int
+#  main (argc, argv)
+#      int argc;
+#      char *argv[];
+#  {
+#      int dll;
+#      unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+#      unsigned long export_rva, export_size, nsections, secptr, expptr;
+#      unsigned long name_rvas, nexp;
+#      unsigned char *expdata, *erva;
+#      char *filename, *dll_name;
+# 
+#      filename = argv[1];
+# 
+#      dll = open(filename, O_RDONLY|O_BINARY);
+#      if (!dll)
+#  	return 1;
+# 
+#      dll_name = filename;
+#    
+#      for (i=0; filename[i]; i++)
+#  	if (filename[i] == '/' || filename[i] == '\\'  || filename[i] == ':')
+#  	    dll_name = filename + i +1;
+# 
+#      pe_header_offset = pe_get32 (dll, 0x3c);
+#      opthdr_ofs = pe_header_offset + 4 + 20;
+#      num_entries = pe_get32 (dll, opthdr_ofs + 92);
+# 
+#      if (num_entries < 1) /* no exports */
+#  	return 1;
+# 
+#      export_rva = pe_get32 (dll, opthdr_ofs + 96);
+#      export_size = pe_get32 (dll, opthdr_ofs + 100);
+#      nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+#      secptr = (pe_header_offset + 4 + 20 +
+#  	      pe_get16 (dll, pe_header_offset + 4 + 16));
+# 
+#      expptr = 0;
+#      for (i = 0; i < nsections; i++)
+#      {
+#  	char sname[8];
+#  	unsigned long secptr1 = secptr + 40 * i;
+#  	unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+#  	unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+#  	unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+#  	lseek(dll, secptr1, SEEK_SET);
+#  	read(dll, sname, 8);
+#  	if (vaddr <= export_rva && vaddr+vsize > export_rva)
+#  	{
+#  	    expptr = fptr + (export_rva - vaddr);
+#  	    if (export_rva + export_size > vaddr + vsize)
+#  		export_size = vsize - (export_rva - vaddr);
+#  	    break;
+#  	}
+#      }
+# 
+#      expdata = (unsigned char*)malloc(export_size);
+#      lseek (dll, expptr, SEEK_SET);
+#      read (dll, expdata, export_size);
+#      erva = expdata - export_rva;
+# 
+#      nexp = pe_as32 (expdata+24);
+#      name_rvas = pe_as32 (expdata+32);
+# 
+#      printf ("EXPORTS\n");
+#      for (i = 0; i<nexp; i++)
+#      {
+#  	unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+#  	printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+#      }
+# 
+#      return 0;
+#  }
+# /* impgen.c ends here */
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    compile_command="$CC"
+    finalize_command="$CC"
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    linkopts=
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval lib_search_path=\`\$echo \"X \${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      lib_search_path=
+    fi
+    # now prepend the system-specific ones
+    eval lib_search_path=\"$sys_lib_search_path_spec\$lib_search_path\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+    
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    link_against_libtool_libs=
+    ltlibs=
+    module=no
+    objs=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case "$arg" in
+      -all-static | -static)
+	if test "X$arg" = "X-all-static"; then
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	else
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	fi
+	build_libtool_libs=no
+	build_old_libs=yes
+	prefer_static_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test $# -gt 0; do
+      arg="$1"
+      shift
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case "$prev" in
+	output)
+	  compile_command="$compile_command @OUTPUT@"
+	  finalize_command="$finalize_command @OUTPUT@"
+	  ;;
+	esac
+
+	case "$prev" in
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    compile_command="$compile_command @SYMFILE@"
+	    finalize_command="$finalize_command @SYMFILE@"
+	    preload=yes
+	  fi
+	  case "$arg" in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test "$dlself" = no; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test "$prev" = dlprefiles; then
+	      dlself=yes
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test "$prev" = dlfiles; then
+	      dlfiles="$dlfiles $arg"
+	    else
+	      dlprefiles="$dlprefiles $arg"
+	    fi
+	    prev=
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  if test ! -f "$arg"; then
+	    $echo "$modename: symbol file \`$arg' does not exist"
+	    exit 1
+	  fi
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  if test "$release_suffix" = all; then
+	    release="$arg"
+	  elif test "$release_suffix" = yes; then
+	    release="-$arg"
+	  fi
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case "$arg" in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    $echo "$modename: only absolute run-paths are allowed" 1>&2
+	    exit 1
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) rpath="$rpath $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) xrpath="$xrpath $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi
+
+      prevarg="$arg"
+
+      case "$arg" in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  compile_command="$compile_command $link_static_flag"
+	  finalize_command="$finalize_command $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	$echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+	continue
+	;;
+
+      -avoid-version)
+	build_old_libs=no
+	avoid_version=yes
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  $echo "$modename: not more than one -exported-symbols argument allowed"
+	  exit 1
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -L*)
+	dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+	# We need an absolute path.
+	case "$dir" in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  if test -z "$absdir"; then
+	    $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+	    $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+	    absdir="$dir"
+	  fi
+	  dir="$absdir"
+	  ;;
+	esac
+	case " $deplibs " in
+	*" $arg "*) ;;
+	*) deplibs="$deplibs $arg";;
+	esac
+	case " $lib_search_path " in
+	*" $dir "*) ;;
+	*) lib_search_path="$lib_search_path $dir";;
+	esac
+	case "$host" in
+	*-*-cygwin* | *-*-mingw* | *-*-os2*)
+	  dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+	  case ":$dllsearchpath:" in
+	  ::) dllsearchpath="$dllsearchdir";;
+	  *":$dllsearchdir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$dllsearchdir";;
+	  esac
+	  ;;
+	esac
+	;;
+
+      -l*)
+	if test "$arg" = "-lc"; then
+	  case "$host" in
+	  *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+	    # These systems don't actually have c library (as such)
+	    continue
+	    ;;
+	  esac
+	elif test "$arg" = "-lm"; then
+	  case "$host" in
+	  *-*-cygwin* | *-*-beos*)
+	    # These systems don't actually have math library (as such)
+	    continue
+	    ;;
+	  esac
+	fi
+	deplibs="$deplibs $arg"
+	;;
+
+      -?thread)
+	deplibs="$deplibs $arg"
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+	# We need an absolute path.
+	case "$dir" in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  $echo "$modename: only absolute run-paths are allowed" 1>&2
+	  exit 1
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) xrpath="$xrpath $dir" ;;
+	esac
+	continue
+	;;
+
+      -static)
+	# If we have no pic_flag, then this is the same as -all-static.
+	if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	  compile_command="$compile_command $link_static_flag"
+	  finalize_command="$finalize_command $link_static_flag"
+	fi
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+
+      # Some other compiler flag.
+      -* | +*)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case "$arg" in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	  arg="\"$arg\""
+	  ;;
+	esac
+	;;
+
+      *.o | *.obj | *.a | *.lib)
+	# A standard object.
+	libobjs="$libobjs $arg"
+	;;
+
+      *.lo)
+	# A library object.
+	if test "$prev" = dlfiles; then
+	  dlfiles="$dlfiles $arg"
+	  if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then
+	    prev=
+	    continue
+	  else
+	    # If libtool objects are unsupported, then we need to preload.
+	    prev=dlprefiles
+	  fi
+	fi
+
+	if test "$prev" = dlprefiles; then
+	  # Preload the old-style object.
+	  dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
+	  prev=
+	fi
+	libobjs="$libobjs $arg"
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	dlname=
+	libdir=
+	library_names=
+	old_library=
+
+	# Check to see that this really is a libtool archive.
+	if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
+	  exit 1
+	fi
+
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variable installed.
+	installed=yes
+
+	# Read the .la file
+	# If there is no directory component, then add one.
+	case "$arg" in
+	*/* | *\\*) . $arg ;;
+	*) . ./$arg ;;
+	esac
+
+	# Get the name of the library we link against.
+	linklib=
+	for l in $old_library $library_names; do
+	  linklib="$l"
+	done
+
+	if test -z "$linklib"; then
+	  $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
+	  exit 1
+	fi
+
+	# Find the relevant object directory and library name.
+	name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+
+	if test "X$installed" = Xyes; then
+	  dir="$libdir"
+	else
+	  dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+	  if test "X$dir" = "X$arg"; then
+	    dir="$objdir"
+	  else
+	    dir="$dir/$objdir"
+	  fi
+	fi
+
+	if test -n "$dependency_libs"; then
+	  # Extract -R and -L from dependency_libs
+	  temp_deplibs=
+	  for deplib in $dependency_libs; do
+	    case "$deplib" in
+	    -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+		 case " $rpath $xrpath " in
+		 *" $temp_xrpath "*) ;;
+		 *) xrpath="$xrpath $temp_xrpath";;
+		 esac;;
+	    -L*) case "$compile_command $temp_deplibs " in
+		 *" $deplib "*) ;;
+		 *) temp_deplibs="$temp_deplibs $deplib";;
+		 esac
+		 temp_dir=`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+		 case " $lib_search_path " in
+		 *" $temp_dir "*) ;;
+		 *) lib_search_path="$lib_search_path $temp_dir";;
+		 esac
+		 ;;
+	    *) temp_deplibs="$temp_deplibs $deplib";;
+	    esac
+	  done
+	  dependency_libs="$temp_deplibs"
+	fi
+
+	if test -z "$libdir"; then
+	  # It is a libtool convenience library, so add in its objects.
+	  convenience="$convenience $dir/$old_library"
+	  old_convenience="$old_convenience $dir/$old_library"
+	  deplibs="$deplibs$dependency_libs"
+	  compile_command="$compile_command $dir/$old_library$dependency_libs"
+	  finalize_command="$finalize_command $dir/$old_library$dependency_libs"
+	  continue
+	fi
+
+	# This library was specified with -dlopen.
+	if test "$prev" = dlfiles; then
+	  dlfiles="$dlfiles $arg"
+	  if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then
+	    # If there is no dlname, no dlopen support or we're linking statically,
+	    # we need to preload.
+	    prev=dlprefiles
+	  else
+	    # We should not create a dependency on this library, but we
+	    # may need any libraries it requires.
+	    compile_command="$compile_command$dependency_libs"
+	    finalize_command="$finalize_command$dependency_libs"
+	    prev=
+	    continue
+	  fi
+	fi
+
+	# The library was specified with -dlpreopen.
+	if test "$prev" = dlprefiles; then
+	  # Prefer using a static library (so that no silly _DYNAMIC symbols
+	  # are required to link).
+	  if test -n "$old_library"; then
+	    dlprefiles="$dlprefiles $dir/$old_library"
+	  else
+	    dlprefiles="$dlprefiles $dir/$linklib"
+	  fi
+	  prev=
+	fi
+
+	if test -n "$library_names" &&
+	   { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+	  link_against_libtool_libs="$link_against_libtool_libs $arg"
+	  if test -n "$shlibpath_var"; then
+	    # Make sure the rpath contains only unique directories.
+	    case "$temp_rpath " in
+	    *" $dir "*) ;;
+	    *) temp_rpath="$temp_rpath $dir" ;;
+	    esac
+	  fi
+
+	  # We need an absolute path.
+	  case "$dir" in
+	  [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+	  *)
+	    absdir=`cd "$dir" && pwd`
+	    if test -z "$absdir"; then
+	      $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+	      $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+	      absdir="$dir"
+	    fi
+	    ;;
+	  esac
+	  
+	  # This is the magic to use -rpath.
+	  # Skip directories that are in the system default run-time
+	  # search path, unless they have been requested with -R.
+	  case " $sys_lib_dlsearch_path " in
+	  *" $absdir "*) ;;
+	  *)
+	    case "$compile_rpath " in
+	    *" $absdir "*) ;;
+	    *) compile_rpath="$compile_rpath $absdir" 
+	    esac
+	    ;;
+	  esac
+
+	  case " $sys_lib_dlsearch_path " in
+	  *" $libdir "*) ;;
+	  *)
+	    case "$finalize_rpath " in
+	    *" $libdir "*) ;;
+	    *) finalize_rpath="$finalize_rpath $libdir"
+	    esac
+	    ;;
+	  esac
+
+	  lib_linked=yes
+	  case "$hardcode_action" in
+	  immediate | unsupported)
+	    if test "$hardcode_direct" = no; then
+	      compile_command="$compile_command $dir/$linklib"
+	      deplibs="$deplibs $dir/$linklib"
+	      case "$host" in
+	      *-*-cygwin* | *-*-mingw* | *-*-os2*)
+		dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+		if test -n "$dllsearchpath"; then
+		  dllsearchpath="$dllsearchpath:$dllsearchdir"
+		else
+		  dllsearchpath="$dllsearchdir"
+		fi
+		;;
+	      esac
+	    elif test "$hardcode_minus_L" = no; then
+	      case "$host" in
+	      *-*-sunos*)
+		compile_shlibpath="$compile_shlibpath$dir:"
+		;;
+	      esac
+	      case "$compile_command " in
+	      *" -L$dir "*) ;;
+	      *) compile_command="$compile_command -L$dir";;
+	      esac
+	      compile_command="$compile_command -l$name"
+	      deplibs="$deplibs -L$dir -l$name"
+	    elif test "$hardcode_shlibpath_var" = no; then
+	      case ":$compile_shlibpath:" in
+	      *":$dir:"*) ;;
+	      *) compile_shlibpath="$compile_shlibpath$dir:";;
+	      esac
+	      compile_command="$compile_command -l$name"
+	      deplibs="$deplibs -l$name"
+	    else
+	      lib_linked=no
+	    fi
+	    ;;
+
+	  relink)
+	    if test "$hardcode_direct" = yes; then
+	      compile_command="$compile_command $absdir/$linklib"
+	      deplibs="$deplibs $absdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      case "$compile_command " in
+	      *" -L$absdir "*) ;;
+	      *) compile_command="$compile_command -L$absdir";;
+	      esac
+	      compile_command="$compile_command -l$name"
+	      deplibs="$deplibs -L$absdir -l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
+	      case ":$compile_shlibpath:" in
+	      *":$absdir:"*) ;;
+	      *) compile_shlibpath="$compile_shlibpath$absdir:";;
+	      esac
+	      compile_command="$compile_command -l$name"
+	      deplibs="$deplibs -l$name"
+	    else
+	      lib_linked=no
+	    fi
+	    ;;
+
+	  *)
+	    lib_linked=no
+	    ;;
+	  esac
+
+	  if test "$lib_linked" != yes; then
+	    $echo "$modename: configuration error: unsupported hardcode properties"
+	    exit 1
+	  fi
+
+	  # Finalize command for both is simple: just hardcode it.
+	  if test "$hardcode_direct" = yes; then
+	    finalize_command="$finalize_command $libdir/$linklib"
+	  elif test "$hardcode_minus_L" = yes; then
+	    case "$finalize_command " in
+	    *" -L$libdir "*) ;;
+	    *) finalize_command="$finalize_command -L$libdir";;
+	    esac
+	    finalize_command="$finalize_command -l$name"
+	  elif test "$hardcode_shlibpath_var" = yes; then
+	    case ":$finalize_shlibpath:" in
+	    *":$libdir:"*) ;;
+	    *) finalize_shlibpath="$finalize_shlibpath$libdir:";;
+	    esac
+	    finalize_command="$finalize_command -l$name"
+	  else
+	    # We cannot seem to hardcode it, guess we'll fake it.
+	    case "$finalize_command " in
+	    *" -L$dir "*) ;;
+	    *) finalize_command="$finalize_command -L$libdir";;
+	    esac
+	    finalize_command="$finalize_command -l$name"
+	  fi
+	else
+	  # Transform directly to old archives if we don't build new libraries.
+	  if test -n "$pic_flag" && test -z "$old_library"; then
+	    $echo "$modename: cannot find static library for \`$arg'" 1>&2
+	    exit 1
+	  fi
+
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_command="$compile_command $dir/$linklib"
+	    finalize_command="$finalize_command $dir/$linklib"
+	  else
+	    case "$compile_command " in
+	    *" -L$dir "*) ;;
+	    *) compile_command="$compile_command -L$dir";;
+	    esac
+	    compile_command="$compile_command -l$name"
+	    case "$finalize_command " in
+	    *" -L$dir "*) ;;
+	    *) finalize_command="$finalize_command -L$dir";;
+	    esac
+	    finalize_command="$finalize_command -l$name"
+	  fi
+	fi
+
+	# Add in any libraries that this one depends upon.
+	compile_command="$compile_command$dependency_libs"
+	finalize_command="$finalize_command$dependency_libs"
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case "$arg" in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	  arg="\"$arg\""
+	  ;;
+	esac
+	;;
+      esac
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	compile_command="$compile_command $arg"
+	finalize_command="$finalize_command $arg"
+      fi
+    done
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+    libobjs_save="$libobjs"
+
+    case "$output" in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+      ;;
+
+    *.a | *.lib)
+      if test -n "$link_against_libtool_libs"; then
+	$echo "$modename: error: cannot link libtool libraries into archives" 1>&2
+	exit 1
+      fi
+
+      if test -n "$deplibs"; then
+	$echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+	$echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+	$echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	$echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+      fi
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      ;;
+
+    *.la)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case "$outputname" in
+      lib*)
+	name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	if test "$module" = no; then
+	  $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+	if test "$need_lib_prefix" != no; then
+	  # Add the "lib" prefix for modules if required
+	  name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+	  eval libname=\"$libname_spec\"
+	else
+	  libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+	fi
+	;;
+      esac
+
+      output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$output_objdir" = "X$output"; then
+	output_objdir="$objdir"
+      else
+	output_objdir="$output_objdir/$objdir"
+      fi
+
+      if test -n "$objs"; then
+	$echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+	exit 1
+      fi
+
+      # How the heck are we supposed to write a wrapper for a shared library?
+      if test -n "$link_against_libtool_libs"; then
+	 $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2
+	 exit 1
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2
+      fi
+
+      set dummy $rpath
+      if test $# -gt 2; then
+	$echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test "$build_libtool_libs" = yes; then
+	  # Building a libtool convenience library.
+	  libext=al
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+	dependency_libs="$deplibs"
+
+	if test -n "$vinfo"; then
+	  $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+	fi
+
+	if test -n "$release"; then
+	  $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+	fi
+      else
+
+	# Parse the version information argument.
+	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=':'
+	set dummy $vinfo 0 0 0
+	IFS="$save_ifs"
+
+	if test -n "$8"; then
+	  $echo "$modename: too many parameters to \`-version-info'" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+
+	current="$2"
+	revision="$3"
+	age="$4"
+
+	# Check that each of the things are valid numbers.
+	case "$current" in
+	0 | [1-9] | [1-9][0-9]*) ;;
+	*)
+	  $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	case "$revision" in
+	0 | [1-9] | [1-9][0-9]*) ;;
+	*)
+	  $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	case "$age" in
+	0 | [1-9] | [1-9][0-9]*) ;;
+	*)
+	  $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	if test $age -gt $current; then
+	  $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case "$version_type" in
+	none) ;;
+
+	irix)
+	  major=`expr $current - $age + 1`
+	  versuffix="$major.$revision"
+	  verstring="sgi$major.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test $loop != 0; do
+	    iface=`expr $revision - $loop`
+	    loop=`expr $loop - 1`
+	    verstring="sgi$major.$iface:$verstring"
+	  done
+	  ;;
+
+	linux)
+	  major=.`expr $current - $age`
+	  versuffix="$major.$age.$revision"
+	  ;;
+
+	osf)
+	  major=`expr $current - $age`
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test $loop != 0; do
+	    iface=`expr $current - $loop`
+	    loop=`expr $loop - 1`
+	    verstring="$verstring:${iface}.0"
+	  done
+
+	  # Make executables depend on our current version.
+	  verstring="$verstring:${current}.0"
+	  ;;
+
+	sunos)
+	  major=".$current"
+	  versuffix=".$current.$revision"
+	  ;;
+
+	freebsd-aout)
+	  major=".$current"
+	  versuffix=".$current.$revision";
+	  ;;
+
+	freebsd-elf)
+	  major=".$current"
+	  versuffix=".$current";
+	  ;;
+
+	windows)
+	  # Like Linux, but with '-' rather than '.', since we only
+	  # want one extension on Windows 95.
+	  major=`expr $current - $age`
+	  versuffix="-$major-$age-$revision"
+	  ;;
+
+	*)
+	  $echo "$modename: unknown library version type \`$version_type'" 1>&2
+	  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  verstring="0.0"
+	  if test "$need_version" = no; then
+	    versuffix=
+	  else
+	    versuffix=".0.0"
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test "$avoid_version" = yes && test "$need_version" = no; then
+	  major=
+	  versuffix=
+	  verstring=""
+	fi
+	
+	# Check to see if the archive will have undefined symbols.
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+	    build_libtool_libs=no
+	    build_old_libs=yes
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag="$no_undefined_flag"
+	fi
+
+	dependency_libs="$deplibs"
+	case "$host" in
+	*-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+	  # these systems don't actually have a c library (as such)!
+	  ;;
+	*-*-freebsd*)
+	  # FreeBSD doesn't need this...
+	  ;;
+	*)
+	  # Add libc to deplibs on all other systems.
+	  deplibs="$deplibs -lc"
+	  ;;
+	esac
+      fi
+
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$compile_rpath " in
+	  *" $libdir "*) ;;
+	  *) compile_rpath="$compile_rpath $libdir" ;;
+	  esac
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) perm_rpath="$perm_rpath $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      # Create the output directory, or remove our outputs if we need to.
+      if test -d $output_objdir; then
+	$show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
+	$run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+      else
+	$show "$mkdir $output_objdir"
+	$run $mkdir $output_objdir
+	status=$?
+	if test $status -ne 0 && test ! -d $output_objdir; then
+	  exit $status
+	fi
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+	if test "$release_suffix" = all; then
+	 oldlibs="$oldlibs $output_objdir/$libname$release.$libext"
+	else
+	 oldlibs="$oldlibs $output_objdir/$libname.$libext"
+	fi
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+      fi
+
+      if test "$build_libtool_libs" = yes; then
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=""
+	versuffix=""
+	major=""
+	newdeplibs=
+	droppeddeps=no
+	case "$deplibs_check_method" in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behaviour.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $rm conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $rm conftest
+	  $C_compiler -o conftest conftest.c $deplibs
+	  if test $? -eq 0 ; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      name="`expr $i : '-l\(.*\)'`"
+	      # If $name is empty we are operating on a -L argument.
+	      if test "$name" != "" ; then
+		libname=`eval \\$echo \"$libname_spec\"`
+		deplib_matches=`eval \\$echo \"$library_names_spec\"`
+		set dummy $deplib_matches
+		deplib_match=$2
+		if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		  newdeplibs="$newdeplibs $i"
+		else
+		  droppeddeps=yes
+		  echo
+		  echo "*** Warning: This library needs some functionality provided by $i."
+		  echo "*** I have the capability to make that library automatically link in when"
+		  echo "*** you link to this library.  But I can only do this if you have a"
+		  echo "*** shared version of the library, which you do not appear to have."
+		fi
+	      else
+		newdeplibs="$newdeplibs $i"
+	      fi
+	    done
+	  else
+	    # Error occured in the first compile.  Let's try to salvage the situation:
+	    # Compile a seperate program for each library.
+	    for i in $deplibs; do
+	      name="`expr $i : '-l\(.*\)'`"
+	     # If $name is empty we are operating on a -L argument.
+	      if test "$name" != "" ; then
+		$rm conftest
+		$C_compiler -o conftest conftest.c $i
+		# Did it work?
+		if test $? -eq 0 ; then
+		  ldd_output=`ldd conftest`
+		  libname=`eval \\$echo \"$libname_spec\"`
+		  deplib_matches=`eval \\$echo \"$library_names_spec\"`
+		  set dummy $deplib_matches
+		  deplib_match=$2
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		    newdeplibs="$newdeplibs $i"
+		  else
+		    droppeddeps=yes
+		    echo
+		    echo "*** Warning: This library needs some functionality provided by $i."
+		    echo "*** I have the capability to make that library automatically link in when"
+		    echo "*** you link to this library.  But I can only do this if you have a"
+		    echo "*** shared version of the library, which you do not appear to have."
+		  fi
+		else
+		  droppeddeps=yes
+		  echo
+		  echo "*** Warning!  Library $i is needed by this library but I was not able to"
+		  echo "***  make it link in!  You will probably need to install it or some"
+		  echo "*** library that it depends on before this library will be fully"
+		  echo "*** functional.  Installing it before continuing would be even better."
+		fi
+	      else
+		newdeplibs="$newdeplibs $i"
+	      fi
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method
+	  file_magic_regex="`expr \"$deplibs_check_method\" : \"$2 \(.*\)\"`"
+	  for a_deplib in $deplibs; do
+	    name="`expr $a_deplib : '-l\(.*\)'`"
+	    # If $name is empty we are operating on a -L argument.
+	    if test "$name" != "" ; then
+	      libname=`eval \\$echo \"$libname_spec\"`
+	      for i in $lib_search_path; do
+		    potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		    for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potent_lib" 2>/dev/null \
+			 | grep " -> " >/dev/null; then
+			continue 
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib="$potent_lib"
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | sed 's/.* -> //'`
+			case "$potliblink" in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+			 | sed 10q \
+			 | egrep "$file_magic_regex" > /dev/null; then
+			newdeplibs="$newdeplibs $a_deplib"
+			a_deplib=""
+			break 2
+		      fi
+		    done
+	      done
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		echo
+		echo "*** Warning: This library needs some functionality provided by $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have."
+	      fi
+	    else
+	      # Add a -L argument.
+	      newdeplibs="$newdeplibs $a_deplib"
+	    fi
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=""
+	  if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+	       -e 's/ -[LR][^ ]*//g' -e 's/[ 	]//g' |
+	     grep . >/dev/null; then
+	    echo
+	    if test "X$deplibs_check_method" = "Xnone"; then
+	      echo "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      echo "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    echo "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	  fi
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
+
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
+	    echo
+	    echo "*** Warning: libtool could not satisfy all declared inter-library"
+	    echo "*** dependencies of module $libname.  Therefore, libtool will create"
+	    echo "*** a static module, that should work as long as the dlopening"
+	    echo "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      echo
+	      echo "*** However, this would only work if libtool was able to extract symbol"
+	      echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+	      echo "*** not find such a program.  So, this module is probably useless."
+	      echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test "$build_old_libs" = no; then
+	      if test "$release_suffix" = all; then
+	        oldlibs="$output_objdir/$libname$release.$libext"
+	      else
+	        oldlibs="$output_objdir/$libname.$libext"
+	      fi
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    echo "*** The inter-library dependencies that have been dropped here will be"
+	    echo "*** automatically added whenever a program is linked with this library"
+	    echo "*** or is declared to -dlopen it."
+	  fi
+	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+      
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+	# Get the real and link names of the library.
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	realname="$2"
+	shift; shift
+
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
+	else
+	  soname="$realname"
+	fi
+
+	lib="$output_objdir/$realname"
+	for link
+	do
+	  linknames="$linknames $link"
+	done
+
+	# Ensure that we have .o objects for linkers which dislike .lo
+	# (e.g. aix) incase we are running --disable-static
+	for obj in $libobjs; do
+	  oldobj=`$echo "X$obj" | $Xsed -e "$lo2o"`
+	  if test ! -f $oldobj; then
+	    $show "${LN_S} $obj $oldobj"
+	    $run ${LN_S} $obj $oldobj || exit $?
+	  fi
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    $show "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $run $rm $export_symbols
+	    eval cmds=\"$export_symbols_cmds\"
+	    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+	    for cmd in $cmds; do
+	      IFS="$save_ifs"
+	      $show "$cmd"
+	      $run eval "$cmd" || exit $?
+	    done
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex"; then
+	      $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+	      $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+	      $run eval '$mv "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+	fi
+
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	  else
+	    gentop="$output_objdir/${outputname}x"
+	    $show "${rm}r $gentop"
+	    $run ${rm}r "$gentop"
+	    $show "mkdir $gentop"
+	    $run mkdir "$gentop"
+	    status=$?
+	    if test $status -ne 0 && test ! -d "$gentop"; then
+	      exit $status
+	    fi
+	    generated="$generated $gentop"
+
+	    for xlib in $convenience; do
+	      # Extract the objects.
+	      case "$xlib" in
+	      [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+	      *) xabs=`pwd`"/$xlib" ;;
+	      esac
+	      xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+	      xdir="$gentop/$xlib"
+
+	      $show "${rm}r $xdir"
+	      $run ${rm}r "$xdir"
+	      $show "mkdir $xdir"
+	      $run mkdir "$xdir"
+	      status=$?
+	      if test $status -ne 0 && test ! -d "$xdir"; then
+		exit $status
+	      fi
+	      $show "(cd $xdir && $AR x $xabs)"
+	      $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+	      libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+	    done
+	  fi
+	fi
+
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  linkopts="$linkopts $flag"
+	fi
+
+	# Do each of the archive commands.
+	if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	  eval cmds=\"$archive_expsym_cmds\"
+	else
+	  eval cmds=\"$archive_cmds\"
+	fi
+	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  $show "$cmd"
+	  $run eval "$cmd" || exit $?
+	done
+	IFS="$save_ifs"
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+	    $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+	  fi
+	done
+
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test "$module" = yes || test "$export_dynamic" = yes; then
+	  # On all known operating systems, these are identical.
+	  dlname="$soname"
+	fi
+      fi
+      ;;
+
+    *.lo | *.o | *.obj)
+      if test -n "$link_against_libtool_libs"; then
+	$echo "$modename: error: cannot link libtool libraries into objects" 1>&2
+	exit 1
+      fi
+
+      if test -n "$deplibs"; then
+	$echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+	$echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+	$echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+      fi
+
+      case "$output" in
+      *.lo)
+	if test -n "$objs"; then
+	  $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+	  exit 1
+	fi
+	libobj="$output"
+	obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+	;;
+      *)
+	libobj=
+	obj="$output"
+	;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec
+      wl= 
+
+      if test -n "$convenience"; then
+	if test -n "$whole_archive_flag_spec"; then
+	  eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+	else
+	  gentop="$output_objdir/${obj}x"
+	  $show "${rm}r $gentop"
+	  $run ${rm}r "$gentop"
+	  $show "mkdir $gentop"
+	  $run mkdir "$gentop"
+	  status=$?
+	  if test $status -ne 0 && test ! -d "$gentop"; then
+	    exit $status
+	  fi
+	  generated="$generated $gentop"
+
+	  for xlib in $convenience; do
+	    # Extract the objects.
+	    case "$xlib" in
+	    [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+	    *) xabs=`pwd`"/$xlib" ;;
+	    esac
+	    xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+	    xdir="$gentop/$xlib"
+
+	    $show "${rm}r $xdir"
+	    $run ${rm}r "$xdir"
+	    $show "mkdir $xdir"
+	    $run mkdir "$xdir"
+	    status=$?
+	    if test $status -ne 0 && test ! -d "$xdir"; then
+	      exit $status
+	    fi
+	    $show "(cd $xdir && $AR x $xabs)"
+	    $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+	    reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+	  done
+	fi
+      fi
+
+      # Create the old-style object.
+      reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs"
+
+      output="$obj"
+      eval cmds=\"$reload_cmds\"
+      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  $show "${rm}r $gentop"
+	  $run ${rm}r $gentop
+	fi
+
+	exit 0
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+	if test -n "$gentop"; then
+	  $show "${rm}r $gentop"
+	  $run ${rm}r $gentop
+	fi
+
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	$show "echo timestamp > $libobj"
+	$run eval "echo timestamp > $libobj" || exit $?
+	exit 0
+      fi
+
+      if test -n "$pic_flag"; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs $reload_conv_objs"
+	output="$libobj"
+	eval cmds=\"$reload_cmds\"
+	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  $show "$cmd"
+	  $run eval "$cmd" || exit $?
+	done
+	IFS="$save_ifs"
+      else
+	# Just create a symlink.
+	$show $rm $libobj
+	$run $rm $libobj
+	$show "$LN_S $obj $libobj"
+	$run $LN_S $obj $libobj || exit $?
+      fi
+
+      if test -n "$gentop"; then
+	$show "${rm}r $gentop"
+	$run ${rm}r $gentop
+      fi
+
+      exit 0
+      ;;
+
+    # Anything else should be a program.
+    *)
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+      fi
+
+      if test "$preload" = yes; then
+	if test "$dlopen" = unknown && test "$dlopen_self" = unknown &&
+	   test "$dlopen_self_static" = unknown; then
+	  $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+	fi 
+      fi
+    
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$compile_rpath " in
+	  *" $libdir "*) ;;
+	  *) compile_rpath="$compile_rpath $libdir" ;;
+	  esac
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) perm_rpath="$perm_rpath $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$output_objdir" = "X$output"; then
+	output_objdir="$objdir"
+      else
+	output_objdir="$output_objdir/$objdir"
+      fi
+
+      # Create the binary in the object directory, then wrap it.
+      if test ! -d $output_objdir; then
+	$show "$mkdir $output_objdir"
+	$run $mkdir $output_objdir
+	status=$?
+	if test $status -ne 0 && test ! -d $output_objdir; then
+	  exit $status
+	fi
+      fi
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+      fi
+
+      dlsyms=
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	  dlsyms="${outputname}S.c"
+	else
+	  $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+	fi
+      fi
+
+      if test -n "$dlsyms"; then
+	case "$dlsyms" in
+	"") ;;
+	*.c)
+	  # Discover the nlist of each of the dlfiles.
+	  nlist="$output_objdir/${outputname}.nm"
+
+	  $show "$rm $nlist ${nlist}S ${nlist}T"
+	  $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+	  # Parse the name list into a source file.
+	  $show "creating $output_objdir/$dlsyms"
+
+	  test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+	  if test "$dlself" = yes; then
+	    $show "generating symbol list for \`$output'"
+
+	    test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+	    # Add our own program objects to the symbol list.
+	    progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	    for arg in $progfiles; do
+	      $show "extracting global C symbols from \`$arg'"
+	      $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+	    done
+
+	    if test -n "$exclude_expsyms"; then
+	      $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      $run eval '$mv "$nlist"T "$nlist"'
+	    fi
+	    
+	    if test -n "$export_symbols_regex"; then
+	      $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      $run eval '$mv "$nlist"T "$nlist"'
+	    fi
+
+	    # Prepare the list of exported symbols
+	    if test -z "$export_symbols"; then
+	      export_symbols="$output_objdir/$output.exp"
+	      $run $rm $export_symbols
+	      $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	    else
+	      $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+	      $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+	      $run eval 'mv "$nlist"T "$nlist"'
+	    fi
+	  fi
+
+	  for arg in $dlprefiles; do
+	    $show "extracting global C symbols from \`$arg'"
+	    name=`echo "$arg" | sed -e 's%^.*/%%'`
+	    $run eval 'echo ": $name " >> "$nlist"'
+	    $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -z "$run"; then
+	    # Make sure we have at least an empty file.
+	    test -f "$nlist" || : > "$nlist"
+
+	    if test -n "$exclude_expsyms"; then
+	      egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	      $mv "$nlist"T "$nlist"
+	    fi
+
+	    # Try sorting and uniquifying the output.
+	    if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
+	      :
+	    else
+	      grep -v "^: " < "$nlist" > "$nlist"S
+	    fi
+
+	    if test -f "$nlist"S; then
+	      eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+	    else
+	      echo '/* NONE */' >> "$output_objdir/$dlsyms"
+	    fi
+
+	    $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+	    sed -n -e 's/^: \([^ ]*\) $/  {\"\1\", (lt_ptr_t) 0},/p' \
+		-e 's/^. \([^ ]*\) \([^ ]*\)$/  {"\2", (lt_ptr_t) \&\2},/p' \
+		  < "$nlist" >> "$output_objdir/$dlsyms"
+
+	    $echo >> "$output_objdir/$dlsyms" "\
+  {0, (lt_ptr_t) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	  fi
+
+	  pic_flag_for_symtable=
+	  case "$host" in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2*|*-*-freebsd3.0*)
+	    case "$compile_command " in
+	    *" -static "*) ;;
+	    *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
+	    esac
+	  esac
+
+	  # Now compile the dynamic symbol file.
+	  $show "(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+	  $run eval '(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+	  # Clean up the generated files.
+	  $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+	  $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+	  # Transform the symbol file into the correct name.
+	  compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+	  finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+	  ;;
+	*)
+	  $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+	  exit 1
+	  ;;
+	esac
+      else
+	# We keep going just in case the user didn't refer to
+	# lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+	# really was required.
+
+	# Nullify the symbol file.
+	compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+	finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+	# Replace the output file specification.
+	compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+	link_command="$compile_command$compile_rpath"
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	$show "$link_command"
+	$run eval "$link_command"
+	status=$?
+	
+	# Delete the generated files.
+	if test -n "$dlsyms"; then
+	  $show "$rm $output_objdir/${outputname}S.${objext}"
+	  $run $rm "$output_objdir/${outputname}S.${objext}"
+	fi
+
+	exit $status
+      fi
+
+      if test -n "$shlibpath_var"; then
+	# We should set the shlibpath_var
+	rpath=
+	for dir in $temp_rpath; do
+	  case "$dir" in
+	  [\\/]* | [A-Za-z]:[\\/]*)
+	    # Absolute path.
+	    rpath="$rpath$dir:"
+	    ;;
+	  *)
+	    # Relative path: add a thisdir entry.
+	    rpath="$rpath\$thisdir/$dir:"
+	    ;;
+	  esac
+	done
+	temp_rpath="$rpath"
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+      fi
+
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
+	
+	$echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+	$echo "$modename: \`$output' will be relinked during installation" 1>&2
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+      
+      # Delete the old output files.
+      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      $show "$link_command"
+      $run eval "$link_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Quote $echo for shipping.
+      if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+	case "$0" in
+	[\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
+	*) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+	esac
+	qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+      else
+	qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
+	esac
+	$rm $output
+	trap "$rm $output; exit 1" 1 2 15
+
+	$echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variable:
+  link_against_libtool_libs='$link_against_libtool_libs'
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    echo=\"$qecho\"
+    file=\"\$0\"
+    # Make sure echo works.
+    if test \"X\$1\" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+      # Yippee, \$echo works!
+      :
+    else
+      # Restart under the correct shell, and then maybe \$echo will work.
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+    fi
+  fi\
+"
+	$echo >> $output "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test "$fast_install" = yes; then
+	  echo >> $output "\
+  program=lt-'$outputname'
+  progdir=\"\$thisdir/$objdir\"
+  
+  if test ! -f \"\$progdir/\$program\" || \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $mkdir \"\$progdir\"
+    else
+      $rm \"\$progdir/\$file\"
+    fi"
+
+	  echo >> $output "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if (cd \"\$thisdir\" && eval \$relink_command); then :
+      else
+	$rm \"\$progdir/\$file\"
+	exit 1
+      fi
+    fi
+
+    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $rm \"\$progdir/\$program\";
+      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $rm \"\$progdir/\$file\"
+  fi"
+	else
+	  echo >> $output "\
+  program='$outputname$exeext'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	echo >> $output "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# Export our shlibpath_var if we have one.
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $echo >> $output "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	# fixup the dll searchpath if we need to.
+	if test -n "$dllsearchpath"; then
+	  $echo >> $output "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	$echo >> $output "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+"
+	case $host in
+	*-*-cygwin* | *-*-mingw | *-*-os2*)
+	  # win32 systems need to use the prog path for dll
+	  # lookup to work
+	  $echo >> $output "\
+      exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+	  ;;
+	*)
+	  $echo >> $output "\
+      # Export the path to the program.
+      PATH=\"\$progdir:\$PATH\"
+      export PATH
+
+      exec \$program \${1+\"\$@\"}
+"
+	  ;;
+	esac
+	$echo >> $output "\
+      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+    \$echo \"This script is just a wrapper for \$program.\" 1>&2
+    echo \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+	chmod +x $output
+      fi
+      exit 0
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
+	  build_libtool_libs=no
+	else
+	  oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+	fi
+	addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+	gentop="$output_objdir/${outputname}x"
+	$show "${rm}r $gentop"
+	$run ${rm}r "$gentop"
+	$show "mkdir $gentop"
+	$run mkdir "$gentop"
+	status=$?
+	if test $status -ne 0 && test ! -d "$gentop"; then
+	  exit $status
+	fi
+	generated="$generated $gentop"
+	  
+	# Add in members from convenience archives.
+	for xlib in $addlibs; do
+	  # Extract the objects.
+	  case "$xlib" in
+	  [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+	  *) xabs=`pwd`"/$xlib" ;;
+	  esac
+	  xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+	  xdir="$gentop/$xlib"
+
+	  $show "${rm}r $xdir"
+	  $run ${rm}r "$xdir"
+	  $show "mkdir $xdir"
+	  $run mkdir "$xdir"
+	  status=$?
+	  if test $status -ne 0 && test ! -d "$xdir"; then
+	    exit $status
+	  fi
+	  $show "(cd $xdir && $AR x $xabs)"
+	  $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+	  oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+	done
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+	eval cmds=\"$old_archive_from_new_cmds\"
+      else
+	# Ensure that we have .o objects in place incase we decided
+	# not to build a shared library, and have fallen back to building
+	# static libs even though --disable-static was passed!
+	for oldobj in $oldobjs; do
+	  if test ! -f $oldobj; then
+	    obj=`$echo "X$oldobj" | $Xsed -e "$o2lo"`
+	    $show "${LN_S} $obj $oldobj"
+	    $run ${LN_S} $obj $oldobj || exit $?
+	  fi
+	done
+
+	eval cmds=\"$old_archive_cmds\"
+      fi
+      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$generated"; then
+      $show "${rm}r$generated"
+      $run ${rm}r$generated
+    fi
+
+    # Now create the libtool archive.
+    case "$output" in
+    *.la)
+      old_library=
+      if test "$release_suffix" = all; then
+        test "$build_old_libs" = yes && old_library="$libname$release.$libext"
+      else
+        test "$build_old_libs" = yes && old_library="$libname.$libext"
+      fi
+      $show "creating $output"
+
+      if test -n "$xrpath"; then
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  temp_xrpath="$temp_xrpath -R$libdir"
+	done
+	dependency_libs="$temp_xrpath $dependency_libs"
+      fi
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+	for installed in no yes; do
+	  if test "$installed" = yes; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output="$output_objdir/$outputname"i
+	  fi
+	  $rm $output
+	  $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'\
+"
+	done
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+      $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $?
+      ;;
+    esac
+    exit 0
+    ;;
+
+  # libtool install mode
+  install)
+    modename="$modename: install"
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then
+      # Aesthetically quote it.
+      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	arg="\"$arg\""
+	;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg="$nonopt"
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+    case "$arg" in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+	files="$files $dest"
+	dest="$arg"
+	continue
+      fi
+
+      case "$arg" in
+      -d) isdir=yes ;;
+      -f) prev="-f" ;;
+      -g) prev="-g" ;;
+      -m) prev="-m" ;;
+      -o) prev="-o" ;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*) ;;
+
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  prev=
+	else
+	  dest="$arg"
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	arg="\"$arg\""
+	;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$modename: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	$echo "$modename: no file or destination specified" 1>&2
+      else
+	$echo "$modename: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test $# -gt 2; then
+	$echo "$modename: \`$dest' is not a directory" 1>&2
+	$echo "$help" 1>&2
+	exit 1
+      fi
+    fi
+    case "$destdir" in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case "$file" in
+	*.lo) ;;
+	*)
+	  $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case "$file" in
+      *.a | *.lib)
+	# Do the static libraries later.
+	staticlibs="$staticlibs $file"
+	;;
+
+      *.la)
+	# Check to see that this really is a libtool archive.
+	if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+
+	library_names=
+	old_library=
+	# If there is no directory component, then add one.
+	case "$file" in
+	*/* | *\\*) . $file ;;
+	*) . ./$file ;;
+	esac
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) current_libdirs="$current_libdirs $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) future_libdirs="$future_libdirs $libdir" ;;
+	  esac
+	fi
+
+	dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
+	test "X$dir" = "X$file/" && dir=
+	dir="$dir$objdir"
+
+	# See the names of the shared library.
+	set dummy $library_names
+	if test -n "$2"; then
+	  realname="$2"
+	  shift
+	  shift
+
+	  # Install the shared library and build the symlinks.
+	  $show "$install_prog $dir/$realname $destdir/$realname"
+	  $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+
+	  if test $# -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    for linkname
+	    do
+	      if test "$linkname" != "$realname"; then
+		$show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+		$run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+	      fi
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib="$destdir/$realname"
+	  eval cmds=\"$postinstall_cmds\"
+	  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+	  for cmd in $cmds; do
+	    IFS="$save_ifs"
+	    $show "$cmd"
+	    $run eval "$cmd" || exit $?
+	  done
+	  IFS="$save_ifs"
+	fi
+
+	# Install the pseudo-library for information purposes.
+	if test "$install_ltlibs" = yes; then
+	  name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	  instname="$dir/$name"i
+	  $show "$install_prog $instname $destdir/$name"
+	  $run eval "$install_prog $instname $destdir/$name" || exit $?
+	fi
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case "$destfile" in
+	*.lo)
+	  staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+	  ;;
+	*.o | *.obj)
+	  staticdest="$destfile"
+	  destfile=
+	  ;;
+	*)
+	  $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	if test -n "$destfile"; then
+	  $show "$install_prog $file $destfile"
+	  $run eval "$install_prog $file $destfile" || exit $?
+	fi
+
+	# Install the old object if enabled.
+	if test "$build_old_libs" = yes; then
+	  # Deduce the name of the old-style object file.
+	  staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+	  $show "$install_prog $staticobj $staticdest"
+	  $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+	fi
+	exit 0
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Do a test to see if this is really a libtool program.
+	if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  link_against_libtool_libs=
+	  relink_command=
+
+	  # If there is no directory component, then add one.
+	  case "$file" in
+	  */* | *\\*) . $file ;;
+	  *) . ./$file ;;
+	  esac
+
+	  # Check the variables that should have been set.
+	  if test -z "$link_against_libtool_libs"; then
+	    $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+	    exit 1
+	  fi
+
+	  finalize=yes
+	  for lib in $link_against_libtool_libs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      # If there is no directory component, then add one.
+	      case "$lib" in
+	      */* | *\\*) . $lib ;;
+	      *) . ./$lib ;;
+	      esac
+	    fi
+	    libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      finalize=no
+	    fi
+	  done
+
+	  outputname=
+	  if test "$fast_install" = no && test -n "$relink_command"; then
+	    if test "$finalize" = yes && test -z "$run"; then
+	      tmpdir="/tmp"
+	      test -n "$TMPDIR" && tmpdir="$TMPDIR"
+	      tmpdir="$tmpdir/libtool-$$"
+	      if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
+	      else
+		$echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+		continue
+	      fi
+	      outputname="$tmpdir/$file"
+	      # Replace the output file specification.
+	      relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+	      $show "$relink_command"
+	      if $run eval "$relink_command"; then :
+	      else
+		$echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+		${rm}r "$tmpdir"
+		continue
+	      fi
+	      file="$outputname"
+	    else
+	      $echo "$modename: warning: cannot relink \`$file'" 1>&2
+	    fi
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	$show "$install_prog$stripme $file $destfile"
+	$run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+	test -n "$outputname" && ${rm}r "$tmpdir"
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      # Do each command in the postinstall commands.
+      eval cmds=\"$old_postinstall_cmds\"
+      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec $SHELL $0 --finish$current_libdirs
+      exit 1
+    fi
+
+    exit 0
+    ;;
+
+  # libtool finish mode
+  finish)
+    modename="$modename: finish"
+    libdirs="$nonopt"
+    admincmds=
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+	libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  eval cmds=\"$finish_cmds\"
+	  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+	  for cmd in $cmds; do
+	    IFS="$save_ifs"
+	    $show "$cmd"
+	    $run eval "$cmd" || admincmds="$admincmds
+       $cmd"
+	  done
+	  IFS="$save_ifs"
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $run eval "$cmds" || admincmds="$admincmds
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    test "$show" = : && exit 0
+
+    echo "----------------------------------------------------------------------"
+    echo "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      echo "   $libdir"
+    done
+    echo
+    echo "If you ever happen to want to link against installed libraries"
+    echo "in a given directory, LIBDIR, you must either use libtool, and"
+    echo "specify the full pathname of the library, or use \`-LLIBDIR'"
+    echo "flag during linking and do at least one of the following:"
+    if test -n "$shlibpath_var"; then
+      echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      echo "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+      echo "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      echo "   - use the \`$flag' linker flag"
+    fi
+    if test -n "$admincmds"; then
+      echo "   - have your system administrator run these commands:$admincmds"
+    fi
+    if test -f /etc/ld.so.conf; then
+      echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    echo
+    echo "See any operating system documentation about shared libraries for"
+    echo "more information, such as the ld(1) and ld.so(8) manual pages."
+    echo "----------------------------------------------------------------------"
+    exit 0
+    ;;
+
+  # libtool execute mode
+  execute)
+    modename="$modename: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$modename: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit 1
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test ! -f "$file"; then
+	$echo "$modename: \`$file' is not a file" 1>&2
+	$echo "$help" 1>&2
+	exit 1
+      fi
+
+      dir=
+      case "$file" in
+      *.la)
+	# Check to see that this really is a libtool archive.
+	if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+
+	# If there is no directory component, then add one.
+	case "$file" in
+	*/* | *\\*) . $file ;;
+	*) . ./$file ;;
+	esac
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$dir" = "X$file" && dir=.
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  dir="$dir/$objdir"
+	else
+	  $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+	  exit 1
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$dir" = "X$file" && dir=.
+	;;
+
+      *)
+	$echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case "$file" in
+      -*) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  # If there is no directory component, then add one.
+	  case "$file" in
+	  */* | *\\*) . $file ;;
+	  *) . ./$file ;;
+	  esac
+
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      # Export the shlibpath_var.
+      eval "export $shlibpath_var"
+
+      # Restore saved enviroment variables
+      if test "${save_LC_ALL+set}" = set; then
+	LC_ALL="$save_LC_ALL"; export LC_ALL
+      fi
+      if test "${save_LANG+set}" = set; then
+	LANG="$save_LANG"; export LANG
+      fi
+
+      # Now actually exec the command.
+      eval "exec \$cmd$args"
+
+      $echo "$modename: cannot exec \$cmd$args"
+      exit 1
+    else
+      # Display what would be done.
+      eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+      $echo "export $shlibpath_var"
+      $echo "$cmd$args"
+      exit 0
+    fi
+    ;;
+
+  # libtool uninstall mode
+  uninstall)
+    modename="$modename: uninstall"
+    rm="$nonopt"
+    files=
+
+    for arg
+    do
+      case "$arg" in
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$modename: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    for file in $files; do
+      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$dir" = "X$file" && dir=.
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      rmfiles="$file"
+
+      case "$name" in
+      *.la)
+	# Possibly a libtool archive, so verify it.
+	if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  . $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    rmfiles="$rmfiles $dir/$n"
+	  done
+	  test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+	  $show "$rm $rmfiles"
+	  $run $rm $rmfiles
+
+	  if test -n "$library_names"; then
+	    # Do each command in the postuninstall commands.
+	    eval cmds=\"$postuninstall_cmds\"
+	    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+	    for cmd in $cmds; do
+	      IFS="$save_ifs"
+	      $show "$cmd"
+	      $run eval "$cmd"
+	    done
+	    IFS="$save_ifs"
+	  fi
+
+	  if test -n "$old_library"; then
+	    # Do each command in the old_postuninstall commands.
+	    eval cmds=\"$old_postuninstall_cmds\"
+	    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+	    for cmd in $cmds; do
+	      IFS="$save_ifs"
+	      $show "$cmd"
+	      $run eval "$cmd"
+	    done
+	    IFS="$save_ifs"
+	  fi
+
+	  # FIXME: should reinstall the best remaining shared library.
+	fi
+	;;
+
+      *.lo)
+	if test "$build_old_libs" = yes; then
+	  oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
+	  rmfiles="$rmfiles $dir/$oldobj"
+	fi
+	$show "$rm $rmfiles"
+	$run $rm $rmfiles
+	;;
+
+      *)
+	$show "$rm $rmfiles"
+	$run $rm $rmfiles
+	;;
+      esac
+    done
+    exit 0
+    ;;
+
+  "")
+    $echo "$modename: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit 1
+    ;;
+  esac
+
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$generic_help" 1>&2
+  exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+    --config          show all configuration variables
+    --debug           enable verbose shell tracing
+-n, --dry-run         display commands without modifying any files
+    --features        display basic configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --version         print version information
+
+MODE must be one of the following:
+
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+  exit 0
+  ;;
+
+compile)
+  $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -static           always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+  ;;
+
+execute)
+  $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+  ;;
+
+finish)
+  $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+  ;;
+
+install)
+  $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+  ;;
+
+link)
+  $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+		    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+		    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+		    specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+  ;;
+
+uninstall)
+  $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+*)
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+  ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/config.sub
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/config.sub	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/config.sub	Sat Jul 13 21:26:07 2002
@@ -0,0 +1,1215 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+#   Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# 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.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+	echo Configuration name missing. 1>&2
+	echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+	echo "or     $0 ALIAS" 1>&2
+	echo where ALIAS is a recognized configuration type. 1>&2
+	exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+	*local*)
+		echo $1
+		exit 0
+		;;
+	*)
+	;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  linux-gnu*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=vxworks
+		basic_machine=$1
+		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+		| arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
+		| 580 | i960 | h8300 \
+		| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+		| alpha | alphaev[4-7] | alphaev56 | alphapca5[67] \
+		| we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
+		| 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
+		| mips64orion | mips64orionel | mipstx39 | mipstx39el \
+		| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
+		| mips64vr5000 | miprs64vr5000el \
+		| sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
+		| thumb | d10v)
+		basic_machine=$basic_machine-unknown
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i[34567]86)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
+	      | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+	      | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+	      | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
+	      | xmp-* | ymp-* \
+	      | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \
+	      | alpha-* | alphaev[4-7]-* | alphaev56-* | alphapca5[67]-* \
+	      | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
+	      | clipper-* | orion-* \
+	      | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+	      | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
+	      | mips64el-* | mips64orion-* | mips64orionel-* \
+	      | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
+	      | mipstx39-* | mipstx39el-* \
+	      | f301-* | armv*-* | t3e-* \
+	      | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
+	      | thumb-* | v850-* | d30v-* | tic30-* | c30-* )
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-cbm
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-cbm
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-cbm
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	cray2)
+		basic_machine=cray2-cray
+		os=-unicos
+		;;
+	[ctj]90-cray)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i[34567]86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i[34567]86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i[34567]86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i[34567]86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	i386-go32 | go32)
+		basic_machine=i386-unknown
+		os=-go32
+		;;
+	i386-mingw32 | mingw32)
+		basic_machine=i386-unknown
+		os=-mingw32
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | *MiNT)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mipsel*-linux*)
+		basic_machine=mipsel-unknown
+		os=-linux-gnu
+		;;
+	mips*-linux*)
+		basic_machine=mips-unknown
+		os=-linux-gnu
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	msdos)
+		basic_machine=i386-unknown
+		os=-msdos
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-corel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+        pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexen)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexen-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=rs6000-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+	        ;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+	        ;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sparclite-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=t3e-cray
+		os=-unicos
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xmp)
+		basic_machine=xmp-cray
+		os=-unicos
+		;;
+        xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	mips)
+		if [ x$os = x-linux-gnu ]; then
+			basic_machine=mips-unknown
+		else
+			basic_machine=mips-mips
+		fi
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sparc | sparcv9)
+		basic_machine=sparc-sun
+		;;
+        cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	c4x*)
+		basic_machine=c4x-none
+		os=-coff
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -rhapsody* | -openstep* | -oskit*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-ns2 )
+	        os=-nextstep2
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+        -*mint | -*MiNT)
+	        os=-mint
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-corel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+        *-gould)
+		os=-sysv
+		;;
+        *-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+        *-sgi)
+		os=-irix
+		;;
+        *-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f301-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-vxsim* | -vxworks*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -*MiNT)
+				vendor=atari
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/fastgen.sh
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/fastgen.sh	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/fastgen.sh	Sat Jul 13 21:26:07 2002
@@ -0,0 +1,58 @@
+#! /bin/sh
+#
+# Copyright (c) 1999, 2000 Sascha Schumann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code 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.
+# 
+# THIS SOFTWARE IS PROVIDED BY SASCHA SCHUMANN ``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 REGENTS OR CONTRIBUTORS 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.
+#
+##############################################################################
+# $Id: fastgen.sh,v 1.7 2000/06/11 10:33:39 sas Exp $ 
+#
+
+srcdir=$1
+shift
+
+mkdir_p=$1
+shift
+
+top_srcdir=`(cd $srcdir; pwd)`
+top_builddir=`pwd`
+
+if test "$mkdir_p" = "yes"; then
+  mkdir_p="mkdir -p"
+else
+  mkdir_p="$top_srcdir/helpers/mkdir.sh"
+fi
+
+for makefile in $@; do
+  echo "creating $makefile"
+  dir=`echo $makefile|sed 's%/*[^/][^/]*$%%'`
+  $mkdir_p "$dir/"
+
+  cat - $top_srcdir/$makefile.in <<EOF >$makefile
+top_srcdir   = $top_srcdir
+top_builddir = $top_builddir
+srcdir       = $top_srcdir/$dir
+builddir     = $top_builddir/$dir
+VPATH        = $top_srcdir/$dir
+EOF
+  
+  test -z "$dir" || touch $dir/.deps
+done

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/rules.mk
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/rules.mk	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/rules.mk	Sat Jul 13 21:26:07 2002
@@ -0,0 +1,116 @@
+# Copyright (c) 1999, 2000 Sascha Schumann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code 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.
+# 
+# THIS SOFTWARE IS PROVIDED BY SASCHA SCHUMANN ``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 REGENTS OR CONTRIBUTORS 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.
+#
+##############################################################################
+# $Id: rules_pear.mk,v 1.9 2000/06/11 19:53:19 rasmus Exp $ 
+#
+
+include $(top_builddir)/config_vars.mk
+
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(EXTRA_INCLUDES) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(EXTRA_INCLUDES) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(CFLAGS) $(EXTRA_CFLAGS) $(LDFLAGS) -o $@
+mkinstalldirs = $(top_srcdir)/build/shtool mkdir -f -p
+INSTALL = $(top_srcdir)/build/shtool install -c
+INSTALL_DATA = $(INSTALL) -m 644
+SHARED_COMPILE = $(SHARED_LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(EXTRA_INCLUDES) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< && touch $@
+DEFS = -DHAVE_CONFIG_H -I. -I$(srcdir) -I$(top_builddir) -I$(top_builddir)/main
+
+moduledir    = $(EXTENSION_DIR)
+
+.SUFFIXES:
+.SUFFIXES: .slo .c .lo .o .s .y .l
+
+.c.o:
+	$(COMPILE) -c $<
+
+.s.o:
+	$(COMPILE) -c $<
+
+.c.lo:
+	$(PHP_COMPILE)
+
+.s.lo:
+	$(PHP_COMPILE)
+
+.c.slo:
+	$(SHARED_COMPILE)
+
+.y.c:
+	$(YACC) $(YFLAGS) $< && mv y.tab.c $*.c
+	if test -f y.tab.h; then \
+	if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \
+	else :; fi
+
+.l.c:
+	$(LEX) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@
+
+install_targets = install-modules
+
+all: all-recursive
+install: install-recursive
+
+distclean-recursive depend-recursive clean-recursive all-recursive install-recursive:
+	@otarget=`echo $@|sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for i in $$list; do \
+		target="$$otarget"; \
+		echo "Making $$target in $$i"; \
+		if test "$$i" = "."; then \
+			ok=yes; \
+			target="$$target-p"; \
+		fi; \
+		(cd $$i && $(MAKE) $$target) || exit 1; \
+	done; \
+	if test "$$otarget" = "all" && test -z '$(targets)'; then ok=yes; fi; \
+	if test "$$ok" != "yes"; then $(MAKE) "$$otarget-p" || exit 1; fi
+
+all-p: $(targets)
+install-p: $(targets) $(install_targets)
+distclean-p depend-p clean-p:
+
+depend: depend-recursive
+	test "`echo *.c`" = '*.c' || perl $(top_srcdir)/build/mkdep.perl $(CPP) $(INCLUDES) $(EXTRA_INCLUDES) *.c > $(builddir)/.deps
+
+clean: clean-recursive clean-x
+
+clean-x:
+	rm -f $(targets) *.lo *.slo *.la *.o $(CLEANFILES)
+	rm -rf .libs
+
+distclean: distclean-recursive clean-x
+	rm -f config.cache config.log config.status config_vars.mk libtool \
+	php_config.h stamp-h Makefile build-defs.h php4.spec libphp4.module
+
+install-modules:
+	@test -d modules && \
+	$(mkinstalldirs) $(moduledir) && \
+	echo "installing shared modules into $(moduledir)" && \
+	rm -f modules/*.la && \
+	cp modules/* $(moduledir) || true
+
+include $(builddir)/.deps
+
+.PHONY: all-recursive clean-recursive install-recursive \
+$(install_targets) install all clean depend depend-recursive shared \
+distclean-recursive distclean clean-x all-p install-p distclean-p \
+depend-p clean-p

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/dynlib.mk
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/dynlib.mk	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/dynlib.mk	Sat Jul 13 21:26:07 2002
@@ -0,0 +1,5 @@
+all: all-recursive
+
+include $(builddir)/libs.mk
+
+include $(top_srcdir)/build/rules.mk

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/shtool
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/shtool	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/shtool	Sat Jul 13 21:26:08 2002
@@ -0,0 +1,716 @@
+#!/bin/sh
+##
+##  GNU shtool -- The GNU Portable Shell Tool
+##  Copyright (c) 1994-2000 Ralf S. Engelschall <rse at engelschall.com>
+##
+##  See http://www.gnu.org/software/shtool/ for more information.
+##  See ftp://ftp.gnu.org/gnu/shtool/ for latest version.
+##
+##  Version 1.4.9 (16-Apr-2000)
+##  Ingredients: 3/17 available modules
+##
+
+##
+##  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, or contact Ralf S. Engelschall <rse at engelschall.com>.
+##
+##  Notice: Given that you include this file verbatim into your own
+##  source tree, you are justified in saying that it remains separate
+##  from your package, and that this way you are simply just using GNU
+##  shtool. So, in this situation, there is no requirement that your
+##  package itself is licensed under the GNU General Public License in
+##  order to take advantage of GNU shtool.
+##
+
+##
+##  Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]
+##
+##  Available commands:
+##    echo       Print string with optional construct expansion
+##    install    Install a program, script or datafile
+##    mkdir      Make one or more directories
+##
+##  Not available commands (because module was not built-in):
+##    mdate      Pretty-print modification time of a file or dir
+##    table      Pretty-print a field-separated list as a table
+##    prop       Display progress with a running propeller
+##    move       Move files with simultaneous substitution
+##    mkln       Make link with calculation of relative paths
+##    mkshadow   Make a shadow tree through symbolic links
+##    fixperm    Fix file permissions inside a source tree
+##    tarball    Roll distribution tarballs
+##    guessos    Simple operating system guesser
+##    arx        Extended archive command
+##    slo        Separate linker options by library class
+##    scpp       Sharing C Pre-Processor
+##    version    Generate and maintain a version information file
+##    path       Deal with program paths
+##
+
+if [ $# -eq 0 ]; then
+    echo "$0:Error: invalid command line" 1>&2
+    echo "$0:Hint:  run \`$0 -h' for usage" 1>&2
+    exit 1
+fi
+if [ ".$1" = ".-h" -o ".$1" = ".--help" ]; then
+    echo "This is GNU shtool, version 1.4.9 (16-Apr-2000)"
+    echo "Copyright (c) 1994-2000 Ralf S. Engelschall <rse at engelschall.com>"
+    echo "Report bugs to <bug-shtool at gnu.org>"
+    echo ''
+    echo "Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]" 
+    echo ''
+    echo 'Available global <options>:'
+    echo '  -v, --version   display shtool version information'
+    echo '  -h, --help      display shtool usage help page (this one)'
+    echo '  -d, --debug     display shell trace information'
+    echo ''
+    echo 'Available <cmd-name> [<cmd-options>] [<cmd-args>]:'
+    echo '  echo     [-n] [-e] [<str> ...]'
+    echo '  install  [-v] [-t] [-c] [-C] [-s] [-m<mode>] [-o<owner>] [-g<group>]'
+    echo '           [-e<ext>] <file> <path>'
+    echo '  mkdir    [-t] [-f] [-p] [-m<mode>] <dir> [<dir> ...]'
+    echo ''
+    echo 'Not available <cmd-name> (because module was not built-in):'
+    echo '  mdate    [-n] [-z] [-s] [-d] [-f<str>] [-o<spec>] <path>'
+    echo '  table    [-F<sep>] [-w<width>] [-c<cols>] [-s<strip>] <str><sep><str>...'
+    echo '  prop     [-p<str>]'
+    echo '  move     [-v] [-t] [-e] [-p] <src-file> <dst-file>'
+    echo '  mkln     [-t] [-f] [-s] <src-path> [<src-path> ...] <dst-path>'
+    echo '  mkshadow [-v] [-t] [-a] <src-dir> <dst-dir>'
+    echo '  fixperm  [-v] [-t] <path> [<path> ...]'
+    echo '  tarball  [-t] [-v] [-o <tarball>] [-c <prog>] [-d <dir>] [-u'
+    echo '           <user>] [-g <group>] [-e <pattern>] <path> [<path> ...]'
+    echo '  guessos  '
+    echo '  arx      [-t] [-C<cmd>] <op> <archive> [<file> ...]'
+    echo '  slo      [-p<str>] -- -L<dir> -l<lib> [-L<dir> -l<lib> ...]'
+    echo '  scpp     [-v] [-p] [-f<filter>] [-o<ofile>] [-t<tfile>] [-M<mark>]'
+    echo '           [-D<dname>] [-C<cname>] <file> [<file> ...]'
+    echo '  version  [-l<lang>] [-n<name>] [-p<prefix>] [-s<version>] [-i<knob>]'
+    echo '           [-d<type>] <file>'
+    echo '  path     [-s] [-r] [-d] [-b] [-m] [-p<path>] <str> [<str> ...]'
+    echo ''
+    exit 0
+fi
+if [ ".$1" = ".-v" -o ".$1" = ."--version" ]; then
+    echo "GNU shtool 1.4.9 (16-Apr-2000)"
+    exit 0
+fi
+if [ ".$1" = ".-d" -o ".$1" = ."--debug" ]; then
+    shift
+    set -x
+fi
+name=`echo "$0" | sed -e 's;.*/\([^/]*\)$;\1;' -e 's;-sh$;;' -e 's;\.sh$;;'`
+case "$name" in
+    echo|install|mkdir )
+        #   implicit tool command selection
+        tool="$name"
+        ;;
+    * )
+        #   explicit tool command selection
+        tool="$1"
+        shift
+        ;;
+esac
+arg_spec=""
+opt_spec=""
+gen_tmpfile=no
+
+##
+##  DISPATCH INTO SCRIPT PROLOG
+##
+
+case $tool in
+    echo )
+        str_tool="echo"
+        str_usage="[-n] [-e] [<str> ...]"
+        arg_spec="0+"
+        opt_spec="n.e."
+        opt_n=no
+        opt_e=no
+        ;;
+    install )
+        str_tool="install"
+        str_usage="[-v] [-t] [-c] [-C] [-s] [-m<mode>] [-o<owner>] [-g<group>] [-e<ext>] <file> <path>"
+        arg_spec="2="
+        opt_spec="v.t.c.C.s.m:o:g:e:"
+        opt_v=no
+        opt_t=no
+        opt_c=no
+        opt_C=no
+        opt_s=no
+        opt_m=""
+        opt_o=""
+        opt_g=""
+        opt_e=""
+        ;;
+    mkdir )
+        str_tool="mkdir"
+        str_usage="[-t] [-f] [-p] [-m<mode>] <dir> [<dir> ...]"
+        arg_spec="1+"
+        opt_spec="t.f.p.m:"
+        opt_t=no
+        opt_f=no
+        opt_p=no
+        opt_m=""
+        ;;
+    -* )
+        echo "$0:Error: unknown option \`$tool'" 2>&1
+        echo "$0:Hint:  run \`$0 -h' for usage" 2>&1
+        exit 1
+        ;;
+    * )
+        echo "$0:Error: unknown command \`$tool'" 2>&1
+        echo "$0:Hint:  run \`$0 -h' for usage" 2>&1
+        exit 1
+        ;;
+esac
+
+##
+##  COMMON UTILITY CODE
+##
+
+#   determine name of tool
+if [ ".$tool" != . ]; then
+    #   used inside shtool script
+    toolcmd="$0 $tool"
+    toolcmdhelp="shtool $tool"
+    msgprefix="shtool:$tool"
+else
+    #   used as standalone script
+    toolcmd="$0"
+    toolcmdhelp="sh $0"
+    msgprefix="$str_tool"
+fi
+
+#   parse argument specification string
+eval `echo $arg_spec |\
+      sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
+
+#   parse option specification string
+eval `echo h.$opt_spec |\
+      sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
+
+#   interate over argument line
+opt_PREV=''
+while [ $# -gt 0 ]; do
+    #   special option stops processing
+    if [ ".$1" = ".--" ]; then
+        shift
+        break
+    fi
+
+    #   determine option and argument
+    opt_ARG_OK=no
+    if [ ".$opt_PREV" != . ]; then
+        #   merge previous seen option with argument
+        opt_OPT="$opt_PREV"
+        opt_ARG="$1"
+        opt_ARG_OK=yes
+        opt_PREV=''
+    else
+        #   split argument into option and argument
+        case "$1" in
+            -[a-zA-Z0-9]*)
+                eval `echo "x$1" |\
+                      sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
+                          -e 's/";\(.*\)$/"; opt_ARG="\1"/'`
+                ;;
+            -[a-zA-Z0-9])
+                opt_OPT=`echo "x$1" | cut -c3-`
+                opt_ARG=''
+                ;;
+            *)
+                break
+                ;;
+        esac
+    fi
+
+    #   eat up option
+    shift
+
+    #   determine whether option needs an argument
+    eval "opt_MODE=\$opt_MODE_${opt_OPT}"
+    if [ ".$opt_ARG" = . -a ".$opt_ARG_OK" != .yes ]; then
+        if [ ".$opt_MODE" = ".:" -o ".$opt_MODE" = ".+" ]; then
+            opt_PREV="$opt_OPT"
+            continue
+        fi
+    fi
+
+    #   process option
+    case $opt_MODE in
+        '.' )
+            #   boolean option
+            eval "opt_${opt_OPT}=yes"
+            ;;
+        ':' )
+            #   option with argument (multiple occurances override)
+            eval "opt_${opt_OPT}=\"\$opt_ARG\""
+            ;;
+        '+' )
+            #   option with argument (multiple occurances append)
+            eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\""
+            ;;
+        * )
+            echo "$msgprefix:Error: unknown option: \`-$opt_OPT'" 1>&2
+            echo "$msgprefix:Hint:  run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2
+            exit 1
+            ;;
+    esac
+done
+if [ ".$opt_PREV" != . ]; then
+    echo "$msgprefix:Error: missing argument to option \`-$opt_PREV'" 1>&2
+    echo "$msgprefix:Hint:  run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2
+    exit 1
+fi
+
+#   process help option
+if [ ".$opt_h" = .yes ]; then
+    echo "Usage: $toolcmdhelp $str_usage"
+    exit 0
+fi
+
+#   complain about incorrect number of arguments
+case $arg_MODE in
+    '=' )
+        if [ $# -ne $arg_NUMS ]; then
+            echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
+            echo "$msgprefix:Hint:  run \`$toolcmd -h' or \`man shtool' for details" 1>&2
+            exit 1
+        fi
+        ;;
+    '+' )
+        if [ $# -lt $arg_NUMS ]; then
+            echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
+            echo "$msgprefix:Hint:  run \`$toolcmd -h' or \`man shtool' for details" 1>&2
+            exit 1
+        fi
+        ;;
+esac
+
+#   establish a temporary file on request
+if [ ".$gen_tmpfile" = .yes ]; then
+    if [ ".$TMPDIR" != . ]; then
+        tmpdir="$TMPDIR"
+    elif [ ".$TEMPDIR" != . ]; then
+        tmpdir="$TEMPDIR"
+    else
+        tmpdir="/tmp"
+    fi
+    tmpfile="$tmpdir/.shtool.$$"
+    rm -f $tmpfile >/dev/null 2>&1
+    touch $tmpfile
+fi
+
+##
+##  DISPATCH INTO SCRIPT BODY
+##
+
+case $tool in
+
+echo )
+    ##
+    ##  echo -- Print string with optional construct expansion
+    ##  Copyright (c) 1998-2000 Ralf S. Engelschall <rse at engelschall.com>
+    ##  Originally written for WML as buildinfo
+    ##
+    
+    text="$*"
+    
+    #   check for broken escape sequence expansion
+    seo=''
+    bytes=`echo '\1' | wc -c | awk '{ printf("%s", $1); }'`
+    if [ ".$bytes" != .3 ]; then
+        bytes=`echo -E '\1' | wc -c | awk '{ printf("%s", $1); }'`
+        if [ ".$bytes" = .3 ]; then
+            seo='-E'
+        fi
+    fi
+    
+    #   check for existing -n option (to suppress newline)
+    minusn=''
+    bytes=`echo -n 123 2>/dev/null | wc -c | awk '{ printf("%s", $1); }'`
+    if [ ".$bytes" = .3 ]; then
+        minusn='-n'
+    fi
+    
+    #   determine terminal bold sequence
+    term_bold='' 
+    term_norm=''
+    if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[Bb]'`" != . ]; then
+        case $TERM in
+            #   for the most important terminal types we directly know the sequences
+            xterm|xterm*|vt220|vt220*)
+                term_bold=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
+                term_norm=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
+                ;;
+            vt100|vt100*)
+                term_bold=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
+                term_norm=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
+                ;;
+            #   for all others, we try to use a possibly existing `tput' or `tcout' utility
+            * )
+                paths=`echo $PATH | sed -e 's/:/ /g'`
+                for tool in tput tcout; do
+                    for dir in $paths; do
+                        if [ -r "$dir/$tool" ]; then
+                            for seq in bold md smso; do # 'smso' is last
+                                bold="`$dir/$tool $seq 2>/dev/null`"
+                                if [ ".$bold" != . ]; then
+                                    term_bold="$bold"
+                                    break
+                                fi
+                            done
+                            if [ ".$term_bold" != . ]; then
+                                for seq in sgr0 me rmso reset; do # 'reset' is last
+                                    norm="`$dir/$tool $seq 2>/dev/null`"
+                                    if [ ".$norm" != . ]; then
+                                        term_norm="$norm"
+                                        break
+                                    fi
+                                done
+                            fi
+                            break
+                        fi
+                    done
+                    if [ ".$term_bold" != . -a ".$term_norm" != . ]; then
+                        break;
+                    fi
+                done
+                ;;
+        esac
+        if [ ".$term_bold" = . -o ".$term_norm" = . ]; then
+            echo "$msgprefix:Warning: unable to determine terminal sequence for bold mode" 1>&2
+        fi
+    fi
+    
+    #   determine user name
+    username=''
+    if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[uU]'`" != . ]; then
+        username="$LOGNAME"
+        if [ ".$username" = . ]; then
+            username="$USER"
+            if [ ".$username" = . ]; then
+                username="`(whoami) 2>/dev/null |\
+                           awk '{ printf("%s", $1); }'`"
+                if [ ".$username" = . ]; then
+                    username="`(who am i) 2>/dev/null |\
+                               awk '{ printf("%s", $1); }'`"
+                    if [ ".$username" = . ]; then
+                        username='unknown'
+                    fi
+                fi
+            fi
+        fi
+    fi
+    
+    #   determine user id
+    userid=''
+    if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%U'`" != . ]; then
+        userid="`(id -u) 2>/dev/null`"
+        if [ ".$userid" = . ]; then
+            str="`(id) 2>/dev/null`"
+            if [ ".`echo $str | grep '^uid[ 	]*=[ 	]*[0-9]*('`" != . ]; then
+                userid=`echo $str | sed -e 's/^uid[ 	]*=[ 	]*//' -e 's/(.*//'`
+            fi
+            if [ ".$userid" = . ]; then
+                userid=`egrep "^${username}:" /etc/passwd 2>/dev/null | \
+                        sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
+                if [ ".$userid" = . ]; then
+                    userid=`(ypcat passwd) 2>/dev/null |
+                            egrep "^${username}:" | \
+                            sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
+                    if [ ".$userid" = . ]; then
+                        userid='?'
+                    fi
+                fi
+            fi
+        fi
+    fi
+    
+    #   determine host name
+    hostname=''
+    if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%h'`" != . ]; then
+        hostname="`(uname -n) 2>/dev/null |\
+                   awk '{ printf("%s", $1); }'`"
+        if [ ".$hostname" = . ]; then
+            hostname="`(hostname) 2>/dev/null |\
+                       awk '{ printf("%s", $1); }'`"
+            if [ ".$hostname" = . ]; then
+                hostname='unknown'
+            fi
+        fi
+        case $hostname in
+            *.* )
+                domainname=".`echo $hostname | cut -d. -f2-`"
+                hostname="`echo $hostname | cut -d. -f1`"
+                ;;
+        esac
+    fi
+    
+    #   determine domain name
+    domainname=''
+    if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%d'`" != . ]; then
+        if [ ".$domainname" = . ]; then
+            if [ -f /etc/resolv.conf ]; then
+                domainname="`egrep '^[ 	]*domain' /etc/resolv.conf | head -1 |\
+                             sed -e 's/.*domain//' \
+                                 -e 's/^[ 	]*//' -e 's/^ *//' -e 's/^	*//' \
+                                 -e 's/^\.//' -e 's/^/./' |\
+                             awk '{ printf("%s", $1); }'`"
+                if [ ".$domainname" = . ]; then
+                    domainname="`egrep '^[ 	]*search' /etc/resolv.conf | head -1 |\
+                                 sed -e 's/.*search//' \
+                                     -e 's/^[ 	]*//' -e 's/^ *//' -e 's/^	*//' \
+                                     -e 's/ .*//' -e 's/	.*//' \
+                                     -e 's/^\.//' -e 's/^/./' |\
+                                 awk '{ printf("%s", $1); }'`"
+                fi
+            fi
+        fi
+    fi
+    
+    #   determine current time
+    time_day=''
+    time_month=''
+    time_year=''
+    time_monthname=''
+    if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[DMYm]'`" != . ]; then
+        time_day=`date '+%d'`
+        time_month=`date '+%m'`
+        time_year=`date '+%Y' 2>/dev/null`
+        if [ ".$time_year" = . ]; then
+            time_year=`date '+%y'`
+            case $time_year in
+                [5-9][0-9]) time_year="19$time_year" ;;
+                [0-4][0-9]) time_year="20$time_year" ;;
+            esac
+        fi
+        case $time_month in
+            1|01) time_monthname='Jan' ;;
+            2|02) time_monthname='Feb' ;;
+            3|03) time_monthname='Mar' ;;
+            4|04) time_monthname='Apr' ;;
+            5|05) time_monthname='May' ;;
+            6|06) time_monthname='Jun' ;;
+            7|07) time_monthname='Jul' ;;
+            8|08) time_monthname='Aug' ;;
+            9|09) time_monthname='Sep' ;;
+              10) time_monthname='Oct' ;;
+              11) time_monthname='Nov' ;;
+              12) time_monthname='Dec' ;;
+        esac
+    fi
+    
+    #   expand special ``%x'' constructs
+    if [ ".$opt_e" = .yes ]; then
+        text=`echo $seo "$text" |\
+              sed -e "s/%B/${term_bold}/g" \
+                  -e "s/%b/${term_norm}/g" \
+                  -e "s/%u/${username}/g" \
+                  -e "s/%U/${userid}/g" \
+                  -e "s/%h/${hostname}/g" \
+                  -e "s/%d/${domainname}/g" \
+                  -e "s/%D/${time_day}/g" \
+                  -e "s/%M/${time_month}/g" \
+                  -e "s/%Y/${time_year}/g" \
+                  -e "s/%m/${time_monthname}/g" 2>/dev/null`
+    fi
+    
+    #   create output
+    if [ .$opt_n = .no ]; then
+        echo $seo "$text"
+    else
+        #   the harder part: echo -n is best, because
+        #   awk may complain about some \xx sequences.
+        if [ ".$minusn" != . ]; then
+            echo $seo $minusn "$text"
+        else
+            echo dummy | awk '{ printf("%s", TEXT); }' TEXT="$text"
+        fi
+    fi
+    ;;
+
+install )
+    ##
+    ##  install -- Install a program, script or datafile
+    ##  Copyright (c) 1997-2000 Ralf S. Engelschall <rse at engelschall.com>
+    ##  Originally written for shtool
+    ##
+    
+    src="$1"
+    dst="$2"
+    
+    #  If destination is a directory, append the input filename
+    if [ -d $dst ]; then
+        dst=`echo "$dst" | sed -e 's:/$::'`
+        dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'`
+        dst="$dst/$dstfile"
+    fi
+    
+    #  Add a possible extension to src and dst
+    if [ ".$opt_e" != . ]; then
+        src="$src$opt_e"
+        dst="$dst$opt_e"
+    fi
+    
+    #  Check for correct arguments
+    if [ ".$src" = ".$dst" ]; then
+        echo "$msgprefix:Error: source and destination are the same" 1>&2
+        exit 1
+    fi
+    
+    #  Make a temp file name in the destination directory
+    dstdir=`echo $dst | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;'`
+    dsttmp="$dstdir/#INST@$$#"
+    
+    #  Verbosity
+    if [ ".$opt_v" = .yes ]; then
+        echo "$src -> $dst" 1>&2
+    fi
+    
+    #  Copy or move the file name to the temp name
+    #  (because we might be not allowed to change the source)
+    if [ ".$opt_C" = .yes ]; then
+        opt_c=yes
+    fi
+    if [ ".$opt_c" = .yes ]; then
+        if [ ".$opt_t" = .yes ]; then
+            echo "cp $src $dsttmp" 1>&2
+        fi
+        cp $src $dsttmp || exit $?
+    else
+        if [ ".$opt_t" = .yes ]; then
+            echo "mv $src $dsttmp" 1>&2
+        fi
+        mv $src $dsttmp || exit $?
+    fi
+    
+    #  Adjust the target file
+    #  (we do chmod last to preserve setuid bits)
+    if [ ".$opt_s" = .yes ]; then
+        if [ ".$opt_t" = .yes ]; then
+            echo "strip $dsttmp" 1>&2
+        fi
+        strip $dsttmp || exit $?
+    fi
+    if [ ".$opt_o" != . ]; then
+        if [ ".$opt_t" = .yes ]; then
+            echo "chown $opt_o $dsttmp" 1>&2
+        fi
+        chown $opt_o $dsttmp || exit $?
+    fi
+    if [ ".$opt_g" != . ]; then
+        if [ ".$opt_t" = .yes ]; then
+            echo "chgrp $opt_g $dsttmp" 1>&2
+        fi
+        chgrp $opt_g $dsttmp || exit $?
+    fi
+    if [ ".$opt_m" != . ]; then
+        if [ ".$opt_t" = .yes ]; then
+            echo "chmod $opt_m $dsttmp" 1>&2
+        fi
+        chmod $opt_m $dsttmp || exit $?
+    fi
+    
+    #   Determine whether to do a quick install
+    #   (has to be done _after_ the strip was already done)
+    quick=no
+    if [ ".$opt_C" = .yes ]; then
+        if [ -r $dst ]; then
+            if cmp -s $src $dst; then
+                quick=yes
+            fi
+        fi
+    fi
+    
+    #   Finally install the file to the real destination
+    if [ $quick = yes ]; then
+        if [ ".$opt_t" = .yes ]; then
+            echo "rm -f $dsttmp" 1>&2
+        fi
+        rm -f $dsttmp
+    else
+        if [ ".$opt_t" = .yes ]; then
+            echo "rm -f $dst && mv $dsttmp $dst" 1>&2
+        fi
+        rm -f $dst && mv $dsttmp $dst
+    fi
+    ;;
+
+mkdir )
+    ##
+    ##  mkdir -- Make one or more directories
+    ##  Copyright (c) 1996-2000 Ralf S. Engelschall <rse at engelschall.com>
+    ##  Originally written for public domain by Noah Friedman <friedman at prep.ai.mit.edu>
+    ##  Cleaned up and enhanced for shtool
+    ##
+    
+    errstatus=0
+    for p in ${1+"$@"}; do
+        #   if the directory already exists...
+        if [ -d "$p" ]; then
+            if [ ".$opt_f" = .no ] && [ ".$opt_p" = .no ]; then
+                echo "$msgprefix:Error: directory already exists: $p" 1>&2
+                errstatus=1
+                break
+            else
+                continue
+            fi
+        fi
+        #   if the directory has to be created...
+        if [ ".$opt_p" = .no ]; then
+            if [ ".$opt_t" = .yes ]; then
+                echo "mkdir $p" 1>&2
+            fi
+            mkdir $p || errstatus=$?
+        else
+            #   the smart situation
+            set fnord `echo ":$p" |\
+                       sed -e 's/^:\//%/' \
+                           -e 's/^://' \
+                           -e 's/\// /g' \
+                           -e 's/^%/\//'`
+            shift
+            pathcomp=''
+            for d in ${1+"$@"}; do
+                pathcomp="$pathcomp$d"
+                case "$pathcomp" in
+                    -* ) pathcomp="./$pathcomp" ;;
+                esac
+                if [ ! -d "$pathcomp" ]; then
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "mkdir $pathcomp" 1>&2
+                    fi
+                    mkdir $pathcomp || errstatus=$?
+                    if [ ".$opt_m" != . ]; then
+                        if [ ".$opt_t" = .yes ]; then
+                            echo "chmod $opt_m $pathcomp" 1>&2
+                        fi
+                        chmod $opt_m $pathcomp || errstatus=$?
+                    fi
+                fi
+                pathcomp="$pathcomp/"
+            done
+        fi
+    done
+    exit $errstatus
+    ;;
+
+esac
+
+exit 0
+
+##EOF##

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/library.mk
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/library.mk	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/library.mk	Sat Jul 13 21:26:08 2002
@@ -0,0 +1,30 @@
+# Copyright (c) 1999, 2000 Sascha Schumann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code 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.
+# 
+# THIS SOFTWARE IS PROVIDED BY SASCHA SCHUMANN ``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 OR CONTRIBUTORS 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.
+#
+##############################################################################
+# $Id: library.mk,v 1.6 2000/05/01 02:57:24 sas Exp $ 
+#
+
+LTLIBRARY_OBJECTS = $(LTLIBRARY_SOURCES:.c=.lo)
+
+$(LTLIBRARY_NAME): $(LTLIBRARY_OBJECTS) $(LTLIBRARY_DEPENDENCIES)
+	$(LINK) $(LTLIBRARY_LDFLAGS) $(LTLIBRARY_OBJECTS) $(LTLIBRARY_LIBADD)

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/ltlib.mk
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/ltlib.mk	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/ltlib.mk	Sat Jul 13 21:26:08 2002
@@ -0,0 +1,31 @@
+# Copyright (c) 1999 Sascha Schumann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code 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.
+# 
+# THIS SOFTWARE IS PROVIDED BY SASCHA SCHUMANN ``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 REGENTS OR CONTRIBUTORS 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.
+#
+##############################################################################
+# $Id: ltlib.mk,v 1.4 2000/04/30 03:10:34 sas Exp $ 
+#
+
+targets = $(LTLIBRARY_NAME)
+
+include $(top_srcdir)/build/rules.mk
+include $(top_srcdir)/build/library.mk
+

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/program.mk
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/program.mk	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/build/program.mk	Sat Jul 13 21:26:08 2002
@@ -0,0 +1,30 @@
+# Copyright (c) 1999, 2000 Sascha Schumann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code 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.
+# 
+# THIS SOFTWARE IS PROVIDED BY SASCHA SCHUMANN ``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 REGENTS OR CONTRIBUTORS 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.
+#
+##############################################################################
+# $Id: program.mk,v 1.2 2000/01/01 20:48:42 sas Exp $ 
+#
+
+PROGRAM_OBJECTS = $(PROGRAM_SOURCES:.c=.lo)
+
+$(PROGRAM_NAME): $(PROGRAM_DEPENDENCIES) $(PROGRAM_OBJECTS)
+	$(LINK) $(PROGRAM_LDFLAGS) $(PROGRAM_OBJECTS) $(PROGRAM_LDADD)

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/dynlib.m4
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/dynlib.m4	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/dynlib.m4	Sat Jul 13 21:26:08 2002
@@ -0,0 +1,64 @@
+
+
+
+AC_DEFUN(LIB_SHARED_CONVENIENCE,[
+  lib_target="\$(LTLIBRARY_NAME)"
+  cat >>$1<<EOF
+\$(LTLIBRARY_NAME): \$(LTLIBRARY_SHARED_OBJECTS) \$(LTLIBRARY_DEPENDENCIES)
+	\$(SHARED_LIBTOOL) --mode=link \$(CCLD) \$(CFLAGS) \$(EXTRA_CFLAGS) \$(LDFLAGS) -o \[$]@ \$(LTLIBRARY_LDFLAGS) \$(LTLIBRARY_OBJECTS) \$(LTLIBRARY_SHARED_LIBADD)
+
+EOF
+])
+
+AC_DEFUN(LIB_SHARED_MODULE,[
+  lib_target="\$(LTLIBRARY_SHARED_NAME)"
+  cat >>$1<<EOF
+\$(LTLIBRARY_SHARED_NAME): \$(LTLIBRARY_SHARED_OBJECTS) \$(LTLIBRARY_DEPENDENCIES)
+	\$(SHARED_LIBTOOL) --mode=link \$(CCLD) \$(CFLAGS) \$(EXTRA_CFLAGS) \$(LDFLAGS) -o \[$]@ -avoid-version -module -rpath \$(phplibdir) \$(LTLIBRARY_LDFLAGS) \$(LTLIBRARY_OBJECTS) \$(LTLIBRARY_SHARED_LIBADD)
+	\$(SHARED_LIBTOOL) --mode=install cp \[$]@ \$(phplibdir)
+
+EOF
+])
+
+AC_DEFUN(LIB_STATIC_CONVENIENCE,[
+  lib_target="\$(LTLIBRARY_NAME)"
+  cat >>$1<<EOF
+\$(LTLIBRARY_NAME): \$(LTLIBRARY_OBJECTS) \$(LTLIBRARY_DEPENDENCIES)
+	\$(LINK) \$(LTLIBRARY_LDFLAGS) \$(LTLIBRARY_OBJECTS) \$(LTLIBRARY_LIBADD)
+
+EOF
+])
+
+dnl LIB_BUILD(path, shared, convenience)
+dnl sets up path to build a shared/static convenience/module
+AC_DEFUN(LIB_BUILD,[
+  lib_makefile="$1/libs.mk"
+  lib_target=""
+  
+  $php_shtool mkdir -p $1
+  cat >$lib_makefile<<EOF
+LTLIBRARY_OBJECTS = \$(LTLIBRARY_SOURCES:.c=.lo)
+LTLIBRARY_SHARED_OBJECTS = \$(LTLIBRARY_OBJECTS:.lo=.slo)
+EOF
+
+  if test "$2" = "shared" || test "$2" = "yes"; then
+    lib_build_shared=yes
+    if test -n "$3"; then
+dnl ---------------------------------------- Shared Convenience
+      LIB_SHARED_CONVENIENCE($lib_makefile)
+    else
+dnl ---------------------------------------- Shared Module
+      LIB_SHARED_MODULE($lib_makefile)
+    fi
+  else
+dnl ---------------------------------------- Static Convenience = Static Module
+    LIB_STATIC_CONVENIENCE($lib_makefile)
+  fi
+
+dnl ---------------------------------------- Generate build targets
+  if test -n "$lib_target"; then
+    cat >>$lib_makefile<<EOF
+targets = $lib_target
+EOF
+  fi
+])

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/USAGE
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/USAGE	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/USAGE	Sat Jul 13 21:26:09 2002
@@ -0,0 +1,166 @@
+$Id: USAGE,v 1.1 2000/07/19 17:23:14 joeym Exp $
+
+--------------------------------------------------
+Usage:
+
+	Loading the rrdtool module is a little bit different with
+PHP4/Zend.  If you build the rrdtool module into PHP4 at compile
+time (see INSTALL file), then there is nothing you need to do
+in your scripts to use the rrd_* functions. 
+
+
+
+	However, if you build the rrdtool module as a 'self-contained'
+module (see INSTALL file), you will need to load it for each
+php script you intend to use.  To do this, you will need a line 
+such as this in your script:
+
+	<? dl("rrdtool.so"); ?>
+
+Note that in PHP4/Zend, you cannot specify the directory where
+the module lives.  It restricts the search to a specifc directory
+which is defined at compile time.  'make install' will place
+this file in the appropriate location.
+
+
+
+API:
+
+--------------------------------------------------------------------
+string rrd_error()
+
+	rrd_error takes no arguments.
+
+	Use this function to retrieve the error message from
+the last rrd_* function that was called and failed.
+
+	If an error was set, a string will be returned.  
+
+	If no error was set, a blank string will be returned.
+
+
+
+
+--------------------------------------------------------------------
+int rrd_last(string filename)
+
+	rrd_last takes only one argument, a filename of an RRD
+file.  
+
+	If rrd_last is successful in obtaining the last modifiation
+time of the file, a date will be returned in the form of the
+number of seconds from the unix epoch (Jan 1, 1970, 00:00:00).
+You can then use any of php's excellent time functions on this
+value.
+
+	If rrd_last is not sucessful, a value of 0 will be returned,
+and the internal rrd error will be set.  You can access this error
+message via the rrd_error() function (if one was set).
+ 
+
+--------------------------------------------------------------------
+int rrd_update(string filename, string options)
+
+	rrd_update takes 2 arguments, a filename of an RRD file
+and a string with options to fill the RRD file with.
+
+	It has been designed to work similary to the rrd_update
+call in the RRDs perl library.
+
+Example:  $result = rrd_update("/some.rrd", "N:123:9873:235");
+ 
+	If rrd_update is successful, 1 is returned. 
+
+	If rrd_update is not successful, 0 is returned, and an
+error message should be obtainable by called 'rrd_error()'.
+
+
+--------------------------------------------------------------------
+int rrd_create(string filename, array options, int num_of_elements)
+
+	rrd_create takes 3 arguments, a filename of an RRD file to
+create, an array of options (exactly like you would pass in the RRDs 
+perl library, or on the command line to 'rrdtool'), and the last 
+argument is the number of elements in the array of options.  This 
+can be obtained by simply calling " count($opt_array) ".  See the 
+example scripts for a more clear example.
+
+	If rrd_update is successful, 1 is returned. 
+
+	If rrd_update is not successful, 0 is returned, and an
+error message should be obtainable by called 'rrd_error()'.
+
+
+
+--------------------------------------------------------------------
+mixed rrd_graph(string filename, array options, int num_of_elements) 
+
+	rrd_graph takes 3 arguments, a filename of an RRD file,
+an array of options (exactly like you would pass in the RRDs perl
+library, or on the command line to 'rrdtool'), and the last argument
+is the number of elements in the array of options.  This can be 
+obtained by simply calling " count($opt_array) ".  See the example
+scripts for a more clear example.
+
+
+	If rrd_graph is successful, an array is returned.  The
+array is an associate array with 3 values:
+
+$array[xsize]  -  The size of the image along the X axis.
+$array[ysize]  -  The size of the image along the Y axis.
+$array[calcpr] -  This is actually another array, that will contain
+                  the results of any PRINT statements.
+
+
+	If rrd_graph is not successful, a 0 is returned.
+
+IMPORTANT NOTE:  In order for php not to complain about mis-using
+the return value, it is important that you check the type of the
+return value.  use the " is_array() " function to check if the 
+returned value is an array (in which case rrd_graph was successful),
+or not an array (meaning rrd_graph was NOT successful).  See the
+examples for an illustration of this.
+
+
+--------------------------------------------------------------------
+mixed rrd_fetch(string filename, array options, int num_of_elements) 
+
+	rrd_fetch takes 3 arguments, a filename of an RRD file,
+an array of options (exactly like you would pass in the RRDs perl
+library, or on the command line to 'rrdtool'), and the last argument
+is the number of elements in the array of options.  This can be 
+obtained by simply calling " count($opt_array) ".  See the example
+scripts for a more clear example.
+
+
+	If rrd_fetch is successful, an array is returned.  The
+array is an associate array with 5 values:
+
+$array[start]   -  This is the start time of the data returned 
+                   (unix epoch timestamp format)
+$array[end]     -  This is the end time of the data returned
+                   (unix epoch timestamp format)
+$array[step]    -  This is the step interval of the data returned,
+                   in number of seconds.
+$array[ds_cnt]  -  This is the number of DS's returned from the
+                   RRD file.
+$array[ds_namv] -  This is an array with the names of the DS's
+                   returned from the RRD file.
+$array[data]    -  This is an array with all the values fetch'd
+                   from the rrd file by rrd_fetch.
+
+(This is very similar to the way rrd_fetch() in the RRDs
+perl library works, as well as the C function rrd_fetch()).
+
+	If rrd_fetch is not successful, a 0 is returned.
+
+IMPORTANT NOTE:  In order for php not to complain about mis-using
+the return value, it is important that you check the type of the
+return value.  use the " is_array() " function to check if the 
+returned value is an array (in which case rrd_fetch was successful),
+or not an array (meaning rrd_fetch was NOT successful).  See the
+examples for an illustration of this.
+
+
+--------------------------------------------------------------------
+

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/ltconfig
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/ltconfig	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/ltconfig	Sat Jul 13 21:26:09 2002
@@ -0,0 +1,3031 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# 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.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+echo=echo
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec "$SHELL" "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# Find the correct PATH separator.  Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != "Xset"; then
+  UNAME=${UNAME-`uname 2>/dev/null`}
+  case X$UNAME in
+    *-DOS) PATH_SEPARATOR=';' ;;
+    *)     PATH_SEPARATOR=':' ;;
+  esac
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+if test "X${echo_test_string+set}" != "Xset"; then
+  # find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+       echo_test_string="`eval $cmd`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" != 'X\t' ||
+   test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+  for dir in $PATH /usr/ucb; do
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+	 test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running ltconfig again with it.
+      ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}"
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"}
+    else
+      # Try using printf.
+      echo='printf "%s\n"'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+	 test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+	# Cool, printf works
+	:
+      elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+	   test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+	CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL"
+	export CONFIG_SHELL
+	SHELL="$CONFIG_SHELL"
+	export SHELL
+	echo="$CONFIG_SHELL $0 --fallback-echo"
+      elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+	   test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+	echo="$CONFIG_SHELL $0 --fallback-echo"
+      else
+	# maybe with a smaller string...
+	prev=:
+
+	for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+	  if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then
+	    break
+	  fi
+	  prev="$cmd"
+	done
+
+	if test "$prev" != 'sed 50q "$0"'; then
+	  echo_test_string=`eval $prev`
+	  export echo_test_string
+	  exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"}
+	else
+	  # Oops.  We lost completely, so just stick with echo.
+	  echo=echo
+	fi
+      fi
+    fi
+  fi
+fi
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.3.3-freebsd-ports
+TIMESTAMP=" (1.385.2.181 1999/07/02 15:49:11)"
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+enable_static=yes
+enable_fast_install=yes
+install_ltlibs=yes
+release_suffix=yes
+enable_dlopen=unknown
+enable_win32_dll=no
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+ofile="$default_ofile"
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+need_locks=yes
+ac_ext=c
+objext=o
+libext=a
+exeext=
+cache_file=
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LDFLAGS="$LDFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_LIBS="$LIBS"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+old_DLLTOOL="$DLLTOOL"
+old_OBJDUMP="$OBJDUMP"
+old_AS="$AS"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+  case "$option" in
+  -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    eval "$prev=\$option"
+    prev=
+    continue
+  fi
+
+  case "$option" in
+  --help) cat <<EOM
+Usage: $progname [OPTION]... [HOST [LTMAIN]]
+
+Generate a system-specific libtool script.
+
+    --debug                enable verbose shell tracing
+    --disable-shared       do not build shared libraries
+    --disable-static       do not build static libraries
+    --disable-fast-install do not optimize for fast installation
+    --disable-ltlibs       don't install the .la archives
+    --release-ignore       don't use -release specification
+    --release-suffix       use -release suffix for all files
+    --enable-dlopen        enable dlopen support
+    --enable-win32-dll     enable building dlls on win32 hosts
+    --help                 display this help and exit
+    --no-verify            do not verify that HOST is a valid host type
+-o, --output=FILE          specify the output file [default=$default_ofile]
+    --quiet                same as \`--silent'
+    --silent               do not print informational messages
+    --srcdir=DIR           find \`config.guess' in DIR
+    --version              output version information and exit
+    --with-gcc             assume that the GNU C compiler will be used
+    --with-gnu-ld          assume that the C compiler uses the GNU linker
+    --disable-lock         disable file locking
+    --cache-file=FILE      configure cache file
+
+LTMAIN is the \`ltmain.sh' shell script fragment or \`ltmain.c' program
+that provides basic libtool functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+  exit 0
+  ;;
+
+  --debug)
+    echo "$progname: enabling shell trace mode"
+    set -x
+    ;;
+
+  --disable-shared) enable_shared=no ;;
+
+  --disable-static) enable_static=no ;;
+
+  --disable-fast-install) enable_fast_install=no ;;
+
+  --disable-ltlibs) install_ltlibs=no ;;
+
+  --release-ignore) release_suffix=no ;;
+
+  --release-suffix) release_suffix=all ;;
+
+  --enable-dlopen) enable_dlopen=yes ;;
+
+  --enable-win32-dll) enable_win32_dll=yes ;;
+
+  --quiet | --silent) silent=yes ;;
+
+  --srcdir) prev=srcdir ;;
+  --srcdir=*) srcdir="$optarg" ;;
+
+  --no-verify) verify_host=no ;;
+
+  --output | -o) prev=ofile ;;
+  --output=*) ofile="$optarg" ;;
+
+  --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"; exit 0 ;;
+
+  --with-gcc) with_gcc=yes ;;
+  --with-gnu-ld) with_gnu_ld=yes ;;
+
+  --disable-lock) need_locks=no ;;
+
+  --cache-file=*) cache_file="$optarg" ;;
+
+  -*)
+    echo "$progname: unrecognized option \`$option'" 1>&2
+    echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    if test -z "$ltmain"; then
+      ltmain="$option"
+    elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+#      if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+#        echo "$progname: warning \`$option' is not a valid host type" 1>&2
+#      fi
+      host="$option"
+    else
+      echo "$progname: too many arguments" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+done
+
+if test -z "$ltmain"; then
+  echo "$progname: you must specify a LTMAIN file" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+if test ! -f "$ltmain"; then
+  echo "$progname: \`$ltmain' does not exist" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+  case "$arg" in
+  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ltconfig_args="$ltconfig_args '$arg'" ;;
+  *) ltconfig_args="$ltconfig_args $arg" ;;
+  esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+
+if test -n "$cache_file" && test -r "$cache_file"; then
+  echo "loading cache $cache_file within ltconfig"
+  . $cache_file
+fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi at caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='	'
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+  # Assume the source directory is the same one as the path to LTMAIN.
+  srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+  test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+  # Check for config.guess and config.sub.
+  ac_aux_dir=
+  for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+    if test -f $ac_dir/config.guess; then
+      ac_aux_dir=$ac_dir
+      break
+    fi
+  done
+  if test -z "$ac_aux_dir"; then
+    echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+  ac_config_guess=$ac_aux_dir/config.guess
+  ac_config_sub=$ac_aux_dir/config.sub
+
+  # Make sure we can run config.sub.
+  if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then :
+  else
+    echo "$progname: cannot run $ac_config_sub" 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+
+  echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+  host_alias=$host
+  case "$host_alias" in
+  "")
+    if host_alias=`$SHELL $ac_config_guess`; then :
+    else
+      echo "$progname: cannot guess host type; you must specify one" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+  host=`$SHELL $ac_config_sub $host_alias`
+  echo "$ac_t$host" 1>&6
+
+  # Make sure the host verified.
+  test -z "$host" && exit 1
+
+elif test -z "$host"; then
+  echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+  echo "$help" 1>&2
+  exit 1
+else
+  host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "${COLLECT_NAMES+set}" != set; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# Set a sane default for `OBJDUMP'.
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+  result=no
+
+  echo $ac_n "checking for ranlib... $ac_c" 1>&6
+  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+  for dir in $PATH; do
+    test -z "$dir" && dir=.
+    if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then
+      RANLIB="ranlib"
+      result="ranlib"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+  old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+fi
+
+# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin.
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$AS" && AS=as
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+  # If CC is not set, then try to find GCC or a usable CC.
+  if test -z "$CC"; then
+    echo $ac_n "checking for gcc... $ac_c" 1>&6
+    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then
+	CC="gcc"
+	break
+      fi
+    done
+    IFS="$save_ifs"
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+  fi
+
+  # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+  if test -z "$CC"; then
+    echo $ac_n "checking for cc... $ac_c" 1>&6
+    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    cc_rejected=no
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/cc || test -f $dir/cc$ac_exeext; then
+	if test "$dir/cc" = "/usr/ucb/cc"; then
+	  cc_rejected=yes
+	  continue
+	fi
+	CC="cc"
+	break
+      fi
+    done
+    IFS="$save_ifs"
+    if test $cc_rejected = yes; then
+      # We found a bogon in the path, so make sure we never use it.
+      set dummy $CC
+      shift
+      if test $# -gt 0; then
+	# We chose a different compiler from the bogus one.
+	# However, it has the same name, so the bogon will be chosen
+	# first if we set CC to just the name; use the full file name.
+	shift
+	set dummy "$dir/cc" "$@"
+	shift
+	CC="$@"
+      fi
+    fi
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+
+    if test -z "$CC"; then
+      echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+      exit 1
+    fi
+  fi
+
+  # Now see if the compiler is really GCC.
+  with_gcc=no
+  echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+  echo "$progname:581: checking whether we are using GNU C" >&5
+
+  $rm conftest.c
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:589: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+    with_gcc=yes
+  fi
+  $rm conftest.c
+  echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for object suffix... $ac_c" 1>&6
+$rm conftest*
+echo 'int i = 1;' > conftest.c
+echo "$progname:603: checking for object suffix" >& 5
+if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then
+  # Append any warnings to the config.log.
+  cat conftest.err 1>&5
+
+  for ac_file in conftest.*; do
+    case $ac_file in
+    *.c) ;;
+    *) objext=`echo $ac_file | sed -e s/conftest.//` ;;
+    esac
+  done
+else
+  cat conftest.err 1>&5
+  echo "$progname: failed program was:" >&5
+  cat conftest.c >&5
+fi
+$rm conftest*
+echo "$ac_t$objext" 1>&6
+
+echo $ac_n "checking for executable suffix... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_exeext="no"
+  $rm conftest*
+  echo 'main () { return 0; }' > conftest.c
+  echo "$progname:629: checking for executable suffix" >& 5
+  if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+
+    for ac_file in conftest.*; do
+      case $ac_file in
+      *.c | *.err | *.$objext ) ;;
+      *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;;
+      esac
+    done
+  else
+    cat conftest.err 1>&5
+    echo "$progname: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  $rm conftest*
+fi
+if test "X$ac_cv_exeext" = Xno; then
+  exeext=""
+else
+  exeext="$ac_cv_exeext"
+fi
+echo "$ac_t$ac_cv_exeext" 1>&6
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+  wl='-Wl,'
+  link_static_flag='-static'
+
+  case "$host_os" in
+  beos* | irix5* | irix6* | osf3* | osf4*)
+    # PIC is the default for these OSes.
+    ;;
+  aix*)
+    # Below there is a dirty hack to force normal static linking with -ldl
+    # The problem is because libdl dynamically linked with both libc and
+    # libC (AIX C++ library), which obviously doesn't included in libraries
+    # list by gcc. This cause undefined symbols with -static flags.
+    # This hack allows C programs to be linked with "-static -ldl", but
+    # we not sure about C++ programs.
+    link_static_flag="$link_static_flag ${wl}-lC"
+    ;;
+  cygwin* | mingw* | os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+  amigaos*)
+    # FIXME: we need at least 68020 code to build shared libraries, but
+    # adding the `-m68020' flag to GCC prevents building anything better,
+    # like `-m68040'.
+    pic_flag='-m68020 -resident32 -malways-restore-a4'
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec; then
+       pic_flag=-Kconform_pic
+    fi
+    ;;
+  *)
+    pic_flag='-fPIC'
+    ;;
+  esac
+else
+  # PORTME Check for PIC flags for the system compiler.
+  case "$host_os" in
+  aix3* | aix4*)
+    # All AIX code is PIC.
+    link_static_flag='-bnso -bI:/lib/syscalls.exp'
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    # Is there a better link_static_flag that works with the bundled CC?
+    wl='-Wl,'
+    link_static_flag="${wl}-a ${wl}archive"
+    pic_flag='+Z'
+    ;;
+
+  irix5* | irix6*)
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    # PIC (with -KPIC) is the default.
+    ;;
+
+  cygwin* | mingw* | os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+
+  osf3* | osf4*)
+    # All OSF/1 code is PIC.
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    ;;
+
+  sco3.2v5*)
+    pic_flag='-Kpic'
+    link_static_flag='-dn'
+    special_shlib_compile_flags='-belf'
+    ;;
+
+  solaris*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  sunos4*)
+    pic_flag='-PIC'
+    link_static_flag='-Bstatic'
+    wl='-Qoption ld '
+    ;;
+
+  sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  uts4*)
+    pic_flag='-pic'
+    link_static_flag='-Bstatic'
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec ;then
+      pic_flag='-Kconform_pic'
+      link_static_flag='-Bstatic'
+    fi
+    ;;
+  *)
+    can_build_shared=no
+    ;;
+  esac
+fi
+
+if test -n "$pic_flag"; then
+  echo "$ac_t$pic_flag" 1>&6
+
+  # Check to make sure the pic_flag actually works.
+  echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $pic_flag -DPIC"
+  echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5
+  if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+    
+    case "$host_os" in
+    hpux9* | hpux10* | hpux11*)
+      # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+      # create non-PIC objects.  So, if there were any warnings, we assume that
+      # PIC is not supported.
+      if test -s conftest.err; then
+	echo "$ac_t"no 1>&6
+	can_build_shared=no
+	pic_flag=
+      else
+	echo "$ac_t"yes 1>&6
+	pic_flag=" $pic_flag"
+      fi
+      ;;
+    *)
+      echo "$ac_t"yes 1>&6
+      pic_flag=" $pic_flag"
+      ;;
+    esac
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    can_build_shared=no
+    pic_flag=
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  echo "$ac_t"none 1>&6
+fi
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+$rm conftest*
+echo "int some_variable = 0;" > conftest.c
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory.  Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.o"
+echo "$progname:829: checking if $compiler supports -c -o file.o" >&5
+if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then
+
+  # The compiler can only warn and ignore the option if not recognized
+  # So say no if there are warnings
+    if test -s out/conftest.err; then
+      echo "$ac_t"no 1>&6
+      compiler_c_o=no
+    else
+      echo "$ac_t"yes 1>&6
+      compiler_c_o=yes
+    fi
+else
+  # Append any errors to the config.log.
+  cat out/conftest.err 1>&5
+  compiler_c_o=no
+  echo "$ac_t"no 1>&6
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+
+if test x"$compiler_c_o" = x"yes"; then
+  # Check to see if we can write to a .lo
+  echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -c -o conftest.lo"
+  echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5
+if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then
+
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+      if test -s conftest.err; then
+	echo "$ac_t"no 1>&6
+	compiler_o_lo=no
+      else
+	echo "$ac_t"yes 1>&6
+	compiler_o_lo=yes
+      fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    compiler_o_lo=no
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$ac_t$hard_links" 1>&6
+  $rm conftest*
+  if test "$hard_links" = no; then
+    echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+if test "$with_gcc" = yes; then
+  # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+  echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c"
+  echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+  if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+      if test -s conftest.err; then
+	echo "$ac_t"no 1>&6
+	compiler_rtti_exceptions=no
+      else
+	echo "$ac_t"yes 1>&6
+	compiler_rtti_exceptions=yes
+      fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    compiler_rtti_exceptions=no
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+
+  if test "$compiler_rtti_exceptions" = "yes"; then
+    no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+  else
+    no_builtin_flag=' -fno-builtin'
+  fi
+  
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+  echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+  if echo "$old_CC $old_CFLAGS " | egrep -e "[ 	]$special_shlib_compile_flags[ 	]" >/dev/null; then :
+  else
+    echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+    can_build_shared=no
+  fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  echo "$ac_t$link_static_flag" 1>&6
+else
+  echo "$ac_t"none 1>&6
+  link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+  # Check to see if we can use ln -s, or we need hard links.
+  echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+  $rm conftest.dat
+  if ln -s X conftest.dat 2>/dev/null; then
+    $rm conftest.dat
+    LN_S="ln -sf"
+  else
+    LN_S=ln
+  fi
+  if test "$LN_S" = "ln -sf"; then
+    echo "$ac_t"yes 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+  ac_prog=ld
+  if test "$with_gcc" = yes; then
+    # Check if gcc -print-prog-name=ld gives a path.
+    echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+    echo "$progname:991: checking for ld used by GCC" >&5
+    ac_prog=`($CC -print-prog-name=ld) 2>&5`
+    case "$ac_prog" in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+    "")
+      # If it fails, then pretend we are not using GCC.
+      ac_prog=ld
+      ;;
+    *)
+      # If it is relative, then search for the first ld in PATH.
+      with_gnu_ld=unknown
+      ;;
+    esac
+  elif test "$with_gnu_ld" = yes; then
+    echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+    echo "$progname:1015: checking for GNU ld" >&5
+  else
+    echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+    echo "$progname:1018: checking for non-GNU ld" >&5
+  fi
+
+  if test -z "$LD"; then
+    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for ac_dir in $PATH; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+	LD="$ac_dir/$ac_prog"
+	# Check to see if the program is GNU ld.  I'd rather use --version,
+	# but apparently some GNU ld's only accept -v.
+	# Break only if it was the GNU/non-GNU ld that we prefer.
+	if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+	  test "$with_gnu_ld" != no && break
+	else
+	  test "$with_gnu_ld" != yes && break
+	fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+  fi
+
+  if test -n "$LD"; then
+    echo "$ac_t$LD" 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+
+  if test -z "$LD"; then
+    echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+    exit 1
+  fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced.  Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+
+case "$host_os" in
+cygwin* | mingw*)
+  # FIXME: the MSVC++ port hasn't been tested in a loooong time
+  # When not using gcc, we currently assume that we are using
+  # Microsoft Visual C++.
+  if test "$with_gcc" != yes; then
+    with_gnu_ld=no
+  fi
+  ;;
+
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+  # If archive_cmds runs LD, not CC, wlarc should be empty
+  wlarc='${wl}'
+
+  # See if GNU ld supports shared libraries.
+  case "$host_os" in
+  aix3* | aix4*)
+    # On AIX, the GNU linker is very broken
+    ld_shlibs=no
+    cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+
+    # Samuel A. Falvo II <kc5tja at dolphin.openprojects.net> reports
+    # that the semantics of dynamic libraries on AmigaOS, at least up
+    # to version 4, is to share data among multiple programs linked
+    # with the same dynamic library.  Since this doesn't match the
+    # behavior of shared libraries on other platforms, we can use
+    # them.
+    ld_shlibs=no
+    ;;
+
+  beos*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      allow_undefined_flag=unsupported
+      # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  cygwin* | mingw*)
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec='-L$libdir'
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+
+    # Extract the symbol export list from an `--export-all' def file,
+    # then regenerate the def file from the symbol export list, so that
+    # the compiled dll only exports the symbol export list.
+    export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+      test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+      $DLLTOOL --export-all --exclude-symbols DllMain at 12,_cygwin_dll_entry at 12,_cygwin_noncygwin_dll_entry at 12 --output-def $objdir/$soname-def  $objdir/$soname-ltdll.$objext $libobjs $convenience~
+      sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]* ; *//" < $objdir/$soname-def > $export_symbols'
+
+    archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~
+      _lt_hint=1;
+      for symbol in `cat $export_symbols`; do
+	echo "	\$symbol @ \$_lt_hint ; " >> $objdir/$soname-def;
+	_lt_hint=`expr 1 + \$_lt_hint`;
+      done~
+      test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+      test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+      $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry at 12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain at 12,_cygwin_dll_entry at 12,_cygwin_noncygwin_dll_entry at 12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+      $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry at 12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain at 12,_cygwin_dll_entry at 12,_cygwin_noncygwin_dll_entry at 12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+      $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry at 12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts'
+
+      old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a' 
+    ;;
+
+  netbsd*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib'
+      # can we support soname and/or expsyms with a.out? -oliva
+    fi
+    ;;
+
+  solaris*)
+    if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+      ld_shlibs=no
+      cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+    elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;      
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    wlarc=
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $compile_rpath $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $compile_rpath $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+  esac
+
+  if test "$ld_shlibs" = yes; then
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    case $host_os in
+    cygwin* | mingw*)
+      # dlltool doesn't understand --whole-archive et. al.
+      whole_archive_flag_spec=
+      ;;
+    *)
+      whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      ;;
+    esac
+  fi
+else
+  # PORTME fill in a description of your system's linker (not GNU ld)
+  case "$host_os" in
+  aix3*)
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+    archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname'
+    # Note: this linker hardcodes the directories in LIBPATH if there
+    # are no directories specified by -L.
+    hardcode_minus_L=yes
+    if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+      # Neither direct hardcoding nor static linking is supported with a
+      # broken collect2.
+      hardcode_direct=unsupported
+    fi
+    ;;
+
+  aix4*)
+    hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib'
+    hardcode_libdir_separator=':'
+    if test "$with_gcc" = yes; then
+      collect2name=`${CC} -print-prog-name=collect2`
+      if test -f "$collect2name" && \
+	 strings "$collect2name" | grep resolve_lib_name >/dev/null
+      then
+	# We have reworked collect2
+	hardcode_direct=yes
+      else
+	# We have old collect2
+	hardcode_direct=unsupported
+	# It fails to find uninstalled libraries when the uninstalled
+	# path is not listed in the libpath.  Setting hardcode_minus_L
+	# to unsupported forces relinking
+	hardcode_minus_L=yes
+	hardcode_libdir_flag_spec='-L$libdir'
+	hardcode_libdir_separator=
+      fi
+      shared_flag='-shared'
+    else
+      shared_flag='${wl}-bM:SRE'
+      hardcode_direct=yes
+    fi
+    allow_undefined_flag=' ${wl}-berok'
+    archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}'
+    archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}'
+    case "$host_os" in aix4.[01]|aix4.[01].*)
+      # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on
+      always_export_symbols=yes ;;
+    esac
+   ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    # see comment about different semantics on the GNU ld section
+    ld_shlibs=no
+    ;;
+
+  cygwin* | mingw*)
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec=' '
+    allow_undefined_flag=unsupported
+    # Tell ltmain to make .lib files, not .a files.
+    libext=lib
+    # FIXME: Setting linknames here is a bad hack.
+    archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+    # The linker will automatically build a .lib file if we build a DLL.
+    old_archive_from_new_cmds='true'
+    # FIXME: Should let the user specify the lib program.
+    old_archive_cmds='lib /OUT:$oldlib$oldobjs'
+    fix_srcfile_path='`cygpath -w $srcfile`'
+    ;;
+
+  freebsd1*)
+    ld_shlibs=no
+    ;;
+
+  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+  # support.  Future versions do this automatically, but an explicit c++rt0.o
+  # does not break anything, and helps significantly (at the cost of a little
+  # extra space).
+  freebsd2.2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+  freebsd2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    case "$host_os" in
+    hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;;
+    *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;;
+    esac
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_libdir_separator=:
+    hardcode_direct=yes
+    hardcode_minus_L=yes # Not in the search PATH, but as the default
+			 # location of the library.
+    export_dynamic_flag_spec='${wl}-E'
+    ;;
+
+  irix5* | irix6*)
+    if test "$with_gcc" = yes; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'  # a.out
+    else
+      archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts'      # ELF
+    fi
+    hardcode_libdir_flag_spec='${wl}-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  openbsd*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  os2*)
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    allow_undefined_flag=unsupported
+    archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def'
+    old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+    ;;
+
+  osf3* | osf4*)
+    if test "$with_gcc" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  sco3.2v5*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_shlibpath_var=no
+    runpath_var=LD_RUN_PATH
+    hardcode_runpath_var=yes
+    ;;
+
+  solaris*)
+    no_undefined_flag=' -z text'
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_shlibpath_var=no
+    case "$host_os" in
+    solaris2.[0-5] | solaris2.[0-5].*) ;;
+    *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+      whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+    esac
+    ;;
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    hardcode_direct=no #Motorola manual says yes, but my tests say they lie 
+    ;;  
+
+  sysv4.3*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_shlibpath_var=no
+    export_dynamic_flag_spec='-Bexport'
+    ;;
+
+  uts4*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  dgux*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4*MP*)
+    if test -d /usr/nec ;then
+    # archive_cmds='$LD -G -z text -h $soname -o $lib$libobjs$deplibs'
+    archive_cmds='$LD -G -h $soname -o $lib$libobjs$deplibs'
+    hardcode_shlibpath_var=no
+    runpath_var=LD_RUN_PATH
+    hardcode_runpath_var=yes
+    ld_shlibs=yes
+    fi
+    ;;
+
+  *)
+    ld_shlibs=no
+    ;;
+  esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+if test -z "$NM"; then
+  echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+  case "$NM" in
+  [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path.
+  *)
+    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+	  NM="$ac_dir/nm -B"
+	  break
+	elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+	  NM="$ac_dir/nm -p"
+	  break
+	else
+	  NM=${NM="$ac_dir/nm"} # keep the first match, but
+	  continue # so that we can try to find one that supports BSD flags
+	fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+    test -z "$NM" && NM=nm
+    ;;
+  esac
+  echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+  ;;
+irix*)
+  symcode='[BCDEGRST]'
+  ;;
+solaris*)
+  symcode='[BDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+  global_symbol_pipe="sed -n -e 's/^.*[ 	]\($symcode\)[ 	][ 	]*\($ac_symprfx\)$sympat$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+  $rm conftest*
+  cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  echo "$progname:1592: checking if global_symbol_pipe works" >&5
+  if { (eval echo $progname:1593: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { echo "$progname:1596: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+	if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+	  # Now generate the symbol file.
+	  eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c'
+
+	  cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+	  sed 's/^. \(.*\) \(.*\)$/  {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c
+	  cat <<\EOF >> conftest.c
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+	  # Now try linking the two files.
+	  mv conftest.$objext conftstm.$objext
+	  save_LIBS="$LIBS"
+	  save_CFLAGS="$CFLAGS"
+	  LIBS="conftstm.$objext"
+	  CFLAGS="$CFLAGS$no_builtin_flag"
+	  if { (eval echo $progname:1648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+	    pipe_works=yes
+	  else
+	    echo "$progname: failed program was:" >&5
+	    cat conftest.c >&5
+	  fi
+	  LIBS="$save_LIBS"
+	else
+	  echo "cannot find nm_test_func in $nlist" >&5
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  $rm conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    global_symbol_pipe=
+  fi
+done
+if test "$pipe_works" = yes; then
+  echo "${ac_t}ok" 1>&6
+else
+  echo "${ac_t}failed" 1>&6
+fi
+
+if test -z "$global_symbol_pipe"; then
+  global_symbol_to_cdecl=
+fi
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var"; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$hardcode_shlibpath_var" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+echo "$ac_t$hardcode_action" 1>&6
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linkers may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag" 1>&6
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib"
+file_magic_cmd=
+file_magic_test_file=
+deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}.so$major'
+  ;;
+
+aix4*)
+  version_type=linux
+  # AIX has no versioning support, so currently we can not hardcode correct
+  # soname into executable. Probably we can add versioning support to
+  # collect2, so additional links can be useful in future.
+  # We preserve .a as extension for shared libraries though AIX4.2
+  # and later linker supports .so
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a'
+  shlibpath_var=LIBPATH
+  deplibs_check_method=pass_all
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}.so'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  deplibs_check_method=pass_all
+  lt_cv_dlopen="load_add_on"
+  lt_cv_dlopen_libs=
+  lt_cv_dlopen_self=yes
+  ;;
+
+bsdi4*)
+  version_type=linux
+  library_names_spec='${libname}.so$major ${libname}.so'
+  soname_spec='${libname}.so'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/shlib/libc.so
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw*)
+  version_type=windows
+  need_version=no
+  need_lib_prefix=no
+  if test "$with_gcc" = yes; then
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a'
+  else
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+  fi
+  dynamic_linker='Win32 ld.exe'
+  deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  file_magic_cmd='${OBJDUMP} -f'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  lt_cv_dlopen="LoadLibrary"
+  lt_cv_dlopen_libs=
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+  
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case "$version_type" in
+    freebsd-elf*)
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+      ;;
+    freebsd-*)
+      deplibs_check_method='file_magic FreeBSD.* shared library'
+      ;;
+  esac
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=`echo /usr/lib/libc.so.*`
+  if test "$release_suffix" = all; then
+    library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so'
+  else
+    library_names_spec='${libname}${release}.so$versuffix ${libname}.so'
+  fi 
+  need_version=no
+  need_lib_prefix=no
+  finish_cmds='/usr/bin/env OBJFORMAT="'"$objformat"'" /sbin/ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  case "$host_os" in
+  freebsd2* | freebsd3.[01]*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  dynamic_linker="$host_os dld.sl"
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  shlibpath_var=SHLIB_PATH
+  shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+  library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+  soname_spec='${libname}${release}.sl$major'
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6*)
+  version_type=irix
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}.so.$major'
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so'
+  case "$host_os" in
+  irix5*)
+    libsuff= shlibsuff=
+    # this will be overridden with pass_all, but let us keep it just in case
+    deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+    ;;
+  *)
+    case "$LD" in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    # this will be overridden with pass_all, but let us keep it just in case
+    deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+  deplibs_check_method='pass_all'
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+
+  if test -f /lib/ld.so.1; then
+    dynamic_linker='GNU ld.so'
+  else
+    # Only the GNU ld.so supports shared libraries on MkLinux.
+    case "$host_cpu" in
+    powerpc*) dynamic_linker=no ;;
+    *) dynamic_linker='Linux ld.so' ;;
+    esac
+  fi
+  ;;
+
+netbsd*)
+  version_type=sunos
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+    soname_spec='${libname}${release}.so$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+openbsd*)
+  version_type=sunos
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+    need_version=no
+  fi
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+os2*)
+  libname_spec='$name'
+  need_lib_prefix=no
+  library_names_spec='$libname.dll $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4*)
+  version_type=osf
+  need_version=no
+  soname_spec='${libname}${release}.so'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  # this will be overridden with pass_all, but let us keep it just in case
+  deplibs_check_method='file_magic COFF format alpha shared library'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/shlib/libc.so
+  deplibs_check_method='pass_all'
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}.so$major'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib"
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/lib/libc.so
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case "$host_vendor" in
+    ncr)
+      deplibs_check_method='pass_all'
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+      file_magic_cmd=/usr/bin/file
+      file_magic_test_file=`echo /usr/lib/libc.so*`
+      ;;
+  esac
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+    soname_spec='$libname.so.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$ac_t$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in
+# configure.in, otherwise build static only libraries.
+case "$host_os" in
+cygwin* | mingw* | os2*)
+  if test x$can_build_shared = xyes; then
+    test x$enable_win32_dll = xno && can_build_shared=no
+    echo "checking if package supports dlls... $can_build_shared" 1>&6
+  fi
+;;
+esac
+
+if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then
+  case "$deplibs_check_method" in
+  "file_magic "*)
+    file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+    if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+       egrep "$file_magic_regex" > /dev/null; then
+      :
+    else
+      cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+EOF
+    fi ;;
+  esac
+fi
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4*)
+  test "$enable_shared" = yes && enable_static=no
+  ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+if test "$hardcode_action" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then
+  lt_cv_dlopen=no lt_cv_dlopen_libs=
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "$progname:2170: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2178 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo $progname:2188: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "$progname:2207: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2212 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char dlopen();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_dlopen=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dlopen"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "$progname:2251: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2259 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char dld_link();
+
+int main() {
+dld_link()
+; return 0; }
+EOF
+if { (eval echo $progname:2269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "$progname:2288: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2293 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char shl_load();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_shl_load=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="shl_load"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "$progname:2333: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2341 "ltconfig"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo $progname:2352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+fi
+
+    
+fi
+
+  
+fi
+
+
+fi
+
+fi
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  fi
+
+  case "$lt_cv_dlopen" in
+  dlopen)
+for ac_hdr in dlfcn.h; do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "$progname:2395: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2400 "ltconfig"
+#include <$ac_hdr>
+int fnord = 0;
+EOF
+ac_try="$ac_compile conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo $progname:2405: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+    if test "x$ac_cv_header_dlfcn_h" = xyes; then
+      CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+    fi
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+  echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2433: checking whether a program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    lt_cv_dlopen_self=cross
+  else
+    cat > conftest.c <<EOF
+#line 2441 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL	RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+#  define LTDL_GLOBAL	DL_GLOBAL
+# else
+#  define LTDL_GLOBAL	0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+#  define LTDL_LAZY_OR_NOW	RTLD_LAZY
+# else
+#  ifdef DL_LAZY
+#   define LTDL_LAZY_OR_NOW	DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define LTDL_LAZY_OR_NOW	RTLD_NOW
+#   else
+#    ifdef DL_NOW
+#     define LTDL_LAZY_OR_NOW	DL_NOW
+#    else
+#     define LTDL_LAZY_OR_NOW	0
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+    if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+	       if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } 
+
+EOF
+if { (eval echo $progname:2487: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  lt_cv_dlopen_self=yes
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  lt_cv_dlopen_self=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self" 1>&6
+
+  if test "$lt_cv_dlopen_self" = yes; then
+    LDFLAGS="$LDFLAGS $link_static_flag"
+  echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2506: checking whether a statically linked program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    lt_cv_dlopen_self_static=cross
+  else
+    cat > conftest.c <<EOF
+#line 2514 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL	RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+#  define LTDL_GLOBAL	DL_GLOBAL
+# else
+#  define LTDL_GLOBAL	0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+#  define LTDL_LAZY_OR_NOW	RTLD_LAZY
+# else
+#  ifdef DL_LAZY
+#   define LTDL_LAZY_OR_NOW	DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define LTDL_LAZY_OR_NOW	RTLD_NOW
+#   else
+#    ifdef DL_NOW
+#     define LTDL_LAZY_OR_NOW	DL_NOW
+#    else
+#     define LTDL_LAZY_OR_NOW	0
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+    if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+    if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } 
+
+EOF
+if { (eval echo $progname:2560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  lt_cv_dlopen_self_static=yes
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  lt_cv_dlopen_self_static=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6
+fi
+    ;;
+  esac
+
+  case "$lt_cv_dlopen_self" in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case "$lt_cv_dlopen_self_static" in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   ltecho="$CONFIG_SHELL \$0 --fallback-echo"
+fi
+LTSHELL="$SHELL"
+
+LTCONFIG_VERSION="$VERSION"
+
+# Only quote variables if we're using ltmain.sh.
+case "$ltmain" in
+*.sh)
+  # Now quote all the things that may contain metacharacters.
+  for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \
+    old_LD old_LDFLAGS old_LIBS \
+    old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \
+    AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \
+    reload_flag reload_cmds wl \
+    pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+    thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+    library_names_spec soname_spec \
+    RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+    old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \
+    file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \
+    finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+    hardcode_libdir_flag_spec hardcode_libdir_separator  \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+    case "$var" in
+    reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case "$ltecho" in
+  *'\$0 --fallback-echo"')
+    ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+  trap "$rm \"$ofile\"; exit 1" 1 2 15
+  echo "creating $ofile"
+  $rm "$ofile"
+  cat <<EOF > "$ofile"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+#
+# 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.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "\${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+### BEGIN LIBTOOL CONFIG
+EOF
+  cfgfile="$ofile"
+  ;;
+
+*)
+  # Double-quote the variables that need it (for aesthetics).
+  for var in old_CC old_CFLAGS old_CPPFLAGS \
+    old_LD old_LDFLAGS old_LIBS \
+    old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do
+    eval "$var=\\\"\$var\\\""
+  done
+
+  # Just create a config file.
+  cfgfile="$ofile.cfg"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  echo "creating $cfgfile"
+  $rm "$cfgfile"
+  cat <<EOF > "$cfgfile"
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+EOF
+  ;;
+esac
+
+cat <<EOF >> "$cfgfile"
+# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\
+# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\
+# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\
+# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\
+#   $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION=$LTCONFIG_VERSION
+
+# Shell to use when invoking shell scripts.
+SHELL=$LTSHELL
+
+# Whether to waste disk space.
+install_ltlibs=$install_ltlibs 
+
+# What to do with -release.
+#  yes - only for shared archive
+#  no  - ingnore
+#  all - for all archives
+release_suffix=$release_suffix
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$ltecho
+
+# The archiver.
+AR=$AR
+
+# The default C compiler.
+CC=$CC
+
+# The linker used to build libraries.
+LD=$LD
+
+# Whether we need hard or soft links.
+LN_S=$LN_S
+
+# A BSD-compatible nm program.
+NM=$NM
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$reload_flag
+reload_cmds=$reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$wl
+
+# Object file suffix (normally "o").
+objext="$objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$pic_flag
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$RANLIB
+old_archive_cmds=$old_archive_cmds
+old_postinstall_cmds=$old_postinstall_cmds
+old_postuninstall_cmds=$old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$old_archive_from_new_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$archive_cmds
+archive_expsym_cmds=$archive_expsym_cmds
+postinstall_cmds=$postinstall_cmds
+postuninstall_cmds=$postuninstall_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$global_symbol_to_cdecl
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$include_expsyms
+
+EOF
+
+case "$ltmain" in
+*.sh)
+  echo '### END LIBTOOL CONFIG' >> "$ofile"
+  echo >> "$ofile"
+  case "$host_os" in
+  aix3*)
+    cat <<\EOF >> "$ofile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "${COLLECT_NAMES+set}" != set; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # Append the ltmain.sh script.
+  sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1)
+
+  chmod +x "$ofile"
+  ;;
+
+*)
+  # Compile the libtool program.
+  echo "FIXME: would compile $ltmain"
+  ;;
+esac
+
+test -n "$cache_file" || exit 0
+
+# AC_CACHE_SAVE
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/acinclude.m4
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/acinclude.m4	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/acinclude.m4	Sat Jul 13 21:26:09 2002
@@ -0,0 +1,876 @@
+dnl $Id: acinclude.m4,v 1.98 2000/06/17 16:13:11 andrei Exp $
+dnl
+dnl This file contains local autoconf functions.
+
+sinclude(dynlib.m4)
+
+dnl PHP_EVAL_LIBLINE(LINE, SHARED-LIBADD)
+dnl
+dnl Use this macro, if you need to add libraries and or library search
+dnl paths to the PHP build system which are only given in compiler
+dnl notation.
+dnl
+AC_DEFUN(PHP_EVAL_LIBLINE,[
+  for ac_i in $1; do
+    case "$ac_i" in
+    -l*)
+      ac_ii=`echo $ac_i|cut -c 3-`
+      AC_ADD_LIBRARY($ac_ii,,$2)
+    ;;
+    -L*)
+      ac_ii=`echo $ac_i|cut -c 3-`
+      AC_ADD_LIBPATH($ac_ii,$2)
+    ;;
+    esac
+  done
+])
+
+dnl PHP_EVAL_INCLINE(LINE)
+dnl
+dnl Use this macro, if you need to add header search paths to the PHP
+dnl build system which are only given in compiler notation.
+dnl
+AC_DEFUN(PHP_EVAL_INCLINE,[
+  for ac_i in $1; do
+    case "$ac_i" in
+    -I*)
+      ac_ii=`echo $ac_i|cut -c 3-`
+      AC_ADD_INCLUDE($ac_ii)
+    ;;
+    esac
+  done
+])
+	
+AC_DEFUN(PHP_READDIR_R_TYPE,[
+  dnl HAVE_READDIR_R is also defined by libmysql
+  AC_CHECK_FUNC(readdir_r,ac_cv_func_readdir_r=yes,ac_cv_func_readdir=no)
+  if test "$ac_cv_func_readdir_r" = "yes"; then
+  AC_CACHE_CHECK(for type of readdir_r, ac_cv_what_readdir_r,[
+    AC_TRY_RUN([
+#define _REENTRANT
+#include <sys/types.h>
+#include <dirent.h>
+
+main() {
+	DIR *dir;
+	struct dirent entry, *pentry;
+
+	dir = opendir("/");
+	if (!dir) 
+		exit(1);
+	if (readdir_r(dir, &entry, &pentry) == 0)
+		exit(0);
+	exit(1);
+}
+    ],[
+      ac_cv_what_readdir_r=POSIX
+    ],[
+      AC_TRY_CPP([
+#define _REENTRANT
+#include <sys/types.h>
+#include <dirent.h>
+int readdir_r(DIR *, struct dirent *);
+        ],[
+          ac_cv_what_readdir_r=old-style
+        ],[
+          ac_cv_what_readdir_r=none
+      ])
+    ],[
+      ac_cv_what_readdir_r=none
+   ])
+  ])
+    case "$ac_cv_what_readdir_r" in
+    POSIX)
+      AC_DEFINE(HAVE_POSIX_READDIR_R,1,[whether you have POSIX readdir_r]);;
+    old-style)
+      AC_DEFINE(HAVE_OLD_READDIR_R,1,[whether you have old-style readdir_r]);;
+    esac
+  fi
+])
+
+AC_DEFUN(PHP_SHLIB_SUFFIX_NAME,[
+  PHP_SUBST(SHLIB_SUFFIX_NAME)
+  SHLIB_SUFFIX_NAME=so
+  case "$host_alias" in
+  *hpux*)
+	SHLIB_SUFFIX_NAME=sl
+	;;
+  esac
+])
+
+AC_DEFUN(PHP_DEBUG_MACRO,[
+  DEBUG_LOG="$1"
+  cat >$1 <<X
+CONFIGURE:  $CONFIGURE_COMMAND
+CC:         $CC
+CFLAGS:     $CFLAGS
+CPPFLAGS:   $CPPFLAGS
+CXX:        $CXX
+CXXFLAGS:   $CXXFLAGS
+INCLUDES:   $INCLUDES
+LDFLAGS:    $LDFLAGS
+LIBS:       $LIBS
+DLIBS:      $DLIBS
+SAPI:       $PHP_SAPI
+PHP_RPATHS: $PHP_RPATHS
+uname -a:   `uname -a`
+
+X
+    cat >conftest.$ac_ext <<X
+main()
+{
+  exit(0);
+}
+X
+    (eval echo \"$ac_link\"; eval $ac_link && ./conftest) >>$1 2>&1
+    rm -fr conftest*
+])
+	
+AC_DEFUN(PHP_MISSING_TIME_R_DECL,[
+  AC_MSG_CHECKING(for missing declarations of reentrant functions)
+  AC_TRY_COMPILE([#include <time.h>],[struct tm *(*func)() = localtime_r],[
+    :
+  ],[
+    AC_DEFINE(MISSING_LOCALTIME_R_DECL,1,[Whether localtime_r is declared])
+  ])
+  AC_TRY_COMPILE([#include <time.h>],[struct tm *(*func)() = gmtime_r],[
+    :
+  ],[
+    AC_DEFINE(MISSING_GMTIME_R_DECL,1,[Whether gmtime_r is declared])
+  ])
+  AC_TRY_COMPILE([#include <time.h>],[char *(*func)() = asctime_r],[
+    :
+  ],[
+    AC_DEFINE(MISSING_ASCTIME_R_DECL,1,[Whether asctime_r is declared])
+  ])
+  AC_TRY_COMPILE([#include <time.h>],[char *(*func)() = ctime_r],[
+    :
+  ],[
+    AC_DEFINE(MISSING_CTIME_R_DECL,1,[Whether ctime_r is declared])
+  ])
+  AC_TRY_COMPILE([#include <string.h>],[char *(*func)() = strtok_r],[
+    :
+  ],[
+    AC_DEFINE(MISSING_STRTOK_R_DECL,1,[Whether strtok_r is declared])
+  ])
+  AC_MSG_RESULT(done)
+])
+
+dnl
+dnl PHP_LIBGCC_LIBPATH(gcc)
+dnl Stores the location of libgcc in libgcc_libpath
+dnl
+AC_DEFUN(PHP_LIBGCC_LIBPATH,[
+  changequote({,})
+  libgcc_libpath="`$1 --print-libgcc-file-name|sed 's%/*[^/][^/]*$%%'`"
+  changequote([,])
+])
+
+AC_DEFUN(PHP_ARG_ANALYZE,[
+case "[$]$1" in
+shared,*)
+  ext_output="yes, shared"
+  ext_shared=yes
+  $1=`echo $ac_n "[$]$1$ac_c"|sed s/^shared,//`
+  ;;
+shared)
+  ext_output="yes, shared"
+  ext_shared=yes
+  $1=yes
+  ;;
+no)
+  ext_output="no"
+  ext_shared=no
+  ;;
+*)
+  ext_output="yes"
+  ext_shared=no
+  ;;
+esac
+
+if test "$php_always_shared" = "yes"; then
+  ext_output="yes, shared"
+  ext_shared=yes
+  test "[$]$1" = "no" && $1=yes
+fi
+
+AC_MSG_RESULT($ext_output)
+])
+
+dnl
+dnl PHP_ARG_WITH(arg-name, check message, help text[, default-val])
+dnl Sets PHP_ARG_NAME either to the user value or to the default value.
+dnl default-val defaults to no. 
+dnl
+AC_DEFUN(PHP_ARG_WITH,[
+PHP_REAL_ARG_WITH([$1],[$2],[$3],[$4],PHP_[]translit($1,a-z-,A-Z_))
+])
+
+AC_DEFUN(PHP_REAL_ARG_WITH,[
+AC_MSG_CHECKING($2)
+AC_ARG_WITH($1,[$3],$5=[$]withval,$5=ifelse($4,,no,$4))
+PHP_ARG_ANALYZE($5)
+])
+
+dnl
+dnl PHP_ARG_ENABLE(arg-name, check message, help text[, default-val])
+dnl Sets PHP_ARG_NAME either to the user value or to the default value.
+dnl default-val defaults to no. 
+dnl
+AC_DEFUN(PHP_ARG_ENABLE,[
+PHP_REAL_ARG_ENABLE([$1],[$2],[$3],[$4],PHP_[]translit($1,a-z-,A-Z_))
+])
+
+AC_DEFUN(PHP_REAL_ARG_ENABLE,[
+AC_MSG_CHECKING($2)
+AC_ARG_ENABLE($1,[$3],$5=[$]enableval,$5=ifelse($4,,no,$4))
+PHP_ARG_ANALYZE($5)
+])
+
+AC_DEFUN(PHP_MODULE_PTR,[
+  EXTRA_MODULE_PTRS="$EXTRA_MODULE_PTRS $1,"
+])
+ 
+AC_DEFUN(PHP_CONFIG_NICE,[
+  rm -f $1
+  cat >$1<<EOF
+#! /bin/sh
+#
+# Created by configure
+
+EOF
+
+  for arg in [$]0 "[$]@"; do
+    echo "\"[$]arg\" \\" >> $1
+  done
+  echo '"[$]@"' >> $1
+  chmod +x $1
+])
+
+AC_DEFUN(PHP_TIME_R_TYPE,[
+AC_CACHE_CHECK(for type of reentrant time-related functions, ac_cv_time_r_type,[
+AC_TRY_RUN([
+#include <time.h>
+#include <stdlib.h>
+
+main() {
+char buf[27];
+struct tm t;
+time_t old = 0;
+int r, s;
+
+s = gmtime_r(&old, &t);
+r = (int) asctime_r(&t, buf, 26);
+if (r == s && s == 0) exit(0);
+exit(1);
+}
+],[
+  ac_cv_time_r_type=hpux
+],[
+  ac_cv_time_r_type=POSIX
+],[
+  ac_cv_time_r_type=POSIX
+])
+])
+if test "$ac_cv_time_r_type" = "hpux"; then
+  AC_DEFINE(PHP_HPUX_TIME_R,1,[Whether you have HP-UX 10.x])
+fi
+])
+
+AC_DEFUN(PHP_SUBST,[
+  PHP_VAR_SUBST="$PHP_VAR_SUBST $1"
+  AC_SUBST($1)
+])
+
+AC_DEFUN(PHP_FAST_OUTPUT,[
+  PHP_FAST_OUTPUT_FILES="$PHP_FAST_OUTPUT_FILES $1"
+])
+
+AC_DEFUN(PHP_MKDIR_P_CHECK,[
+  AC_CACHE_CHECK(for working mkdir -p, ac_cv_mkdir_p,[
+    test -d conftestdir && rm -rf conftestdir
+    mkdir -p conftestdir/somedir >/dev/null 2>&1
+    if test -d conftestdir/somedir; then
+      ac_cv_mkdir_p=yes
+    else
+      ac_cv_mkdir_p=no
+    fi
+    rm -rf conftestdir
+  ])
+])
+
+AC_DEFUN(PHP_GEN_CONFIG_VARS,[
+  PHP_MKDIR_P_CHECK
+  echo creating config_vars.mk
+  > config_vars.mk
+  for i in $PHP_VAR_SUBST; do
+    eval echo "$i = \$$i" >> config_vars.mk
+  done
+])
+
+AC_DEFUN(PHP_GEN_MAKEFILES,[
+  $SHELL $srcdir/build/fastgen.sh $srcdir $ac_cv_mkdir_p $PHP_FAST_OUTPUT_FILES
+])
+
+AC_DEFUN(PHP_TM_GMTOFF,[
+AC_CACHE_CHECK([for tm_gmtoff in struct tm], ac_cv_struct_tm_gmtoff,
+[AC_TRY_COMPILE([#include <sys/types.h>
+#include <$ac_cv_struct_tm>], [struct tm tm; tm.tm_gmtoff;],
+  ac_cv_struct_tm_gmtoff=yes, ac_cv_struct_tm_gmtoff=no)])
+
+if test "$ac_cv_struct_tm_gmtoff" = yes; then
+  AC_DEFINE(HAVE_TM_GMTOFF,1,[whether you have tm_gmtoff in struct tm])
+fi
+])
+
+dnl PHP_CONFIGURE_PART(MESSAGE)
+dnl Idea borrowed from mm
+AC_DEFUN(PHP_CONFIGURE_PART,[
+  AC_MSG_RESULT()
+  AC_MSG_RESULT(${T_MD}$1${T_ME})
+])
+
+AC_DEFUN(PHP_PROG_SENDMAIL,[
+AC_PATH_PROG(PROG_SENDMAIL, sendmail, /usr/lib/sendmail, $PATH:/usr/bin:/usr/sbin:/usr/etc:/etc:/usr/ucblib)
+if test -n "$PROG_SENDMAIL"; then
+  AC_DEFINE(HAVE_SENDMAIL,1,[whether you have sendmail])
+fi
+])
+
+AC_DEFUN(PHP_RUNPATH_SWITCH,[
+dnl check for -R, etc. switch
+AC_MSG_CHECKING(if compiler supports -R)
+AC_CACHE_VAL(php_cv_cc_dashr,[
+	SAVE_LIBS="${LIBS}"
+	LIBS="-R /usr/lib ${LIBS}"
+	AC_TRY_LINK([], [], php_cv_cc_dashr=yes, php_cv_cc_dashr=no)
+	LIBS="${SAVE_LIBS}"])
+AC_MSG_RESULT($php_cv_cc_dashr)
+if test $php_cv_cc_dashr = "yes"; then
+	ld_runpath_switch="-R"
+else
+	AC_MSG_CHECKING([if compiler supports -Wl,-rpath,])
+	AC_CACHE_VAL(php_cv_cc_rpath,[
+		SAVE_LIBS="${LIBS}"
+		LIBS="-Wl,-rpath,/usr/lib ${LIBS}"
+		AC_TRY_LINK([], [], php_cv_cc_rpath=yes, php_cv_cc_rpath=no)
+		LIBS="${SAVE_LIBS}"])
+	AC_MSG_RESULT($php_cv_cc_rpath)
+	if test $php_cv_cc_rpath = "yes"; then
+		ld_runpath_switch="-Wl,-rpath,"
+	else
+		dnl something innocuous
+		ld_runpath_switch="-L"
+	fi
+fi
+])
+
+AC_DEFUN(PHP_STRUCT_FLOCK,[
+AC_CACHE_CHECK(for struct flock,ac_cv_struct_flock,
+    AC_TRY_COMPILE([
+#include <unistd.h>
+#include <fcntl.h>
+        ],
+        [struct flock x;],
+        [
+          ac_cv_struct_flock=yes
+        ],[
+          ac_cv_struct_flock=no
+        ])
+)
+if test "$ac_cv_struct_flock" = "yes" ; then
+    AC_DEFINE(HAVE_STRUCT_FLOCK, 1,[whether you have struct flock])
+fi
+])
+
+AC_DEFUN(PHP_SOCKLEN_T,[
+AC_CACHE_CHECK(for socklen_t,ac_cv_socklen_t,
+  AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+],[
+socklen_t x;
+],[
+  ac_cv_socklen_t=yes
+],[
+  ac_cv_socklen_t=no
+]))
+if test "$ac_cv_socklen_t" = "yes"; then
+  AC_DEFINE(HAVE_SOCKLEN_T, 1, [Whether you have socklen_t])
+fi
+])
+
+dnl
+dnl PHP_SET_SYM_FILE(path)
+dnl
+dnl set the path of the file which contains the symbol export list
+dnl
+AC_DEFUN(PHP_SET_SYM_FILE,
+[
+  PHP_SYM_FILE="$1"
+])
+
+dnl
+dnl PHP_BUILD_THREAD_SAFE
+dnl
+AC_DEFUN(PHP_BUILD_THREAD_SAFE,[
+  enable_experimental_zts=yes
+  if test "$pthreads_working" != "yes"; then
+    AC_MSG_ERROR(ZTS currently requires working POSIX threads. Your system does not support this.)
+  fi
+])
+
+dnl
+dnl PHP_BUILD_SHARED
+dnl
+AC_DEFUN(PHP_BUILD_SHARED,[
+  php_build_target=shared
+])
+
+dnl
+dnl PHP_BUILD_STATIC
+dnl
+AC_DEFUN(PHP_BUILD_STATIC,[
+  php_build_target=static
+])
+
+dnl
+dnl PHP_BUILD_PROGRAM
+dnl
+AC_DEFUN(PHP_BUILD_PROGRAM,[
+  php_build_target=program
+])
+
+dnl
+dnl AC_PHP_ONCE(namespace, variable, code)
+dnl
+dnl execute code, if variable is not set in namespace
+dnl
+AC_DEFUN(AC_PHP_ONCE,[
+  changequote({,})
+  unique=`echo $2|sed 's/[^a-zA-Z0-9]/_/g'`
+  changequote([,])
+  cmd="echo $ac_n \"\$$1$unique$ac_c\""
+  if test -n "$unique" && test "`eval $cmd`" = "" ; then
+    eval "$1$unique=set"
+    $3
+  fi
+])
+
+dnl
+dnl AC_EXPAND_PATH(path, variable)
+dnl
+dnl expands path to an absolute path and assigns it to variable
+dnl
+AC_DEFUN(AC_EXPAND_PATH,[
+  if test -z "$1" || echo "$1" | grep '^/' >/dev/null ; then
+    $2="$1"
+  else
+    changequote({,})
+    ep_dir="`echo $1|sed 's%/*[^/][^/]*$%%'`"
+    changequote([,])
+    ep_realdir="`(cd \"$ep_dir\" && pwd)`"
+    $2="$ep_realdir/`basename \"$1\"`"
+  fi
+])
+
+dnl
+dnl AC_ADD_LIBPATH(path[, shared-libadd])
+dnl
+dnl add a library to linkpath/runpath
+dnl
+AC_DEFUN(AC_ADD_LIBPATH,[
+  if test "$1" != "/usr/lib"; then
+    AC_EXPAND_PATH($1, ai_p)
+    if test "$ext_shared" = "yes" && test -n "$2"; then
+      $2="-R$1 -L$1 [$]$2"
+    else
+      AC_PHP_ONCE(LIBPATH, $ai_p, [
+        test -n "$ld_runpath_switch" && LDFLAGS="$LDFLAGS $ld_runpath_switch$ai_p"
+        LDFLAGS="$LDFLAGS -L$ai_p"
+        PHP_RPATHS="$PHP_RPATHS $ai_p"
+      ])
+    fi
+  fi
+])
+
+dnl
+dnl AC_BUILD_RPATH()
+dnl
+dnl builds RPATH from PHP_RPATHS
+dnl
+AC_DEFUN(AC_BUILD_RPATH,[
+  if test "$PHP_RPATH" = "yes" && test -n "$PHP_RPATHS"; then
+    OLD_RPATHS="$PHP_RPATHS"
+    PHP_RPATHS=""
+    for i in $OLD_RPATHS; do
+      PHP_LDFLAGS="$PHP_LDFLAGS -L$i"
+      PHP_RPATHS="$PHP_RPATHS -R $i"
+      NATIVE_RPATHS="$NATIVE_RPATHS ${ld_runpath_switch}$i"
+    done
+  fi
+])
+
+dnl
+dnl AC_ADD_INCLUDE(path)
+dnl
+dnl add a include path
+dnl
+AC_DEFUN(AC_ADD_INCLUDE,[
+  if test "$1" != "/usr/include"; then
+    AC_EXPAND_PATH($1, ai_p)
+    AC_PHP_ONCE(INCLUDEPATH, $ai_p, [
+      INCLUDES="$INCLUDES -I$ai_p"
+    ])
+  fi
+])
+
+AC_DEFUN(PHP_X_ADD_LIBRARY,[
+  ifelse($2,,$3="-l$1 [$]$3", $3="[$]$3 -l$1")
+])
+
+dnl
+dnl AC_ADD_LIBRARY(library[, append[, shared-libadd]])
+dnl
+dnl add a library to the link line
+dnl
+AC_DEFUN(AC_ADD_LIBRARY,[
+ case "$1" in
+ c|c_r|pthread*) ;;
+ *)
+ifelse($3,,[
+   AC_PHP_ONCE(LIBRARY, $1, [
+     PHP_X_ADD_LIBRARY($1,$2,LIBS)
+   ])
+],[
+   if test "$ext_shared" = "yes"; then
+     PHP_X_ADD_LIBRARY($1,$2,$3)
+   else
+     AC_ADD_LIBRARY($1,$2)
+   fi
+])
+  ;;
+  esac
+])
+
+dnl
+dnl AC_ADD_LIBRARY_DEFER(library[, append])
+dnl
+dnl add a library to the link line (deferred)
+AC_DEFUN(AC_ADD_LIBRARY_DEFER,[
+  AC_PHP_ONCE(LIBRARY, $1, [
+    ifelse($#, 1, DLIBS="-l$1 $DLIBS", DLIBS="$DLIBS -l$1")
+  ])
+])
+
+dnl
+dnl AC_ADD_LIBRARY_WITH_PATH(library, path[, shared-libadd])
+dnl
+dnl add a library to the link line and path to linkpath/runpath.
+dnl if shared-libadd is not empty and $ext_shared is yes,
+dnl shared-libadd will be assigned the library information
+dnl
+AC_DEFUN(AC_ADD_LIBRARY_WITH_PATH,[
+ifelse($3,,[
+  if test -n "$2"; then
+    AC_ADD_LIBPATH($2)
+  fi
+  AC_ADD_LIBRARY($1)
+],[
+  if test "$ext_shared" = "yes"; then
+    $3="-l$1 [$]$3"
+    if test -n "$2"; then
+      AC_ADD_LIBPATH($2,$3)
+    fi
+  else
+    AC_ADD_LIBRARY_WITH_PATH($1,$2)
+  fi
+])
+])
+
+dnl
+dnl AC_ADD_LIBRARY_DEFER_WITH_PATH(library, path)
+dnl
+dnl add a library to the link line (deferred)
+dnl and path to linkpath/runpath (not deferred)
+dnl
+AC_DEFUN(AC_ADD_LIBRARY_DEFER_WITH_PATH,[
+  AC_ADD_LIBPATH($2)
+  AC_ADD_LIBRARY_DEFER($1)
+])
+
+AC_DEFUN(AM_SET_LIBTOOL_VARIABLE,[
+  LIBTOOL='$(SHELL) $(top_builddir)/libtool $1'
+])
+
+dnl
+dnl Check for cc option
+dnl
+AC_DEFUN(AC_CHECK_CC_OPTION,[
+  echo "main(){return 0;}" > conftest.$ac_ext
+  opt="$1"
+  changequote({,})
+  var=`echo $opt|sed 's/[^a-zA-Z0-9]/_/g'`
+  changequote([,])
+  AC_MSG_CHECKING([if compiler supports -$1 really])
+  ac_php_compile="${CC-cc} -$opt -o conftest $CFLAGS $CPPFLAGS conftest.$ac_ext 2>&1"
+  if eval $ac_php_compile 2>&1 | egrep "$opt" > /dev/null 2>&1 ; then
+    eval php_cc_$var=no
+	AC_MSG_RESULT(no)
+  else
+    if eval ./conftest 2>/dev/null ; then
+      eval php_cc_$var=yes
+	  AC_MSG_RESULT(yes)
+    else
+      eval php_cc_$var=no
+	  AC_MSG_RESULT(no)
+    fi
+  fi
+])
+
+AC_DEFUN(PHP_REGEX,[
+
+if test "$REGEX_TYPE" = "php"; then
+  REGEX_LIB=regex/libregex.la
+  REGEX_DIR=regex
+  AC_DEFINE(HSREGEX,1,[ ])
+  AC_DEFINE(REGEX,1,[ ])
+  PHP_FAST_OUTPUT(regex/Makefile)
+elif test "$REGEX_TYPE" = "system"; then
+  AC_DEFINE(REGEX,0,[ ])
+fi
+
+AC_MSG_CHECKING(which regex library to use)
+AC_MSG_RESULT($REGEX_TYPE)
+
+PHP_SUBST(REGEX_DIR)
+PHP_SUBST(REGEX_LIB)
+PHP_SUBST(HSREGEX)
+])
+
+dnl
+dnl See if we have broken header files like SunOS has.
+dnl
+AC_DEFUN(AC_MISSING_FCLOSE_DECL,[
+  AC_MSG_CHECKING([for fclose declaration])
+  AC_TRY_COMPILE([#include <stdio.h>],[int (*func)() = fclose],[
+    AC_DEFINE(MISSING_FCLOSE_DECL,0,[ ])
+    AC_MSG_RESULT(ok)
+  ],[
+    AC_DEFINE(MISSING_FCLOSE_DECL,1,[ ])
+    AC_MSG_RESULT(missing)
+  ])
+])
+
+dnl
+dnl Check for broken sprintf()
+dnl
+AC_DEFUN(AC_BROKEN_SPRINTF,[
+  AC_CACHE_CHECK(whether sprintf is broken, ac_cv_broken_sprintf,[
+    AC_TRY_RUN([main() {char buf[20];exit(sprintf(buf,"testing 123")!=11); }],[
+      ac_cv_broken_sprintf=no
+    ],[
+      ac_cv_broken_sprintf=yes
+    ],[
+      ac_cv_broken_sprintf=no
+    ])
+  ])
+  if test "$ac_cv_broken_sprintf" = "yes"; then
+    AC_DEFINE(PHP_BROKEN_SPRINTF, 1, [ ])
+  else
+    AC_DEFINE(PHP_BROKEN_SPRINTF, 0, [ ])
+  fi
+])
+
+dnl
+dnl PHP_EXTENSION(extname [, shared])
+dnl
+dnl Includes an extension in the build.
+dnl
+dnl "extname" is the name of the ext/ subdir where the extension resides
+dnl "shared" can be set to "shared" or "yes" to build the extension as
+dnl a dynamically loadable library.
+dnl
+AC_DEFUN(PHP_EXTENSION,[
+  EXT_SUBDIRS="$EXT_SUBDIRS $1"
+  
+  if test -d "$abs_srcdir/ext/$1"; then
+dnl ---------------------------------------------- Internal Module
+    ext_builddir="ext/$1"
+    ext_srcdir="$abs_srcdir/ext/$1"
+  else
+dnl ---------------------------------------------- External Module
+    ext_builddir="."
+    ext_srcdir="$abs_srcdir"
+  fi
+
+  if test "$2" != "shared" && test "$2" != "yes"; then
+dnl ---------------------------------------------- Static module
+    LIB_BUILD($ext_builddir)
+    EXT_LTLIBS="$EXT_LTLIBS $ext_builddir/lib$1.la"
+    EXT_STATIC="$EXT_STATIC $1"
+  else 
+dnl ---------------------------------------------- Shared module
+    LIB_BUILD($ext_builddir,yes)
+    AC_DEFINE_UNQUOTED([COMPILE_DL_]translit($1,a-z-,A-Z_), 1, Whether to build $1 as dynamic module)
+  fi
+
+  PHP_FAST_OUTPUT($ext_builddir/Makefile)
+])
+
+PHP_SUBST(EXT_SUBDIRS)
+PHP_SUBST(EXT_STATIC)
+PHP_SUBST(EXT_SHARED)
+PHP_SUBST(EXT_LIBS)
+PHP_SUBST(EXT_LTLIBS)
+
+dnl
+dnl Solaris requires main code to be position independent in order
+dnl to let shared objects find symbols.  Weird.  Ugly.
+dnl
+dnl Must be run after all --with-NN options that let the user
+dnl choose dynamic extensions, and after the gcc test.
+dnl
+AC_DEFUN(PHP_SOLARIS_PIC_WEIRDNESS,[
+  AC_MSG_CHECKING(whether -fPIC is required)
+  if test "$EXT_SHARED" != ""; then
+    os=`uname -sr 2>/dev/null`
+    case "$os" in
+        "SunOS 5.6"|"SunOS 5.7")
+          case "$CC" in
+	    gcc*|egcs*) CFLAGS="$CFLAGS -fPIC";;
+	    *) CFLAGS="$CFLAGS -fpic";;
+	  esac
+	  AC_MSG_RESULT(yes);;
+	*)
+	  AC_MSG_RESULT(no);;
+    esac
+  else
+    AC_MSG_RESULT(no)
+  fi
+])
+
+dnl
+dnl Checks whether $withval is "shared" or starts with "shared,XXX"
+dnl and sets $shared to "yes" or "no", and removes "shared,?" stuff
+dnl from $withval.
+dnl
+AC_DEFUN(PHP_WITH_SHARED,[
+    case $withval in
+	shared)
+	    shared=yes
+	    withval=yes
+	    ;;
+	shared,*)
+	    shared=yes
+	    withval=`echo $withval | sed -e 's/^shared,//'`      
+	    ;;
+	*)
+	    shared=no
+	    ;;
+    esac
+    if test -n "$php_always_shared"; then
+		shared=yes
+	fi
+])
+
+dnl The problem is that the default compilation flags in Solaris 2.6 won't
+dnl let programs access large files;  you need to tell the compiler that
+dnl you actually want your programs to work on large files.  For more
+dnl details about this brain damage please see:
+dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html
+
+dnl Written by Paul Eggert <eggert at twinsun.com>.
+
+AC_DEFUN(AC_SYS_LFS,
+[dnl
+  # If available, prefer support for large files unless the user specified
+  # one of the CPPFLAGS, LDFLAGS, or LIBS variables.
+  AC_MSG_CHECKING(whether large file support needs explicit enabling)
+  ac_getconfs=''
+  ac_result=yes
+  ac_set=''
+  ac_shellvars='CPPFLAGS LDFLAGS LIBS'
+  for ac_shellvar in $ac_shellvars; do
+    case $ac_shellvar in
+      CPPFLAGS) ac_lfsvar=LFS_CFLAGS ;;
+      *) ac_lfsvar=LFS_$ac_shellvar ;;
+    esac
+    eval test '"${'$ac_shellvar'+set}"' = set && ac_set=$ac_shellvar
+    (getconf $ac_lfsvar) >/dev/null 2>&1 || { ac_result=no; break; }
+    ac_getconf=`getconf $ac_lfsvar`
+    ac_getconfs=$ac_getconfs$ac_getconf
+    eval ac_test_$ac_shellvar=\$ac_getconf
+  done
+  case "$ac_result$ac_getconfs" in
+    yes) ac_result=no ;;
+  esac
+  case "$ac_result$ac_set" in
+    yes?*) ac_result="yes, but $ac_set is already set, so use its settings"
+  esac
+  AC_MSG_RESULT($ac_result)
+  case $ac_result in
+    yes)
+      for ac_shellvar in $ac_shellvars; do
+        eval $ac_shellvar=\$ac_test_$ac_shellvar
+      done ;;
+  esac
+])
+
+AC_DEFUN(AC_SOCKADDR_SA_LEN,[
+  AC_CACHE_CHECK([for field sa_len in struct sockaddr],ac_cv_sockaddr_sa_len,[
+    AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/socket.h>],
+    [struct sockaddr s; s.sa_len;],
+    [ac_cv_sockaddr_sa_len=yes
+     AC_DEFINE(HAVE_SOCKADDR_SA_LEN,1,[ ])],
+    [ac_cv_sockaddr_sa_len=no])
+  ])
+])
+
+
+dnl ## PHP_AC_OUTPUT(file)
+dnl ## adds "file" to the list of files generated by AC_OUTPUT
+dnl ## This macro can be used several times.
+AC_DEFUN(PHP_OUTPUT,[
+  PHP_OUTPUT_FILES="$PHP_OUTPUT_FILES $1"
+])
+
+AC_DEFUN(PHP_DECLARED_TIMEZONE,[
+  AC_CACHE_CHECK(for declared timezone, ac_cv_declared_timezone,[
+    AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <time.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+],[
+    time_t foo = (time_t) timezone;
+],[
+  ac_cv_declared_timezone=yes
+],[
+  ac_cv_declared_timezone=no
+])])
+  if test "$ac_cv_declared_timezone" = "yes"; then
+    AC_DEFINE(HAVE_DECLARED_TIMEZONE, 1, [Whether system headers declare timezone])
+  fi
+])
+
+AC_DEFUN(PHP_EBCDIC,[
+  AC_CACHE_CHECK([whether system uses EBCDIC],ac_cv_ebcdic,[
+  AC_TRY_RUN( [
+int main(void) { 
+  return (unsigned char)'A' != (unsigned char)0xC1; 
+} 
+],[
+  ac_cv_ebcdic="yes"
+],[
+  ac_cv_ebcdic="no"
+],[
+  ac_cv_ebcdic="no"
+])])
+  if test "$ac_cv_ebcdic" = "yes"; then
+    AC_DEFINE(CHARSET_EBCDIC,1, [Define if system uses EBCDIC])
+  fi
+])
+

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/INSTALL
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/INSTALL	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/INSTALL	Sat Jul 13 21:26:09 2002
@@ -0,0 +1,79 @@
+$Id: INSTALL,v 1.2 2000/08/07 16:48:48 joeym Exp joeym $
+
+* Installing rrdtool module as a self-contained extension:
+
+There are two ways to install the rrdtool module for php4/zend.
+The first involves simply compiling the rrdtool module as a
+'self-contained extension'.  This is similar to the previous
+rrdtool module for php3 in that to use the rrd_* functions you
+must first load the module in each script that will use the
+rrd_* functions with a dl() call.  See the USAGE file for
+more info on this.
+
+To install as a self-contained extension:
+
+    1.  Install rrdtool.  (Tested with rrdtool-1.0.25)
+        Make sure you build shared and static libraries, if
+        your system lets you.  
+
+        rrdtool% ./configure --enable-shared
+
+    2.  Make sure Apache is installed.
+
+    3.  Make sure PHP4 is installed (tested with php-4.0.1pl2)
+
+    4.  Now we can build the rrdtool module.  
+
+        rrdtool-module% ./configure --with-rrdtool=/usr/local/rrdtool \
+                            --with-php-config=/usr/local/bin/php-config
+
+        'php-config' is usually installed in /usr/local/bin, and is often
+        readable/executable only by root, so you will have to run the
+        configure script as root.
+
+        rrdtool-module% make
+        rrdtool-module% make install
+
+        This should build and install 'rrdtool.so' into the correct
+        directory on your system.
+
+        Now you can access the rrd_* functions from your php4 scripts
+        by first calling "  dl("rrdtool.so"); ".  See the README and USAGE
+        for more info on the rrd_* functions.
+
+
+* Installing the rrdtool module as an embedded extension
+
+Installing rrdtool module as an embedded extension provides all of
+your php4 scripts access to the rrd_* functions without having to
+load any shared libs with the dl() function of php.  
+
+In order to install the rrdtool module as an embedded extension
+you will need to have autoconf/automake and friends installed.
+
+    1. make sure you have the php4 sources untarred somewhere, lets
+        call it /src/php-4.0.1pl2/
+
+    2. create a home for our embedded extension in the php4 source
+        tree.
+
+            % mkdir /src/php-4.0.1pl2/ext/rrdtool
+
+    3. from the rrdtool module directory, do:
+
+            % cp config.m4 Makefile.in php_rrdtool.h rrdtool.c \
+                /src/php-4.0.1pl2/ext/rrdtool/
+
+    4. Now we must recreate the configure scripts, etc for php4.
+    
+            % cd /src/php-4.0.1pl2
+            % ./buildconf
+            
+    5. If all goes well, you should be ready to run configure for
+        php4.  Make sure you include "--with-rrdtool" in the options
+        to configure.  
+
+    6. make, make install.  and you're ready to go.
+
+
+- Joe Miller, <joeym at inficad.com, joeym at ibizcorp.com>, 7/19/2000

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/rrdtool.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/rrdtool.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/rrdtool.c	Sat Jul 13 21:26:10 2002
@@ -0,0 +1,475 @@
+/*
+ *
+ * php4_rrdtool.c
+ *
+ *	PHP interface to RRD Tool. (for php4/zend)
+ *
+ *
+ *       Joe Miller, <joeym at ibizcorp.com>, <joeym at inficad.com> 
+ *          iBIZ Technology Corp,  SkyLynx / Inficad Communications
+ *          2/12/2000 & 7/18/2000
+ *
+ *
+ * See README, INSTALL, and USAGE files for more details.
+ *
+ * $Id: rrdtool.c,v 1.2 2000/08/22 17:30:34 joeym Exp $
+ *
+ */
+
+#include "php.h"
+#include "rrd.h"
+#include "php_rrdtool.h"
+
+#if HAVE_RRDTOOL
+
+function_entry rrdtool_functions[] = {
+	PHP_FE(rrd_error, NULL)
+	PHP_FE(rrd_clear_error, NULL)
+	PHP_FE(rrd_graph, NULL)
+	PHP_FE(rrd_last, NULL)
+	PHP_FE(rrd_fetch, NULL)
+	PHP_FE(rrd_update, NULL)
+	PHP_FE(rrd_create, NULL)
+	{NULL, NULL, NULL}
+};
+
+zend_module_entry rrdtool_module_entry = {
+	"RRDTool",
+	rrdtool_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	PHP_MINFO(rrdtool),
+	STANDARD_MODULE_PROPERTIES,
+};
+
+#ifdef COMPILE_DL_RRDTOOL
+ZEND_GET_MODULE(rrdtool)
+#endif
+
+PHP_MINFO_FUNCTION(rrdtool)
+{
+	php_info_print_table_start();
+	php_info_print_table_header(2, "rrdtool support", "enabled");
+	php_info_print_table_end();
+}
+
+//PHP_MINIT_FUNCTION(rrdtool)
+//{
+//	return SUCCESS;
+//}
+
+
+/* {{{ proto string rrd_error(void)
+	Get the error message set by the last rrd tool function call */
+
+PHP_FUNCTION(rrd_error)
+{
+	char *msg;
+
+	if ( rrd_test_error() )
+	{
+		msg = rrd_get_error();        
+
+		RETVAL_STRING(msg, 1);
+		rrd_clear_error();
+	}
+	else
+		return;
+}
+/* }}} */
+
+
+
+/* {{{ proto void rrd_clear_error(void)
+	Clear the error set by the last rrd tool function call */
+
+PHP_FUNCTION(rrd_clear_error)
+{
+	if ( rrd_test_error() )
+		rrd_clear_error();
+
+	return;
+}
+/* }}} */
+
+
+
+/* {{{ proto int rrd_update(string file, string opt) 
+	Update an RRD file with values specified */
+
+PHP_FUNCTION(rrd_update)
+{
+	pval *file, *opt;
+	char **argv;
+
+	if ( rrd_test_error() )
+		rrd_clear_error();
+
+	if ( ZEND_NUM_ARGS() == 2 && 
+		 zend_get_parameters(ht, 2, &file, &opt) == SUCCESS )
+	{
+		convert_to_string(file);
+		convert_to_string(opt);
+
+		argv = (char **) emalloc(4 * sizeof(char *));
+
+		argv[0] = "dummy";
+		argv[1] = estrdup("update");
+		argv[2] = estrdup(file->value.str.val);
+		argv[3] = estrdup(opt->value.str.val);
+
+		optind = 0; opterr = 0;
+		if ( rrd_update(3, &argv[1]) != -1 )
+		{
+			RETVAL_TRUE;
+		}
+		else
+		{
+			RETVAL_FALSE;
+		}
+		efree(argv[1]); efree(argv[2]); efree(argv[3]);
+		efree(argv);
+	}
+	else
+	{
+		WRONG_PARAM_COUNT;
+	}
+	return;
+}
+/* }}} */
+
+
+
+/* {{{ proto int rrd_last(string file)
+	Gets last update time of an RRD file */
+
+PHP_FUNCTION(rrd_last)
+{
+	pval *file;
+	unsigned long retval;
+
+	char **argv = (char **) emalloc(3 * sizeof(char *));
+    
+	if ( rrd_test_error() )
+		rrd_clear_error();
+    
+	if (zend_get_parameters(ht, 1, &file) == SUCCESS)
+	{
+		convert_to_string(file);
+
+		argv[0] = "dummy";
+		argv[1] = estrdup("last");
+		argv[2] = estrdup(file->value.str.val);
+
+		optind = 0; opterr = 0;
+		retval = rrd_last(2, &argv[1]);
+
+		efree(argv[1]);  efree(argv[2]);
+		efree(argv);
+		RETVAL_LONG(retval);
+	}
+	else
+	{
+		WRONG_PARAM_COUNT;
+	}
+	return;
+}
+/* }}} */
+
+
+/* {{{ proto int rrd_create(string file, array args_arr, int argc)
+	Create an RRD file with the options passed (passed via array) */ 
+
+PHP_FUNCTION(rrd_create)
+{
+	pval *file, *args, *p_argc;
+	pval *entry;
+	char **argv;
+	HashTable *args_arr;
+	int argc, i;
+
+	if ( rrd_test_error() )
+		rrd_clear_error();
+
+	if ( ZEND_NUM_ARGS() == 3 && 
+		getParameters(ht, 3, &file, &args, &p_argc) == SUCCESS )
+	{
+		if ( args->type != IS_ARRAY )
+		{ 
+			php_error(E_WARNING, "2nd Variable passed to rrd_create is not an array!\n");
+			RETURN_FALSE;
+		}
+
+		convert_to_long(p_argc);
+		convert_to_string(file);
+		
+		convert_to_array(args);
+		args_arr = args->value.ht;
+		zend_hash_internal_pointer_reset(args_arr);
+
+		argc = p_argc->value.lval + 3;
+		argv = (char **) emalloc(argc * sizeof(char *));
+
+		argv[0] = "dummy";
+		argv[1] = estrdup("create");
+		argv[2] = estrdup(file->value.str.val);
+
+		for (i = 3; i < argc; i++) 
+		{
+			pval **dataptr;
+
+			if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE )
+				continue;
+
+			entry = *dataptr;
+
+			if ( entry->type != IS_STRING )
+				convert_to_string(entry);
+
+			argv[i] = estrdup(entry->value.str.val);
+
+			if ( i < argc )
+				zend_hash_move_forward(args_arr);
+		}
+  
+		optind = 0;  opterr = 0;
+
+		if ( rrd_create(argc-1, &argv[1]) != -1 )
+		{
+			RETVAL_TRUE;
+		}
+		else
+		{
+			RETVAL_FALSE;
+		}
+		for (i = 1; i < argc; i++)
+			efree(argv[i]);
+
+		efree(argv);
+	}
+	else
+	{
+	    WRONG_PARAM_COUNT;
+	}
+	return;
+}
+/* }}} */
+
+
+
+/* {{{ proto mixed rrd_graph(string file, array args_arr, int argc)
+	Creates a graph based on options passed via an array */
+
+PHP_FUNCTION(rrd_graph)
+{
+	pval *file, *args, *p_argc;
+	pval *entry;
+	zval *p_calcpr;
+	HashTable *args_arr;
+	int i, xsize, ysize, argc;
+	char **argv, **calcpr;
+    
+
+	if ( rrd_test_error() )
+		rrd_clear_error();
+    
+	if ( ZEND_NUM_ARGS() == 3 && 
+		zend_get_parameters(ht, 3, &file, &args, &p_argc) == SUCCESS)
+	{
+		if ( args->type != IS_ARRAY )
+		{ 
+			php_error(E_WARNING, "2nd Variable passed to rrd_graph is not an array!\n");
+			RETURN_FALSE;
+		}
+        
+		convert_to_long(p_argc);
+		convert_to_string(file);
+
+		convert_to_array(args);
+		args_arr = args->value.ht;
+
+		argc = p_argc->value.lval + 3;
+		argv = (char **) emalloc(argc * sizeof(char *));
+ 
+		argv[0] = "dummy";
+		argv[1] = estrdup("graph");
+		argv[2] = estrdup(file->value.str.val);
+
+		for (i = 3; i < argc; i++) 
+		{
+			pval **dataptr;
+
+			if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE )
+				continue;
+
+			entry = *dataptr;
+
+			if ( entry->type != IS_STRING )
+				convert_to_string(entry);
+
+			argv[i] = estrdup(entry->value.str.val);
+
+			if ( i < argc )
+				zend_hash_move_forward(args_arr);
+		}
+   
+		optind = 0; opterr = 0; 
+		if ( rrd_graph(argc-1, &argv[1], &calcpr, &xsize, &ysize) != -1 )
+		{
+			array_init(return_value);
+			add_assoc_long(return_value, "xsize", xsize);
+			add_assoc_long(return_value, "ysize", ysize);
+
+			MAKE_STD_ZVAL(p_calcpr);
+			array_init(p_calcpr);
+    
+			if (calcpr)
+			{
+				for (i = 0; calcpr[i]; i++)
+				{
+					add_next_index_string(p_calcpr, calcpr[i], 1);
+					free(calcpr[i]);
+				}
+				free(calcpr);
+			}
+			zend_hash_update(return_value->value.ht, "calcpr", sizeof("calcpr"), 
+							(void *)&p_calcpr, sizeof(zval *), NULL);
+		}
+		else
+		{
+			RETVAL_FALSE;
+		}
+		for (i = 1; i < argc; i++)
+			efree(argv[i]);
+
+		efree(argv);
+	}
+	else
+	{ 
+		WRONG_PARAM_COUNT;
+	}
+	return;
+}
+/* }}} */
+
+
+
+/* {{{ proto mixed rrd_fetch(string file, array args_arr, int p_argc)
+	Fetch info from an RRD file */
+
+PHP_FUNCTION(rrd_fetch)
+{
+	pval *file, *args, *p_argc;
+	pval *entry;
+	pval *p_start, *p_end, *p_step, *p_ds_cnt;
+	HashTable *args_arr;
+	zval *p_ds_namv, *p_data;
+	int i, argc;
+	time_t start, end;
+	unsigned long step, ds_cnt;
+	char **argv, **ds_namv; 
+	rrd_value_t *data, *datap;
+    
+	if ( rrd_test_error() )
+		rrd_clear_error();
+    
+	if ( ZEND_NUM_ARGS() == 3 && 
+		 zend_get_parameters(ht, 3, &file, &args, &p_argc) == SUCCESS)
+	{
+		if ( args->type != IS_ARRAY )
+		{ 
+			php_error(E_WARNING, "2nd Variable passed to rrd_fetch is not an array!\n");
+			RETURN_FALSE;
+		}
+        
+		convert_to_long(p_argc);
+		convert_to_string(file);
+
+		convert_to_array(args);
+		args_arr = args->value.ht;
+
+		argc = p_argc->value.lval + 3;
+		argv = (char **) emalloc(argc * sizeof(char *));
+ 
+		argv[0] = "dummy";
+		argv[1] = estrdup("fetch");
+		argv[2] = estrdup(file->value.str.val);
+
+		for (i = 3; i < argc; i++) 
+		{
+			pval **dataptr;
+
+			if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE )
+				continue;
+
+			entry = *dataptr;
+
+			if ( entry->type != IS_STRING )
+				convert_to_string(entry);
+
+			argv[i] = estrdup(entry->value.str.val);
+
+			if ( i < argc )
+				zend_hash_move_forward(args_arr);
+		}
+  
+		optind = 0; opterr = 0; 
+
+		if ( rrd_fetch(argc-1, &argv[1], &start,&end,&step,&ds_cnt,&ds_namv,&data) != -1 )
+		{
+			array_init(return_value);
+			add_assoc_long(return_value, "start", start);
+			add_assoc_long(return_value, "end", end);
+			add_assoc_long(return_value, "step", step);
+			add_assoc_long(return_value, "ds_cnt", ds_cnt);
+
+			MAKE_STD_ZVAL(p_ds_namv);
+			MAKE_STD_ZVAL(p_data);
+			array_init(p_ds_namv);
+			array_init(p_data);
+   
+			if (ds_namv)
+			{
+				for (i = 0; i < ds_cnt; i++)
+				{
+					add_next_index_string(p_ds_namv, ds_namv[i], 1);
+					free(ds_namv[i]);
+				}
+				free(ds_namv);
+			}
+
+			if (data)
+			{
+				datap = data;
+ 
+				for (i = start; i <= end; i += step)
+					add_next_index_double(p_data, *(datap++));
+ 
+				free(data);
+			}
+
+			zend_hash_update(return_value->value.ht, "ds_namv", sizeof("ds_namv"), 
+							(void *)&p_ds_namv, sizeof(zval *), NULL);
+			zend_hash_update(return_value->value.ht, "data", sizeof("data"), 
+							(void *)&p_data, sizeof(zval *), NULL);
+		}
+		else
+		{
+			RETVAL_FALSE;
+		}
+		for (i = 1; i < argc; i++)
+			efree(argv[i]);
+
+		efree(argv);
+	}
+	else
+	{ 
+		WRONG_PARAM_COUNT;
+	}
+	return;
+}
+/* }}} */
+
+#endif	/* HAVE_RRDTOOL */

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/php_config.h.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/php_config.h.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/php_config.h.in	Sat Jul 13 21:26:10 2002
@@ -0,0 +1,11 @@
+/* php_config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define if your C compiler doesn't accept -c and -o together.  */
+#undef NO_MINUS_C_MINUS_O
+
+/*   */
+#undef HAVE_RRDTOOL
+
+/* Whether to build rrdtool as dynamic module */
+#undef COMPILE_DL_RRDTOOL
+

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/.deps
==============================================================================

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/missing
==============================================================================

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/aclocal.m4
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/aclocal.m4	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/aclocal.m4	Sat Jul 13 21:26:10 2002
@@ -0,0 +1,1295 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+dnl $Id: acinclude.m4,v 1.98 2000/06/17 16:13:11 andrei Exp $
+dnl
+dnl This file contains local autoconf functions.
+
+sinclude(dynlib.m4)
+
+dnl PHP_EVAL_LIBLINE(LINE, SHARED-LIBADD)
+dnl
+dnl Use this macro, if you need to add libraries and or library search
+dnl paths to the PHP build system which are only given in compiler
+dnl notation.
+dnl
+AC_DEFUN(PHP_EVAL_LIBLINE,[
+  for ac_i in $1; do
+    case "$ac_i" in
+    -l*)
+      ac_ii=`echo $ac_i|cut -c 3-`
+      AC_ADD_LIBRARY($ac_ii,,$2)
+    ;;
+    -L*)
+      ac_ii=`echo $ac_i|cut -c 3-`
+      AC_ADD_LIBPATH($ac_ii,$2)
+    ;;
+    esac
+  done
+])
+
+dnl PHP_EVAL_INCLINE(LINE)
+dnl
+dnl Use this macro, if you need to add header search paths to the PHP
+dnl build system which are only given in compiler notation.
+dnl
+AC_DEFUN(PHP_EVAL_INCLINE,[
+  for ac_i in $1; do
+    case "$ac_i" in
+    -I*)
+      ac_ii=`echo $ac_i|cut -c 3-`
+      AC_ADD_INCLUDE($ac_ii)
+    ;;
+    esac
+  done
+])
+	
+AC_DEFUN(PHP_READDIR_R_TYPE,[
+  dnl HAVE_READDIR_R is also defined by libmysql
+  AC_CHECK_FUNC(readdir_r,ac_cv_func_readdir_r=yes,ac_cv_func_readdir=no)
+  if test "$ac_cv_func_readdir_r" = "yes"; then
+  AC_CACHE_CHECK(for type of readdir_r, ac_cv_what_readdir_r,[
+    AC_TRY_RUN([
+#define _REENTRANT
+#include <sys/types.h>
+#include <dirent.h>
+
+main() {
+	DIR *dir;
+	struct dirent entry, *pentry;
+
+	dir = opendir("/");
+	if (!dir) 
+		exit(1);
+	if (readdir_r(dir, &entry, &pentry) == 0)
+		exit(0);
+	exit(1);
+}
+    ],[
+      ac_cv_what_readdir_r=POSIX
+    ],[
+      AC_TRY_CPP([
+#define _REENTRANT
+#include <sys/types.h>
+#include <dirent.h>
+int readdir_r(DIR *, struct dirent *);
+        ],[
+          ac_cv_what_readdir_r=old-style
+        ],[
+          ac_cv_what_readdir_r=none
+      ])
+    ],[
+      ac_cv_what_readdir_r=none
+   ])
+  ])
+    case "$ac_cv_what_readdir_r" in
+    POSIX)
+      AC_DEFINE(HAVE_POSIX_READDIR_R,1,[whether you have POSIX readdir_r]);;
+    old-style)
+      AC_DEFINE(HAVE_OLD_READDIR_R,1,[whether you have old-style readdir_r]);;
+    esac
+  fi
+])
+
+AC_DEFUN(PHP_SHLIB_SUFFIX_NAME,[
+  PHP_SUBST(SHLIB_SUFFIX_NAME)
+  SHLIB_SUFFIX_NAME=so
+  case "$host_alias" in
+  *hpux*)
+	SHLIB_SUFFIX_NAME=sl
+	;;
+  esac
+])
+
+AC_DEFUN(PHP_DEBUG_MACRO,[
+  DEBUG_LOG="$1"
+  cat >$1 <<X
+CONFIGURE:  $CONFIGURE_COMMAND
+CC:         $CC
+CFLAGS:     $CFLAGS
+CPPFLAGS:   $CPPFLAGS
+CXX:        $CXX
+CXXFLAGS:   $CXXFLAGS
+INCLUDES:   $INCLUDES
+LDFLAGS:    $LDFLAGS
+LIBS:       $LIBS
+DLIBS:      $DLIBS
+SAPI:       $PHP_SAPI
+PHP_RPATHS: $PHP_RPATHS
+uname -a:   `uname -a`
+
+X
+    cat >conftest.$ac_ext <<X
+main()
+{
+  exit(0);
+}
+X
+    (eval echo \"$ac_link\"; eval $ac_link && ./conftest) >>$1 2>&1
+    rm -fr conftest*
+])
+	
+AC_DEFUN(PHP_MISSING_TIME_R_DECL,[
+  AC_MSG_CHECKING(for missing declarations of reentrant functions)
+  AC_TRY_COMPILE([#include <time.h>],[struct tm *(*func)() = localtime_r],[
+    :
+  ],[
+    AC_DEFINE(MISSING_LOCALTIME_R_DECL,1,[Whether localtime_r is declared])
+  ])
+  AC_TRY_COMPILE([#include <time.h>],[struct tm *(*func)() = gmtime_r],[
+    :
+  ],[
+    AC_DEFINE(MISSING_GMTIME_R_DECL,1,[Whether gmtime_r is declared])
+  ])
+  AC_TRY_COMPILE([#include <time.h>],[char *(*func)() = asctime_r],[
+    :
+  ],[
+    AC_DEFINE(MISSING_ASCTIME_R_DECL,1,[Whether asctime_r is declared])
+  ])
+  AC_TRY_COMPILE([#include <time.h>],[char *(*func)() = ctime_r],[
+    :
+  ],[
+    AC_DEFINE(MISSING_CTIME_R_DECL,1,[Whether ctime_r is declared])
+  ])
+  AC_TRY_COMPILE([#include <string.h>],[char *(*func)() = strtok_r],[
+    :
+  ],[
+    AC_DEFINE(MISSING_STRTOK_R_DECL,1,[Whether strtok_r is declared])
+  ])
+  AC_MSG_RESULT(done)
+])
+
+dnl
+dnl PHP_LIBGCC_LIBPATH(gcc)
+dnl Stores the location of libgcc in libgcc_libpath
+dnl
+AC_DEFUN(PHP_LIBGCC_LIBPATH,[
+  changequote({,})
+  libgcc_libpath="`$1 --print-libgcc-file-name|sed 's%/*[^/][^/]*$%%'`"
+  changequote([,])
+])
+
+AC_DEFUN(PHP_ARG_ANALYZE,[
+case "[$]$1" in
+shared,*)
+  ext_output="yes, shared"
+  ext_shared=yes
+  $1=`echo $ac_n "[$]$1$ac_c"|sed s/^shared,//`
+  ;;
+shared)
+  ext_output="yes, shared"
+  ext_shared=yes
+  $1=yes
+  ;;
+no)
+  ext_output="no"
+  ext_shared=no
+  ;;
+*)
+  ext_output="yes"
+  ext_shared=no
+  ;;
+esac
+
+if test "$php_always_shared" = "yes"; then
+  ext_output="yes, shared"
+  ext_shared=yes
+  test "[$]$1" = "no" && $1=yes
+fi
+
+AC_MSG_RESULT($ext_output)
+])
+
+dnl
+dnl PHP_ARG_WITH(arg-name, check message, help text[, default-val])
+dnl Sets PHP_ARG_NAME either to the user value or to the default value.
+dnl default-val defaults to no. 
+dnl
+AC_DEFUN(PHP_ARG_WITH,[
+PHP_REAL_ARG_WITH([$1],[$2],[$3],[$4],PHP_[]translit($1,a-z-,A-Z_))
+])
+
+AC_DEFUN(PHP_REAL_ARG_WITH,[
+AC_MSG_CHECKING($2)
+AC_ARG_WITH($1,[$3],$5=[$]withval,$5=ifelse($4,,no,$4))
+PHP_ARG_ANALYZE($5)
+])
+
+dnl
+dnl PHP_ARG_ENABLE(arg-name, check message, help text[, default-val])
+dnl Sets PHP_ARG_NAME either to the user value or to the default value.
+dnl default-val defaults to no. 
+dnl
+AC_DEFUN(PHP_ARG_ENABLE,[
+PHP_REAL_ARG_ENABLE([$1],[$2],[$3],[$4],PHP_[]translit($1,a-z-,A-Z_))
+])
+
+AC_DEFUN(PHP_REAL_ARG_ENABLE,[
+AC_MSG_CHECKING($2)
+AC_ARG_ENABLE($1,[$3],$5=[$]enableval,$5=ifelse($4,,no,$4))
+PHP_ARG_ANALYZE($5)
+])
+
+AC_DEFUN(PHP_MODULE_PTR,[
+  EXTRA_MODULE_PTRS="$EXTRA_MODULE_PTRS $1,"
+])
+ 
+AC_DEFUN(PHP_CONFIG_NICE,[
+  rm -f $1
+  cat >$1<<EOF
+#! /bin/sh
+#
+# Created by configure
+
+EOF
+
+  for arg in [$]0 "[$]@"; do
+    echo "\"[$]arg\" \\" >> $1
+  done
+  echo '"[$]@"' >> $1
+  chmod +x $1
+])
+
+AC_DEFUN(PHP_TIME_R_TYPE,[
+AC_CACHE_CHECK(for type of reentrant time-related functions, ac_cv_time_r_type,[
+AC_TRY_RUN([
+#include <time.h>
+#include <stdlib.h>
+
+main() {
+char buf[27];
+struct tm t;
+time_t old = 0;
+int r, s;
+
+s = gmtime_r(&old, &t);
+r = (int) asctime_r(&t, buf, 26);
+if (r == s && s == 0) exit(0);
+exit(1);
+}
+],[
+  ac_cv_time_r_type=hpux
+],[
+  ac_cv_time_r_type=POSIX
+],[
+  ac_cv_time_r_type=POSIX
+])
+])
+if test "$ac_cv_time_r_type" = "hpux"; then
+  AC_DEFINE(PHP_HPUX_TIME_R,1,[Whether you have HP-UX 10.x])
+fi
+])
+
+AC_DEFUN(PHP_SUBST,[
+  PHP_VAR_SUBST="$PHP_VAR_SUBST $1"
+  AC_SUBST($1)
+])
+
+AC_DEFUN(PHP_FAST_OUTPUT,[
+  PHP_FAST_OUTPUT_FILES="$PHP_FAST_OUTPUT_FILES $1"
+])
+
+AC_DEFUN(PHP_MKDIR_P_CHECK,[
+  AC_CACHE_CHECK(for working mkdir -p, ac_cv_mkdir_p,[
+    test -d conftestdir && rm -rf conftestdir
+    mkdir -p conftestdir/somedir >/dev/null 2>&1
+    if test -d conftestdir/somedir; then
+      ac_cv_mkdir_p=yes
+    else
+      ac_cv_mkdir_p=no
+    fi
+    rm -rf conftestdir
+  ])
+])
+
+AC_DEFUN(PHP_GEN_CONFIG_VARS,[
+  PHP_MKDIR_P_CHECK
+  echo creating config_vars.mk
+  > config_vars.mk
+  for i in $PHP_VAR_SUBST; do
+    eval echo "$i = \$$i" >> config_vars.mk
+  done
+])
+
+AC_DEFUN(PHP_GEN_MAKEFILES,[
+  $SHELL $srcdir/build/fastgen.sh $srcdir $ac_cv_mkdir_p $PHP_FAST_OUTPUT_FILES
+])
+
+AC_DEFUN(PHP_TM_GMTOFF,[
+AC_CACHE_CHECK([for tm_gmtoff in struct tm], ac_cv_struct_tm_gmtoff,
+[AC_TRY_COMPILE([#include <sys/types.h>
+#include <$ac_cv_struct_tm>], [struct tm tm; tm.tm_gmtoff;],
+  ac_cv_struct_tm_gmtoff=yes, ac_cv_struct_tm_gmtoff=no)])
+
+if test "$ac_cv_struct_tm_gmtoff" = yes; then
+  AC_DEFINE(HAVE_TM_GMTOFF,1,[whether you have tm_gmtoff in struct tm])
+fi
+])
+
+dnl PHP_CONFIGURE_PART(MESSAGE)
+dnl Idea borrowed from mm
+AC_DEFUN(PHP_CONFIGURE_PART,[
+  AC_MSG_RESULT()
+  AC_MSG_RESULT(${T_MD}$1${T_ME})
+])
+
+AC_DEFUN(PHP_PROG_SENDMAIL,[
+AC_PATH_PROG(PROG_SENDMAIL, sendmail, /usr/lib/sendmail, $PATH:/usr/bin:/usr/sbin:/usr/etc:/etc:/usr/ucblib)
+if test -n "$PROG_SENDMAIL"; then
+  AC_DEFINE(HAVE_SENDMAIL,1,[whether you have sendmail])
+fi
+])
+
+AC_DEFUN(PHP_RUNPATH_SWITCH,[
+dnl check for -R, etc. switch
+AC_MSG_CHECKING(if compiler supports -R)
+AC_CACHE_VAL(php_cv_cc_dashr,[
+	SAVE_LIBS="${LIBS}"
+	LIBS="-R /usr/lib ${LIBS}"
+	AC_TRY_LINK([], [], php_cv_cc_dashr=yes, php_cv_cc_dashr=no)
+	LIBS="${SAVE_LIBS}"])
+AC_MSG_RESULT($php_cv_cc_dashr)
+if test $php_cv_cc_dashr = "yes"; then
+	ld_runpath_switch="-R"
+else
+	AC_MSG_CHECKING([if compiler supports -Wl,-rpath,])
+	AC_CACHE_VAL(php_cv_cc_rpath,[
+		SAVE_LIBS="${LIBS}"
+		LIBS="-Wl,-rpath,/usr/lib ${LIBS}"
+		AC_TRY_LINK([], [], php_cv_cc_rpath=yes, php_cv_cc_rpath=no)
+		LIBS="${SAVE_LIBS}"])
+	AC_MSG_RESULT($php_cv_cc_rpath)
+	if test $php_cv_cc_rpath = "yes"; then
+		ld_runpath_switch="-Wl,-rpath,"
+	else
+		dnl something innocuous
+		ld_runpath_switch="-L"
+	fi
+fi
+])
+
+AC_DEFUN(PHP_STRUCT_FLOCK,[
+AC_CACHE_CHECK(for struct flock,ac_cv_struct_flock,
+    AC_TRY_COMPILE([
+#include <unistd.h>
+#include <fcntl.h>
+        ],
+        [struct flock x;],
+        [
+          ac_cv_struct_flock=yes
+        ],[
+          ac_cv_struct_flock=no
+        ])
+)
+if test "$ac_cv_struct_flock" = "yes" ; then
+    AC_DEFINE(HAVE_STRUCT_FLOCK, 1,[whether you have struct flock])
+fi
+])
+
+AC_DEFUN(PHP_SOCKLEN_T,[
+AC_CACHE_CHECK(for socklen_t,ac_cv_socklen_t,
+  AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+],[
+socklen_t x;
+],[
+  ac_cv_socklen_t=yes
+],[
+  ac_cv_socklen_t=no
+]))
+if test "$ac_cv_socklen_t" = "yes"; then
+  AC_DEFINE(HAVE_SOCKLEN_T, 1, [Whether you have socklen_t])
+fi
+])
+
+dnl
+dnl PHP_SET_SYM_FILE(path)
+dnl
+dnl set the path of the file which contains the symbol export list
+dnl
+AC_DEFUN(PHP_SET_SYM_FILE,
+[
+  PHP_SYM_FILE="$1"
+])
+
+dnl
+dnl PHP_BUILD_THREAD_SAFE
+dnl
+AC_DEFUN(PHP_BUILD_THREAD_SAFE,[
+  enable_experimental_zts=yes
+  if test "$pthreads_working" != "yes"; then
+    AC_MSG_ERROR(ZTS currently requires working POSIX threads. Your system does not support this.)
+  fi
+])
+
+dnl
+dnl PHP_BUILD_SHARED
+dnl
+AC_DEFUN(PHP_BUILD_SHARED,[
+  php_build_target=shared
+])
+
+dnl
+dnl PHP_BUILD_STATIC
+dnl
+AC_DEFUN(PHP_BUILD_STATIC,[
+  php_build_target=static
+])
+
+dnl
+dnl PHP_BUILD_PROGRAM
+dnl
+AC_DEFUN(PHP_BUILD_PROGRAM,[
+  php_build_target=program
+])
+
+dnl
+dnl AC_PHP_ONCE(namespace, variable, code)
+dnl
+dnl execute code, if variable is not set in namespace
+dnl
+AC_DEFUN(AC_PHP_ONCE,[
+  changequote({,})
+  unique=`echo $2|sed 's/[^a-zA-Z0-9]/_/g'`
+  changequote([,])
+  cmd="echo $ac_n \"\$$1$unique$ac_c\""
+  if test -n "$unique" && test "`eval $cmd`" = "" ; then
+    eval "$1$unique=set"
+    $3
+  fi
+])
+
+dnl
+dnl AC_EXPAND_PATH(path, variable)
+dnl
+dnl expands path to an absolute path and assigns it to variable
+dnl
+AC_DEFUN(AC_EXPAND_PATH,[
+  if test -z "$1" || echo "$1" | grep '^/' >/dev/null ; then
+    $2="$1"
+  else
+    changequote({,})
+    ep_dir="`echo $1|sed 's%/*[^/][^/]*$%%'`"
+    changequote([,])
+    ep_realdir="`(cd \"$ep_dir\" && pwd)`"
+    $2="$ep_realdir/`basename \"$1\"`"
+  fi
+])
+
+dnl
+dnl AC_ADD_LIBPATH(path[, shared-libadd])
+dnl
+dnl add a library to linkpath/runpath
+dnl
+AC_DEFUN(AC_ADD_LIBPATH,[
+  if test "$1" != "/usr/lib"; then
+    AC_EXPAND_PATH($1, ai_p)
+    if test "$ext_shared" = "yes" && test -n "$2"; then
+      $2="-R$1 -L$1 [$]$2"
+    else
+      AC_PHP_ONCE(LIBPATH, $ai_p, [
+        test -n "$ld_runpath_switch" && LDFLAGS="$LDFLAGS $ld_runpath_switch$ai_p"
+        LDFLAGS="$LDFLAGS -L$ai_p"
+        PHP_RPATHS="$PHP_RPATHS $ai_p"
+      ])
+    fi
+  fi
+])
+
+dnl
+dnl AC_BUILD_RPATH()
+dnl
+dnl builds RPATH from PHP_RPATHS
+dnl
+AC_DEFUN(AC_BUILD_RPATH,[
+  if test "$PHP_RPATH" = "yes" && test -n "$PHP_RPATHS"; then
+    OLD_RPATHS="$PHP_RPATHS"
+    PHP_RPATHS=""
+    for i in $OLD_RPATHS; do
+      PHP_LDFLAGS="$PHP_LDFLAGS -L$i"
+      PHP_RPATHS="$PHP_RPATHS -R $i"
+      NATIVE_RPATHS="$NATIVE_RPATHS ${ld_runpath_switch}$i"
+    done
+  fi
+])
+
+dnl
+dnl AC_ADD_INCLUDE(path)
+dnl
+dnl add a include path
+dnl
+AC_DEFUN(AC_ADD_INCLUDE,[
+  if test "$1" != "/usr/include"; then
+    AC_EXPAND_PATH($1, ai_p)
+    AC_PHP_ONCE(INCLUDEPATH, $ai_p, [
+      INCLUDES="$INCLUDES -I$ai_p"
+    ])
+  fi
+])
+
+AC_DEFUN(PHP_X_ADD_LIBRARY,[
+  ifelse($2,,$3="-l$1 [$]$3", $3="[$]$3 -l$1")
+])
+
+dnl
+dnl AC_ADD_LIBRARY(library[, append[, shared-libadd]])
+dnl
+dnl add a library to the link line
+dnl
+AC_DEFUN(AC_ADD_LIBRARY,[
+ case "$1" in
+ c|c_r|pthread*) ;;
+ *)
+ifelse($3,,[
+   AC_PHP_ONCE(LIBRARY, $1, [
+     PHP_X_ADD_LIBRARY($1,$2,LIBS)
+   ])
+],[
+   if test "$ext_shared" = "yes"; then
+     PHP_X_ADD_LIBRARY($1,$2,$3)
+   else
+     AC_ADD_LIBRARY($1,$2)
+   fi
+])
+  ;;
+  esac
+])
+
+dnl
+dnl AC_ADD_LIBRARY_DEFER(library[, append])
+dnl
+dnl add a library to the link line (deferred)
+AC_DEFUN(AC_ADD_LIBRARY_DEFER,[
+  AC_PHP_ONCE(LIBRARY, $1, [
+    ifelse($#, 1, DLIBS="-l$1 $DLIBS", DLIBS="$DLIBS -l$1")
+  ])
+])
+
+dnl
+dnl AC_ADD_LIBRARY_WITH_PATH(library, path[, shared-libadd])
+dnl
+dnl add a library to the link line and path to linkpath/runpath.
+dnl if shared-libadd is not empty and $ext_shared is yes,
+dnl shared-libadd will be assigned the library information
+dnl
+AC_DEFUN(AC_ADD_LIBRARY_WITH_PATH,[
+ifelse($3,,[
+  if test -n "$2"; then
+    AC_ADD_LIBPATH($2)
+  fi
+  AC_ADD_LIBRARY($1)
+],[
+  if test "$ext_shared" = "yes"; then
+    $3="-l$1 [$]$3"
+    if test -n "$2"; then
+      AC_ADD_LIBPATH($2,$3)
+    fi
+  else
+    AC_ADD_LIBRARY_WITH_PATH($1,$2)
+  fi
+])
+])
+
+dnl
+dnl AC_ADD_LIBRARY_DEFER_WITH_PATH(library, path)
+dnl
+dnl add a library to the link line (deferred)
+dnl and path to linkpath/runpath (not deferred)
+dnl
+AC_DEFUN(AC_ADD_LIBRARY_DEFER_WITH_PATH,[
+  AC_ADD_LIBPATH($2)
+  AC_ADD_LIBRARY_DEFER($1)
+])
+
+AC_DEFUN(AM_SET_LIBTOOL_VARIABLE,[
+  LIBTOOL='$(SHELL) $(top_builddir)/libtool $1'
+])
+
+dnl
+dnl Check for cc option
+dnl
+AC_DEFUN(AC_CHECK_CC_OPTION,[
+  echo "main(){return 0;}" > conftest.$ac_ext
+  opt="$1"
+  changequote({,})
+  var=`echo $opt|sed 's/[^a-zA-Z0-9]/_/g'`
+  changequote([,])
+  AC_MSG_CHECKING([if compiler supports -$1 really])
+  ac_php_compile="${CC-cc} -$opt -o conftest $CFLAGS $CPPFLAGS conftest.$ac_ext 2>&1"
+  if eval $ac_php_compile 2>&1 | egrep "$opt" > /dev/null 2>&1 ; then
+    eval php_cc_$var=no
+	AC_MSG_RESULT(no)
+  else
+    if eval ./conftest 2>/dev/null ; then
+      eval php_cc_$var=yes
+	  AC_MSG_RESULT(yes)
+    else
+      eval php_cc_$var=no
+	  AC_MSG_RESULT(no)
+    fi
+  fi
+])
+
+AC_DEFUN(PHP_REGEX,[
+
+if test "$REGEX_TYPE" = "php"; then
+  REGEX_LIB=regex/libregex.la
+  REGEX_DIR=regex
+  AC_DEFINE(HSREGEX,1,[ ])
+  AC_DEFINE(REGEX,1,[ ])
+  PHP_FAST_OUTPUT(regex/Makefile)
+elif test "$REGEX_TYPE" = "system"; then
+  AC_DEFINE(REGEX,0,[ ])
+fi
+
+AC_MSG_CHECKING(which regex library to use)
+AC_MSG_RESULT($REGEX_TYPE)
+
+PHP_SUBST(REGEX_DIR)
+PHP_SUBST(REGEX_LIB)
+PHP_SUBST(HSREGEX)
+])
+
+dnl
+dnl See if we have broken header files like SunOS has.
+dnl
+AC_DEFUN(AC_MISSING_FCLOSE_DECL,[
+  AC_MSG_CHECKING([for fclose declaration])
+  AC_TRY_COMPILE([#include <stdio.h>],[int (*func)() = fclose],[
+    AC_DEFINE(MISSING_FCLOSE_DECL,0,[ ])
+    AC_MSG_RESULT(ok)
+  ],[
+    AC_DEFINE(MISSING_FCLOSE_DECL,1,[ ])
+    AC_MSG_RESULT(missing)
+  ])
+])
+
+dnl
+dnl Check for broken sprintf()
+dnl
+AC_DEFUN(AC_BROKEN_SPRINTF,[
+  AC_CACHE_CHECK(whether sprintf is broken, ac_cv_broken_sprintf,[
+    AC_TRY_RUN([main() {char buf[20];exit(sprintf(buf,"testing 123")!=11); }],[
+      ac_cv_broken_sprintf=no
+    ],[
+      ac_cv_broken_sprintf=yes
+    ],[
+      ac_cv_broken_sprintf=no
+    ])
+  ])
+  if test "$ac_cv_broken_sprintf" = "yes"; then
+    AC_DEFINE(PHP_BROKEN_SPRINTF, 1, [ ])
+  else
+    AC_DEFINE(PHP_BROKEN_SPRINTF, 0, [ ])
+  fi
+])
+
+dnl
+dnl PHP_EXTENSION(extname [, shared])
+dnl
+dnl Includes an extension in the build.
+dnl
+dnl "extname" is the name of the ext/ subdir where the extension resides
+dnl "shared" can be set to "shared" or "yes" to build the extension as
+dnl a dynamically loadable library.
+dnl
+AC_DEFUN(PHP_EXTENSION,[
+  EXT_SUBDIRS="$EXT_SUBDIRS $1"
+  
+  if test -d "$abs_srcdir/ext/$1"; then
+dnl ---------------------------------------------- Internal Module
+    ext_builddir="ext/$1"
+    ext_srcdir="$abs_srcdir/ext/$1"
+  else
+dnl ---------------------------------------------- External Module
+    ext_builddir="."
+    ext_srcdir="$abs_srcdir"
+  fi
+
+  if test "$2" != "shared" && test "$2" != "yes"; then
+dnl ---------------------------------------------- Static module
+    LIB_BUILD($ext_builddir)
+    EXT_LTLIBS="$EXT_LTLIBS $ext_builddir/lib$1.la"
+    EXT_STATIC="$EXT_STATIC $1"
+  else 
+dnl ---------------------------------------------- Shared module
+    LIB_BUILD($ext_builddir,yes)
+    AC_DEFINE_UNQUOTED([COMPILE_DL_]translit($1,a-z-,A-Z_), 1, Whether to build $1 as dynamic module)
+  fi
+
+  PHP_FAST_OUTPUT($ext_builddir/Makefile)
+])
+
+PHP_SUBST(EXT_SUBDIRS)
+PHP_SUBST(EXT_STATIC)
+PHP_SUBST(EXT_SHARED)
+PHP_SUBST(EXT_LIBS)
+PHP_SUBST(EXT_LTLIBS)
+
+dnl
+dnl Solaris requires main code to be position independent in order
+dnl to let shared objects find symbols.  Weird.  Ugly.
+dnl
+dnl Must be run after all --with-NN options that let the user
+dnl choose dynamic extensions, and after the gcc test.
+dnl
+AC_DEFUN(PHP_SOLARIS_PIC_WEIRDNESS,[
+  AC_MSG_CHECKING(whether -fPIC is required)
+  if test "$EXT_SHARED" != ""; then
+    os=`uname -sr 2>/dev/null`
+    case "$os" in
+        "SunOS 5.6"|"SunOS 5.7")
+          case "$CC" in
+	    gcc*|egcs*) CFLAGS="$CFLAGS -fPIC";;
+	    *) CFLAGS="$CFLAGS -fpic";;
+	  esac
+	  AC_MSG_RESULT(yes);;
+	*)
+	  AC_MSG_RESULT(no);;
+    esac
+  else
+    AC_MSG_RESULT(no)
+  fi
+])
+
+dnl
+dnl Checks whether $withval is "shared" or starts with "shared,XXX"
+dnl and sets $shared to "yes" or "no", and removes "shared,?" stuff
+dnl from $withval.
+dnl
+AC_DEFUN(PHP_WITH_SHARED,[
+    case $withval in
+	shared)
+	    shared=yes
+	    withval=yes
+	    ;;
+	shared,*)
+	    shared=yes
+	    withval=`echo $withval | sed -e 's/^shared,//'`      
+	    ;;
+	*)
+	    shared=no
+	    ;;
+    esac
+    if test -n "$php_always_shared"; then
+		shared=yes
+	fi
+])
+
+dnl The problem is that the default compilation flags in Solaris 2.6 won't
+dnl let programs access large files;  you need to tell the compiler that
+dnl you actually want your programs to work on large files.  For more
+dnl details about this brain damage please see:
+dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html
+
+dnl Written by Paul Eggert <eggert at twinsun.com>.
+
+AC_DEFUN(AC_SYS_LFS,
+[dnl
+  # If available, prefer support for large files unless the user specified
+  # one of the CPPFLAGS, LDFLAGS, or LIBS variables.
+  AC_MSG_CHECKING(whether large file support needs explicit enabling)
+  ac_getconfs=''
+  ac_result=yes
+  ac_set=''
+  ac_shellvars='CPPFLAGS LDFLAGS LIBS'
+  for ac_shellvar in $ac_shellvars; do
+    case $ac_shellvar in
+      CPPFLAGS) ac_lfsvar=LFS_CFLAGS ;;
+      *) ac_lfsvar=LFS_$ac_shellvar ;;
+    esac
+    eval test '"${'$ac_shellvar'+set}"' = set && ac_set=$ac_shellvar
+    (getconf $ac_lfsvar) >/dev/null 2>&1 || { ac_result=no; break; }
+    ac_getconf=`getconf $ac_lfsvar`
+    ac_getconfs=$ac_getconfs$ac_getconf
+    eval ac_test_$ac_shellvar=\$ac_getconf
+  done
+  case "$ac_result$ac_getconfs" in
+    yes) ac_result=no ;;
+  esac
+  case "$ac_result$ac_set" in
+    yes?*) ac_result="yes, but $ac_set is already set, so use its settings"
+  esac
+  AC_MSG_RESULT($ac_result)
+  case $ac_result in
+    yes)
+      for ac_shellvar in $ac_shellvars; do
+        eval $ac_shellvar=\$ac_test_$ac_shellvar
+      done ;;
+  esac
+])
+
+AC_DEFUN(AC_SOCKADDR_SA_LEN,[
+  AC_CACHE_CHECK([for field sa_len in struct sockaddr],ac_cv_sockaddr_sa_len,[
+    AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/socket.h>],
+    [struct sockaddr s; s.sa_len;],
+    [ac_cv_sockaddr_sa_len=yes
+     AC_DEFINE(HAVE_SOCKADDR_SA_LEN,1,[ ])],
+    [ac_cv_sockaddr_sa_len=no])
+  ])
+])
+
+
+dnl ## PHP_AC_OUTPUT(file)
+dnl ## adds "file" to the list of files generated by AC_OUTPUT
+dnl ## This macro can be used several times.
+AC_DEFUN(PHP_OUTPUT,[
+  PHP_OUTPUT_FILES="$PHP_OUTPUT_FILES $1"
+])
+
+AC_DEFUN(PHP_DECLARED_TIMEZONE,[
+  AC_CACHE_CHECK(for declared timezone, ac_cv_declared_timezone,[
+    AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <time.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+],[
+    time_t foo = (time_t) timezone;
+],[
+  ac_cv_declared_timezone=yes
+],[
+  ac_cv_declared_timezone=no
+])])
+  if test "$ac_cv_declared_timezone" = "yes"; then
+    AC_DEFINE(HAVE_DECLARED_TIMEZONE, 1, [Whether system headers declare timezone])
+  fi
+])
+
+AC_DEFUN(PHP_EBCDIC,[
+  AC_CACHE_CHECK([whether system uses EBCDIC],ac_cv_ebcdic,[
+  AC_TRY_RUN( [
+int main(void) { 
+  return (unsigned char)'A' != (unsigned char)0xC1; 
+} 
+],[
+  ac_cv_ebcdic="yes"
+],[
+  ac_cv_ebcdic="no"
+],[
+  ac_cv_ebcdic="no"
+])])
+  if test "$ac_cv_ebcdic" = "yes"; then
+    AC_DEFINE(CHARSET_EBCDIC,1, [Define if system uses EBCDIC])
+  fi
+])
+
+
+
+# serial 40 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+  [  --disable-libtool-lock  avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw*)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_SHARED, [dnl
+define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<<  --enable-shared[=PKGS]  build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_STATIC, [dnl
+define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<<  --enable-static[=PKGS]  build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl
+define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<<  --enable-fast-install[=PKGS]  optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by GCC])
+  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+  case "$ac_prog" in
+    # Accept absolute paths.
+changequote(,)dnl
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+	test "$with_gnu_ld" != no && break
+      else
+	test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  ac_cv_path_NM="$NM"
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+	ac_cv_path_NM="$ac_dir/nm -B"
+	break
+      elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+	ac_cv_path_NM="$ac_dir/nm -p"
+	break
+      else
+	ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+	continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case "$host" in
+*-*-beos* | *-*-cygwin*)
+  # These system don't have libm
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, main, LIBM="-lm")
+  ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  case "$enable_ltdl_convenience" in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+  esac
+  LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+  INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  AC_CHECK_LIB(ltdl, main,
+  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+  [if test x"$enable_ltdl_install" = xno; then
+     AC_MSG_WARN([libltdl not installed, but installation disabled])
+   else
+     enable_ltdl_install=yes
+   fi
+  ])
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+    INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+  else
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    INCLTDL=
+  fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
+

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/.cvsignore
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/.cvsignore	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/.cvsignore	Sat Jul 13 21:26:11 2002
@@ -0,0 +1,7 @@
+.deps
+Makefile
+*.o
+*.lo
+*.la
+.libs
+libs.mk

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_update.php
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_update.php	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_update.php	Sat Jul 13 21:26:11 2002
@@ -0,0 +1,23 @@
+<?
+
+ ## the following line is only needed if built as a self-contained
+ ## extension.  If you build the rrdtool module as an embedded
+ ## extension, the rrd_* functions will always be available, so you
+ ## do not need the dl() call.
+ dl("rrdtool.so");
+
+ ##
+ ## demonstration of the rrd_update() command
+ ##
+
+  $ret = rrd_update("/some/file.rrd", "N:1245:98344");
+
+  if ( $ret == 0 )
+  {
+      $err = rrd_error();
+      echo "ERROR occurred: $err\n";
+  }
+ /* else rrd_update() was successful */
+
+
+?>

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_last.php
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_last.php	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_last.php	Sat Jul 13 21:26:11 2002
@@ -0,0 +1,26 @@
+<?
+
+ ## the following line is only needed if built as a self-contained
+ ## extension.  If you build the rrdtool module as an embedded
+ ## extension, the rrd_* functions will always be available, so you
+ ## do not need the dl() call.
+ dl("rrdtool.so");
+
+ ##
+ ## demonstration of the rrd_last() command
+ ##
+
+ $ret = rrd_last("/some/path/some-router-fe2.rrd");
+
+ if ( $ret != - 1 )
+ {
+     printf("Last update time:  %s\n", strftime("%m/%d/%Y %H:%M:%S"), $ret);
+ }
+ else
+ {
+     $err_msg = rrd_error();
+     echo "Error occurred:  $err_msg\n";
+ }
+
+
+?>

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_create.php
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_create.php	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_create.php	Sat Jul 13 21:26:11 2002
@@ -0,0 +1,31 @@
+<?
+
+ ## the following line is only needed if built as a self-contained
+ ## extension.  If you build the rrdtool module as an embedded
+ ## extension, the rrd_* functions will always be available, so you
+ ## do not need the dl() call.
+ dl("rrdtool.so");
+
+ ##
+ ## demonstration of the rrd_create() command
+ ##
+
+  $_opts = array( "--step", "300", "--start", 0,
+                 "DS:input:COUNTER:900:0:U",
+                 "DS:output:COUNTER:900:0:U",
+                 "RRA:AVERAGE:0.5:1:1000",
+                 "RRA:MIN:0.5:1:1000",
+                 "RRA:MAX:0.5:1:1000"
+               );
+
+  $ret = rrd_create("/tmp/test.rrd", $_opts, count($_opts));
+
+  if ( $ret == 0 )
+  {
+      $err = rrd_error();
+      echo "Create error: $err\n";
+  }
+  /*  else rrd_create was successful  */
+
+
+?>

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_fetch.php
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_fetch.php	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_fetch.php	Sat Jul 13 21:26:12 2002
@@ -0,0 +1,55 @@
+<?
+
+ ## the following line is only needed if built as a self-contained
+ ## extension.  If you build the rrdtool module as an embedded
+ ## extension, the rrd_* functions will always be available, so you
+ ## do not need the dl() call.
+ dl("rrdtool.so");
+
+ ##
+ ## demonstration of the rrd_fetch() command
+ ##
+
+
+
+  $opts = array ( "AVERAGE", "--start", "-1h" );
+
+  $ret = rrd_fetch("/dir/router-port2.rrd", $opts, count($opts));
+ 
+  ##
+  ## if $ret is an array, rrd_fetch() succeeded
+  ## 
+  if ( is_array($ret) )
+  {
+      echo "Start time    (epoch): $ret[start]\n";
+      echo "End time      (epoch): $ret[end]\n";
+      echo "Step interval (epoch): $ret[step]\n";
+
+      ##
+      ## names of the DS's (data sources) will be 
+      ## contained in the array $ret[ds_namv][..]
+      ##
+      for($i = 0; $i < count($ret[ds_namv]); $i++)
+      {
+          $tmp = $ret[ds_namv][$i];
+          echo "$tmp \n";
+      }
+
+      ##
+      ## all data will be packed into the
+      ## $ret[data][..]  array
+      ##
+      for($i = 0; $i < count($ret[data]); $i++)
+      {
+          $tmp = $ret[data][$i];
+          echo "$hi\n";
+      }
+  }
+  else
+  {
+      $err = rrd_error();
+      echo "fetch() ERROR: $err\n";
+  }
+
+
+?>

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_graph.php
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_graph.php	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/php4/examples/rrd_graph.php	Sat Jul 13 21:26:12 2002
@@ -0,0 +1,47 @@
+<?
+
+ ## the following line is only needed if built as a self-contained
+ ## extension.  If you build the rrdtool module as an embedded
+ ## extension, the rrd_* functions will always be available, so you
+ ## do not need the dl() call.
+ dl("rrdtool.so");
+
+ ##
+ ## demonstration of the rrd_graph() command
+ ##
+
+   $opts = array( "--start", "-4d", 
+                  "DEF:in=/dir/router-port2.rrd:input:AVERAGE",
+                  "DEF:out=/dir/router-port2.rrd:output:AVERAGE",
+                  "LINE2:in#0000ff:Incoming Traffic Avg.",
+                  "PRINT:in:AVERAGE:incoming\: %1.2lf b/s",
+                  "PRINT:in:AVERAGE:incoming2\: %1.2lf b/s"
+                );
+
+
+   $ret = rrd_graph("/some-dir/router-port2.gif", $opts, count($opts));
+
+   ##
+   ## if $ret is an array, then rrd_graph was successful
+   ##
+   if ( is_array($ret) )
+   {
+       echo "Image size:  $ret[xsize] x $ret[ysize]\n";
+       
+
+       ##
+       ## all results from any PRINT commands will be
+       ## in the array $ret[calcpr][..]
+       ##
+       echo "rrd_graph1 print results: \n";
+
+       for ($i = 0; $i < count($ret[calcpr]); $i++)
+           echo $ret[calcpr][$i] . "\n";
+   }
+   else
+   {
+       $err = rrd_error();
+       echo "rrd_graph() ERROR: $err\n";
+   }
+
+?>

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/php4/install-sh
==============================================================================

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/add_ds.pl
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/add_ds.pl	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/add_ds.pl	Sat Jul 13 21:26:12 2002
@@ -0,0 +1,113 @@
+#! /usr/sepp/bin/perl
+
+# add_ds.pl, program to add datasources to an existing RRD 
+#
+#    Copyright (C) 2000 Selena M. Brewington 
+#
+#    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+use strict;
+
+my $ds = shift || die "need number of additional datasources desired";
+if ($ds eq '-h') {
+  &Usage;
+  exit 0;
+}
+
+my $default_val = shift || 'NaN';
+my $type = shift || 'COUNTER';
+my $heartbeat = shift || '1800';
+my $rrdmin = shift || 'NaN';
+my $rrdmax = shift || 'NaN';
+
+my $cdp_prep_end = '</cdp_prep>';
+
+my $row_end = '</row>';
+my $name = '<name>';
+my $name_end = '</name>';
+
+my $field = '<v> ' . $default_val . ' </v>';
+
+my $found_ds = 0;
+my $num_sources = 0;
+my $last;
+my $fields = " ";
+my $datasource;
+my $x;
+
+while (<STDIN>) {
+
+  if (($_ =~ s/$row_end$/$fields$row_end/) && $found_ds) {
+    # need to hit <ds> types first, if we don't, we're screwed
+    print $_; 
+
+  } elsif (/$cdp_prep_end/) {
+    print "\t\t\t<ds><value> NaN </value>  <unknown_datapoints> 0 </unknown_datapoints></ds>\n" x $ds;
+    print $_;
+
+  } elsif (/$name_end$/) {
+    ($datasource) = /$name (\w+)/;
+    $found_ds++;
+    print $_;
+
+  } elsif (/Round Robin Archives/) {
+    # print out additional datasource definitions
+
+    ($num_sources) = ($datasource =~ /(\d+)/);
+    
+    for ($x = $num_sources+1; $x < $num_sources+$ds+1; $x++) {
+
+      $fields .= $field;
+      
+      print "\n\t<ds>\n";
+      print "\t\t<name> ds$x <\/name>\n";
+      print "\t\t<type> $type <\/type>\n";
+      print "\t\t<minimal_heartbeat> $heartbeat <\/minimal_heartbeat>\n";
+      print "\t\t<min> $rrdmin <\/min>\n";
+      print "\t\t<max> $rrdmax <\/max>\n\n";
+      print "\t\t<!-- PDP Status-->\n";
+      print "\t\t<last_ds> NaN <\/last_ds>\n";
+      print "\t\t<value> NaN <\/value>\n";
+      print "\t\t<unknown_sec> NaN <\/unknown_sec>\n"; 
+      print "\t<\/ds>\n\n";
+
+    }
+
+    print $_;
+  } else {
+    print $_;
+  }
+
+  $last = $_;
+}
+
+
+
+
+sub Usage {
+
+  print "add-ds.pl <add'l ds> [default_val] [type] [heartbeat] [rrdmin] [rrdmax] < file.xml\n";
+  print "\t<add'l ds>\tnumber of additional datasources\n";
+  print "\t[default_val]\tdefault value to be entered in add'l fields\n";
+  print "\t[type]\ttype of datasource (i.e. COUNTER, GAUGE...)\n";
+  print "\t[heatbeat]\tlength of time in seconds before RRD thinks your DS is dead\n";
+  print "\t[rrdmin]\tminimum value allowed for each datasource\n";
+  print "\t[rrdmax]\tmax value allowed for each datasource\n\n";
+  print "\tOptions are read in order, so if you want to change the\n";
+  print "\tdefault heartbeat, you need to specify the default_val and\n";
+  print "\ttype as well, etc.\n";
+  print "\n\tOutput goes to STDOUT.\n";
+}
+

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/batch.pl
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/batch.pl	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/batch.pl	Sat Jul 13 21:26:13 2002
@@ -0,0 +1,95 @@
+#! /usr/sepp/bin/perl
+
+# batch.pl, simple program to help add datasources to an existing RRD
+#   goes with add_ds.pl
+#
+#    Copyright (C) 2000 Selena M. Brewington
+#
+#    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+# 
+# for use with add_ds.pl script to add datasources to an RRD
+#
+# usage: ls -1 | ./batch.pl [-o] <# ds to add>
+#
+# -o will let you overwrite your rrds.  i don't recommend using this 
+# switch the first time you run this program.  If something
+# gets messed up, the original xml files will be in the xml
+# directory and you can run 'rrdtool restore' on all of them
+# uncomment the commented out lines below to make this work.
+#
+# also, you can change the name of the directory the XML is
+# getting dumped to, where your rrdtool binary is located, 
+# and where add_ds.pl is located.  the variables are listed 
+# below.
+#
+# This script could theoretically take fully-qualified pathnames
+# as input from STDIN rather than the output from ls -1. 
+#
+
+use strict;
+
+########### USER CONFIGURABLE SECTION #######################
+
+my $newdir = "xml";
+my $rrdtool = "/usr/local/rrdtool-1.0.30/bin/rrdtool";
+my $add_ds = "./add_ds.pl";  # path to add_ds.pl script
+
+########### END CONFIGURE SECTION ###########################
+
+
+my $ds = shift || die 'need number of datasources to add';
+
+my $overwrite = 0;
+
+if ($ds eq '-o') {
+  $overwrite = 1;
+  $ds = shift || die 'need number of datasources to add';
+} 
+
+if (! (-x $newdir)) {
+  `mkdir xml` || die "can't make directory xml";
+}
+
+while (<STDIN>) {
+
+  next if (! /rrd/);
+  chop;
+  my $file = $_;
+
+  $_ =~ s/rrd$/xml/;
+
+  open(FILE, ">$newdir/$_");
+
+  my @output = `$rrdtool dump $file`;
+  print FILE @output;
+
+  close(FILE);
+
+  open (FILE, ">$newdir/$_.2");
+
+  my @new = `cat $newdir/$_ | $add_ds $ds`; 
+
+  print FILE @new;
+
+  close (FILE);
+
+  system("$rrdtool restore $newdir/$_.2 $newdir/$file") == 0 
+    or die "rrdtool restore failed for $file";
+
+  if ($overwrite == 1) {
+    system("mv $newdir/$file $file") == 0
+      or die "can't overwrite $file";
+  }
+}

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/add_ds/add_ds.pl
==============================================================================

Added: trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/add_ds/batch.pl
==============================================================================

Deleted: trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/Makefile.in

Deleted: trunk/orca/packages/rrdtool-1.0.33/contrib/add_ds/Makefile.am

Modified: trunk/orca/packages/rrdtool-1.0.33/perl-piped/RRDp.pm
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/perl-piped/RRDp.pm	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/perl-piped/RRDp.pm	Sat Jul 13 21:26:14 2002
@@ -110,7 +110,7 @@
 sub end ();
 sub read ();
 
-$VERSION = 1.000131 ;
+$VERSION = 1.000331 ;
 
 sub start ($){
   croak "rrdtool is already running"

Modified: trunk/orca/packages/rrdtool-1.0.33/config/acconfig.h
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/config/acconfig.h	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/config/acconfig.h	Sat Jul 13 21:26:14 2002
@@ -40,32 +40,41 @@
 #endif      
 
 #if HAVE_MATH_H
-#  include <math.h>                                                                                                                      
-#endif                                                                                                                                   
-                                                                                                                                         
-#if HAVE_FLOAT_H                                                                                                                         
-#  include <float.h>                                                                                                                     
-#endif                                                                                                                                   
- 
+#  include <math.h>
+#endif
+
+#if HAVE_FLOAT_H
+#  include <float.h>
+#endif
+
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
 
 /* for Solaris */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
-#define HAVE_ISINF 1
-#include <ieeefp.h>
-#define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
 #endif
 
 /* for OSF1 Digital Unix */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
 #  define HAVE_ISINF 1
-#  include <fp_class.h>
 #  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
 #endif
 
-/* for HP-UX 10.20 */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) )
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
 #  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)  
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
 #endif
 
 /* for AIX */
@@ -74,9 +83,14 @@
 #  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
 #endif
 
+#if (! defined (HAVE_FINITE) && defined (HAVE_ISFINITE))
+#  define HAVE_FINITE 1
+#  define finite(a) isfinite(a)
+#endif
+
 #if (! defined(HAVE_FINITE) && defined(HAVE_ISNAN) && defined(HAVE_ISINF))
-#define HAVE_FINITE 1
-#define finite(a) (! isnan(a) && ! isinf(a))
+#  define HAVE_FINITE 1
+#  define finite(a) (! isnan(a) && ! isinf(a))
 #endif
 
 #ifndef HAVE_FINITE
@@ -89,4 +103,3 @@
 
 #endif /* CONFIG_H */
 
-

Modified: trunk/orca/packages/rrdtool-1.0.33/config/config.h.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/config/config.h.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/config/config.h.in	Sat Jul 13 21:26:14 2002
@@ -71,6 +71,9 @@
 /* Define if you have the strchr function.  */
 #undef HAVE_STRCHR
 
+/* Define if you have the strerror function.  */
+#undef HAVE_STRERROR
+
 /* Define if you have the vsnprintf function.  */
 #undef HAVE_VSNPRINTF
 
@@ -83,6 +86,9 @@
 /* Define if you have the <fp_class.h> header file.  */
 #undef HAVE_FP_CLASS_H
 
+/* Define if you have the <ieeefp.h> header file.  */
+#undef HAVE_IEEEFP_H
+
 /* Define if you have the <malloc.h> header file.  */
 #undef HAVE_MALLOC_H
 
@@ -139,32 +145,41 @@
 #endif      
 
 #if HAVE_MATH_H
-#  include <math.h>                                                                                                                      
-#endif                                                                                                                                   
-                                                                                                                                         
-#if HAVE_FLOAT_H                                                                                                                         
-#  include <float.h>                                                                                                                     
-#endif                                                                                                                                   
- 
+#  include <math.h>
+#endif
+
+#if HAVE_FLOAT_H
+#  include <float.h>
+#endif
+
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
 
 /* for Solaris */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
-#define HAVE_ISINF 1
-#include <ieeefp.h>
-#define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
 #endif
 
 /* for OSF1 Digital Unix */
 #if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
 #  define HAVE_ISINF 1
-#  include <fp_class.h>
 #  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
 #endif
 
-/* for HP-UX 10.20 */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) )
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
 #  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)  
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
 #endif
 
 /* for AIX */
@@ -173,9 +188,14 @@
 #  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
 #endif
 
+#if (! defined (HAVE_FINITE) && defined (HAVE_ISFINITE))
+#  define HAVE_FINITE 1
+#  define finite(a) isfinite(a)
+#endif
+
 #if (! defined(HAVE_FINITE) && defined(HAVE_ISNAN) && defined(HAVE_ISINF))
-#define HAVE_FINITE 1
-#define finite(a) (! isnan(a) && ! isinf(a))
+#  define HAVE_FINITE 1
+#  define finite(a) (! isnan(a) && ! isinf(a))
 #endif
 
 #ifndef HAVE_FINITE
@@ -188,4 +208,3 @@
 
 #endif /* CONFIG_H */
 
-

Modified: trunk/orca/packages/rrdtool-1.0.33/config/Makefile.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/config/Makefile.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/config/Makefile.in	Sat Jul 13 21:26:14 2002
@@ -70,15 +70,26 @@
 target_alias = @target_alias@
 target_triplet = @target@
 CC = @CC@
-CFLAGS = @CFLAGS@
 CGI_LIB_DIR = @CGI_LIB_DIR@
 COMP_PERL = @COMP_PERL@
 CPP = @CPP@
 GD_LIB_DIR = @GD_LIB_DIR@
 LIBTOOL = @LIBTOOL@
+NROFF = @NROFF@
 PERL = @PERL@
+PERLFLAGS = @PERLFLAGS@
+PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PNG_LIB_DIR = @PNG_LIB_DIR@
 RANLIB = @RANLIB@
+SO_EXT = @SO_EXT@
+TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
+TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
+TCL_PREFIX = @TCL_PREFIX@
+TCL_SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@
+TCL_SHLIB_LD = @TCL_SHLIB_LD@
+TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+TROFF = @TROFF@
+VERSION = @VERSION@
 ZLIB_LIB_DIR = @ZLIB_LIB_DIR@
 
 AUTOHEADER = @AUTOHEADER@ --localdir=config
@@ -90,12 +101,11 @@
 CONFIG_HEADER = config.h
 CONFIG_CLEAN_FILES = 
 DIST_COMMON =  ./stamp-h.in Makefile.am Makefile.in acconfig.h \
-acinclude.m4 config.guess config.h.in config.sub install-sh ltconfig \
-ltmain.sh missing mkinstalldirs
+config.guess config.h.in config.sub install-sh ltconfig ltmain.sh \
+missing mkinstalldirs
 
 
 PACKAGE = @PACKAGE@
-VERSION = @VERSION@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
@@ -151,7 +161,7 @@
 	@for file in $(DISTFILES); do \
 	  d=$(srcdir); \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$/$$file $(distdir)/$$file; \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
 	    test -f $(distdir)/$$file \
 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \

Modified: trunk/orca/packages/rrdtool-1.0.33/config/ltconfig
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/config/ltconfig	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/config/ltconfig	Sat Jul 13 21:26:15 2002
@@ -663,7 +663,7 @@
   link_static_flag='-static'
 
   case "$host_os" in
-  beos* | irix5* | irix6* | osf3* | osf4*)
+  beos* | irix5* | irix6* | osf3* | osf4* | bsdi3* )
     # PIC is the default for these OSes.
     ;;
   aix*)

Modified: trunk/orca/packages/rrdtool-1.0.33/config/aclocal.m4
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/config/aclocal.m4	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/config/aclocal.m4	Sat Jul 13 21:26:15 2002
@@ -1,4 +1,4 @@
-dnl config/aclocal.m4 generated automatically by aclocal 1.4
+dnl aclocal.m4 generated automatically by aclocal 1.4
 
 dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
@@ -125,6 +125,19 @@
 done<<>>dnl>>)
 changequote([,]))])
 
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi])
+
 
 # serial 40 AC_PROG_LIBTOOL
 AC_DEFUN(AC_PROG_LIBTOOL,
@@ -139,7 +152,7 @@
 LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
 DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
 ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
-$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
 || AC_MSG_ERROR([libtool configure failed])
 
 # Reload cache, that may have been modified by ltconfig
@@ -171,6 +184,11 @@
 AC_REQUIRE([AC_PROG_LN_S])dnl
 dnl
 
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
+esac
+
 # Check for any special flags to pass to ltconfig.
 libtool_flags="--cache-file=$cache_file"
 test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
@@ -189,7 +207,7 @@
 
 # Some flags need to be propagated to the compiler or linker for good
 # libtool support.
-case "$host" in
+case "$lt_target" in
 *-*-irix6*)
   # Find out which ABI we are using.
   echo '[#]line __oline__ "configure"' > conftest.$ac_ext
@@ -405,7 +423,6 @@
   AC_MSG_RESULT(no)
 fi
 test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
-AC_SUBST(LD)
 AC_PROG_LD_GNU
 ])
 
@@ -451,14 +468,13 @@
 fi])
 NM="$ac_cv_path_NM"
 AC_MSG_RESULT([$NM])
-AC_SUBST(NM)
 ])
 
 # AC_CHECK_LIBM - check for math library
 AC_DEFUN(AC_CHECK_LIBM,
 [AC_REQUIRE([AC_CANONICAL_HOST])dnl
 LIBM=
-case "$host" in
+case "$lt_target" in
 *-*-beos* | *-*-cygwin*)
   # These system don't have libm
   ;;

Deleted: trunk/orca/packages/rrdtool-1.0.33/config/acinclude.m4

Modified: trunk/orca/packages/rrdtool-1.0.33/TODO
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/TODO	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/TODO	Sat Jul 13 21:26:16 2002
@@ -1,7 +1,23 @@
 1.1.x Goals
 -----------
 
-let the user define the base resolution of the graph independently of
+ability to completely remove x and y grid
+
+reverse order of stacked graph entries prior to plotting ... this is to make
+plotting order more naturally fit with the ordering of the legend ...
+
+use XDR to write architecture independant date
+
+have drawing methode modifier for the LINE, AREA, STACK functions which allows
+to select wether the data points should be presented as stepes (todays state)
+or connected with lines.
+
+LINEx:ds[#color][/method]:description
+
+be more clever in the fetch function when no complete data coverage for the
+desired area is possible.
+
+Let the user define the base resolution of the graph independently of
 the pixel resolution. If it is smaller than one pixel it will simply
 be ignored
 
@@ -43,3 +59,12 @@
 
 make it possible to define order of legend items independant of their order
 on the commandline ...
+
+have configurable role-over limits for counters
+
+align data points not to GMT but some free offset
+
+allow starting through symlinks called rrdcreate rrdtune and the like
+
+allow time shifiting of data before it is being graphed ... allow overlay of last years data over todays data
+

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/Makefile.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/Makefile.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/Makefile.in	Sat Jul 13 21:26:16 2002
@@ -64,26 +64,37 @@
 target_alias = @target_alias@
 target_triplet = @target@
 CC = @CC@
-CFLAGS = @CFLAGS@
 CGI_LIB_DIR = @CGI_LIB_DIR@
 COMP_PERL = @COMP_PERL@
 CPP = @CPP@
 GD_LIB_DIR = @GD_LIB_DIR@
 LIBTOOL = @LIBTOOL@
+NROFF = @NROFF@
 PERL = @PERL@
+PERLFLAGS = @PERLFLAGS@
+PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PNG_LIB_DIR = @PNG_LIB_DIR@
 RANLIB = @RANLIB@
+SO_EXT = @SO_EXT@
+TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
+TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
+TCL_PREFIX = @TCL_PREFIX@
+TCL_SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@
+TCL_SHLIB_LD = @TCL_SHLIB_LD@
+TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+TROFF = @TROFF@
+VERSION = @VERSION@
 ZLIB_LIB_DIR = @ZLIB_LIB_DIR@
 
-SUFFIXES = .pod .1 .man .html .txt .pm
+SUFFIXES = .pod .1 .man .html .txt .pm .pdf
 
 #AUTOMAKE_OPTIONS        =  foreign
 
 #ACLOCAL_M4 = $(top_srcdir)/config/aclocal.m4
 
-CLEANFILES = *.1 *.html *.txt *-dircache *.pm
+CLEANFILES = *.1 *.html *.txt *-dircache *.pm *.pdf *~ core *itemcache *.rej *.orig
 
-POD = rrdtool.pod rrdlast.pod rrdcreate.pod rrdupdate.pod 	cdeftutorial.pod rpntutorial.pod rrdgraph.pod  bin_dec_hex.pod 	rrdfetch.pod rrdrestore.pod rrddump.pod rrdtune.pod rrdresize.pod 	rrdcgi.pod rrdtutorial.pod
+POD = rrdtool.pod rrdlast.pod rrdcreate.pod rrdupdate.pod  rrdtutorial.es.pod 	cdeftutorial.pod rpntutorial.pod rrdgraph.pod  bin_dec_hex.pod 	rrdfetch.pod rrdrestore.pod rrddump.pod rrdtune.pod rrdresize.pod 	rrdcgi.pod rrdtutorial.pod rrdinfo.pod
 
 
 PMP = RRDs.pm RRDp.pm
@@ -91,6 +102,7 @@
 MAN = $(POD:.pod=.1) $(PMP:.pm=.1) 
 TXT = $(MAN:.1=.txt)
 HTML = $(POD:.pod=.html) $(PMP:.pm=.html) 
+PDF = $(MAN:.1=.pdf)
 
 # what should go into the distribution
 EXTRA_DIST = $(POD) $(HTML) $(TXT)
@@ -111,7 +123,6 @@
 
 
 PACKAGE = @PACKAGE@
-VERSION = @VERSION@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
@@ -119,7 +130,7 @@
 GZIP_ENV = --best
 all: all-redirect
 .SUFFIXES:
-.SUFFIXES: .1 .html .man .pm .pod .txt
+.SUFFIXES: .1 .html .man .pdf .pm .pod .txt
 $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
 	cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps doc/Makefile
 
@@ -196,7 +207,7 @@
 	@for file in $(DISTFILES); do \
 	  d=$(srcdir); \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$/$$file $(distdir)/$$file; \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
 	    test -f $(distdir)/$$file \
 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
@@ -275,7 +286,10 @@
 	pod2man --release=$(VERSION) --center=rrdtool $<  > $@
 
 .1.txt:
-	nroff -man -Tlp $< > $@
+	@NROFF@ -man -Tlp $< > $@
+
+.1.pdf:
+	@TROFF@ -man $< | ps2pdf - $@
 
 .pm.html .pod.html .pl.html:
 	pod2html --infile=$< --outfile=$@ --noindex --htmlroot=. --podpath=. --title=$*
@@ -294,6 +308,8 @@
 
 txt: $(TXT)
 
+pdf: $(PDF)
+
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:

Added: trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.es.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.es.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.es.html	Sat Jul 13 21:26:16 2002
@@ -0,0 +1,1109 @@
+<HTML>
+<HEAD>
+<TITLE>rrdtutorial.es</TITLE>
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
+</HEAD>
+
+<BODY>
+
+<A NAME="__index__"></A>
+<!-- INDEX BEGIN -->
+<!--
+
+<UL>
+
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#description / descripciÓn">DESCRIPTION / DESCRIPCIÓN</A></LI>
+	<LI><A HREF="#tutorial">TUTORIAL</A></LI>
+	<UL>
+
+		<LI><A HREF="#importante">Importante</A></LI>
+		<LI><A HREF="#¿qué es rrdtool">¿Qué es RRDtool?</A></LI>
+		<LI><A HREF="#¿qué datos pueden guardarse en una rrd">¿Qué datos pueden guardarse en una RRD?</A></LI>
+		<LI><A HREF="#¿qué puedo hacer con esta herramienta">¿Qué puedo hacer con esta herramienta?</A></LI>
+		<LI><A HREF="#¿y si aún tengo problemas después de leer este documento">¿Y si aún tengo problemas después de leer este documento?</A></LI>
+		<LI><A HREF="#¿cómo me vas a ayudar">¿Cómo me vas a ayudar?</A></LI>
+		<LI><A HREF="#tu primera base de datos en roundrobin">Tu primera base de datos en round-robin</A></LI>
+		<LI><A HREF="#¿qué hemos creado">¿Qué hemos creado?</A></LI>
+		<LI><A HREF="#hora de hacer algunos gráficos">Hora de hacer algunos gráficos</A></LI>
+		<LI><A HREF="#gráficos con un poco de matemática">Gráficos con un poco de matemática</A></LI>
+		<LI><A HREF="#magia gráfica">Magia gráfica</A></LI>
+		<LI><A HREF="#actualizaciones de verdad">Actualizaciones de verdad</A></LI>
+		<LI><A HREF="#unas palabras sobre snmp">Unas palabras sobre SNMP</A></LI>
+		<LI><A HREF="#un ejemplo real">Un ejemplo real</A></LI>
+		<LI><A HREF="#funciones de consolidación">Funciones de consolidación</A></LI>
+		<LI><A HREF="#repasemos lo que sabemos">Repasemos lo que sabemos</A></LI>
+		<LI><A HREF="#tipos de fuentes de datos">Tipos de fuentes de datos</A></LI>
+		<LI><A HREF="#rrdtool bajo el microscopio">RRDtool bajo el microscopio</A></LI>
+		<LI><A HREF="#reinicialización de los contadores">Reinicialización de los contadores</A></LI>
+		<LI><A HREF="#remuestreo de los datos">Remuestreo de los datos</A></LI>
+	</UL>
+
+	<LI><A HREF="#resumen">RESUMEN</A></LI>
+	<LI><A HREF="#lista de correo">LISTA DE CORREO</A></LI>
+	<LI><A HREF="#ver tambiÉn">VER TAMBIÉN</A></LI>
+	<LI><A HREF="#autor">AUTOR</A></LI>
+</UL>
+-->
+<!-- INDEX END -->
+
+<P>
+<H1><A NAME="name">NAME</A></H1>
+<P>rrdtutorial - Tutorial sobre RRDtool por Alex van den Bogaerdt
+(Traducido al castellano por Jesús Couto Fandiño)</P>
+<div align="right">Versión <a href="rrdtutorial.es.pdf">PDF</a></div><div align="right"><a href="rrdtutorial.html">Enlish</a></div><P>
+<HR>
+<H1><A NAME="description / descripciÓn">DESCRIPTION / DESCRIPCIÓN</A></H1>
+<P>RRDtool es un programa escrito por Tobias Oetiker con la
+colaboración de muchas personas en diversas partes del mundo. Alex van
+den Bogaerdt escribió este documento para ayudarte a entender que es
+RRDtool y que es lo que puede hacer por ti.</P>
+<P>La documentación que viene con RRDtool puede ser demasiado técnica
+para algunos. Este tutorial existe para ayudarte a entender las
+funciones básicas de RRdtool. Debe servirte de preparación para leer la
+documentación, y además explica algunas ideas generales sobre
+estadística, con un enfoque particular hacia las redes.</P>
+<P>
+<HR>
+<H1><A NAME="tutorial">TUTORIAL</A></H1>
+<P>
+<H2><A NAME="importante">Importante</A></H2>
+<P>¡Por favor, no te adelantes en la lectura de este documento! Esta
+primera parte explica los fundamentos básicos. Puede ser aburrida,
+pero si te saltas los fundamentos, los ejemplos no te van a tener
+mucho sentido.</P>
+<P>
+<H2><A NAME="¿qué es rrdtool">¿Qué es RRDtool?</A></H2>
+<P>RRDtool significa ``herramienta de bases de datos en round robin''.
+``Round robin'' es una técnica que implica un número fijo de datos, y un
+apuntador al elemento más reciente. Piensa en un circulo con unos
+cuantos puntos dibujados alrededor del borde; estos puntos son los
+lugares donde se pueden guardar los datos. Dibuja ahora una flecha
+desde el centro del círculo a uno de los puntos; este es el apuntador.
+Cuando se lee o escribe el dato actualmente apuntado, la flecha se
+mueve al próximo elemento. Como estamos en un círculo, no hay ni
+principio ni fin; siempre puedes seguir, eternamente. Al cabo de un
+tiempo ya se habrán usado todas las posiciones disponibles y el
+proceso empieza a reutilizar las antiguas. De esta forma, la base de datos
+no crece en tamaño y, por lo tanto, no requiere ningún mantenimiento.
+RRDtool trabaja con estas bases de datos en ``round-robin'', guardando y
+recuperando datos de ellas.</P>
+<P>
+<H2><A NAME="¿qué datos pueden guardarse en una rrd">¿Qué datos pueden guardarse en una RRD?</A></H2>
+<P>Lo que se te ocurra. Debes poder medir algún valor dado en distintos
+momentos en el tiempo y proveer a RRDtool de estos valores. Si puedes
+hacer esto, RRDtool puede guardar los datos. Los valores tienen que
+ser numéricos, pero no necesariamente enteros, como en MRTG.</P>
+<P>Muchos ejemplos mencionan SNMP, que es el acrónimo de
+``Simple Network Management Protocol'' (Protocolo Simple de
+Administración de Redes). Lo de ``simple'' se refiere al protocolo - no
+se supone que sea fácil administrar o monitorizar una red. Cuando
+hayas terminado con este documento, deberás saber lo suficiente para
+entender cuando oigas a otros hablar sobre
+SNMP. Por ahora, simplemente considera a
+SNMP como una forma de preguntarle a los dispositivos
+por los valores de ciertos contadores que mantienen. Son estos valores
+de estos contadores los que vamos a almacenar en la RRD.</P>
+<P>
+<H2><A NAME="¿qué puedo hacer con esta herramienta">¿Qué puedo hacer con esta herramienta?</A></H2>
+<P>RRDtool se deriva de MRTG (Multi Router
+Traffic Grapher, Graficador De Tráfico de Múltiples Enrutadores).
+MRTG empezó como un pequeño script para poder
+graficar el uso de una conexión a la Internet. Luego evolucionó,
+permitiendo graficar otras fuentes de datos, como temperatura,
+velocidad, voltajes, cantidad de páginas impresas, etc... Lo más
+probable es que empieces a usar RRDtool para guardar y procesar datos
+conseguidos a través de SNMP, y que los datos
+sean el número de bytes (o bits) transferidos desde y hacia una red u
+ordenador. RRDtool te permite crear una base de datos, guardar los
+datos en ellas, recuperarlos y crear gráficos en formato GIF o PNG,
+para mostrarlos en un navegador web. Esas imágenes dependen de los
+datos que hayas guardado y pueden, por ejemplo, ser un sumario del
+promedio de uso de la red, o los picos de tráfico que ocurrieron.
+También lo puedes usar para mostrar el nivel de las mareas, la
+radiación solar, el consumo de electricidad, el número de visitantes
+en una exposición en un momento dado, los niveles de ruido cerca del
+aeropuerto, la temperatura en tu lugar de vacaciones favorito, o en
+la nevera, o cualquier otra cosa que te puedas imaginar, mientras
+tengas algún sensor con el cual medir los datos y seas capaz de
+pasarle los números a RRDtool.</P>
+<P>
+<H2><A NAME="¿y si aún tengo problemas después de leer este documento">¿Y si aún tengo problemas después de leer este documento?</A></H2>
+<P>Lo primero, ¡léelo otra vez!. Puede que te hayas perdido de algo.
+Si no puedes compilar el código fuente y usas un sistema operativo
+bastante común, casi seguro que no es la culpa de RRDtool.
+Probablemente consigas versiones pre-compiladas por la Internet. Si
+provienen de una fuente confiable, úsalas. Si, por otro lado, el
+programa funciona, pero no te da los resultados que tu esperabas,
+puede ser un problema con la configuración; revísala y
+compárala con los ejemplos.</P>
+<P>Hay una lista de correo electrónico y una archivo de la misma. Lee
+la lista durante unas cuantas semanas, y busca en el archivo. Es
+descortés hacer una pregunta sin haber revisado el archivo; ¡puede que
+tu problema ya haya sido resuelto antes! Normalmente ocurre así en todas
+las listas de correo, no sólo esta. Examina la documentación que vino
+con RRDtool para ver donde está el archivo y como usarlo.</P>
+<P>Te sugiero que te tomes un momento y te subscribas a la lista ahora
+mismo, enviando un mensaje a <A HREF="mailto:rrd-users-request at list.ee.ethz.ch">rrd-users-request at list.ee.ethz.ch</A>
+con título <CODE>subscribe</CODE>. Si eventualmente deseas salirte de la lista,
+envía otro correo a la misma dirección, con título <CODE>unsubscribe</CODE>.</P>
+<P>
+<H2><A NAME="¿cómo me vas a ayudar">¿Cómo me vas a ayudar?</A></H2>
+<P>Dándote descripciones y ejemplos detallados. Asumimos que el seguir
+las instrucciones en el orden en que se presentan aquí te dará
+suficiente conocimiento  de RRDtool como para que experimentes por tu
+cuenta. Si no funciona a la primera, puede que te hallas saltado algo;
+siguiendo los ejemplos obtendrás algo de experiencia práctica y, lo
+que es más importante, un poco de información sobre como funciona el
+programa.</P>
+<P>Necesitarás saber algo sobre números hexadecimales. Si no, empieza
+por leer ``bin_dec_hex'' antes de continuar.</P>
+<P>
+<H2><A NAME="tu primera base de datos en roundrobin">Tu primera base de datos en round-robin</A></H2>
+<P>En mi opinión, la mejor forma de aprender algo es haciéndolo. ¿Por
+qué no empezamos ya? Vamos a crear una base de datos, poner unos cuantos
+valores en ella y extraerlos después. La salida que obtengas debe ser
+igual a la que aparece en este documento.</P>
+<P>Empezaremos con algo fácil, comparando un coche con un enrutador, o
+por decirlo de otra forma, comparando kilómetros con bits y bytes. A
+nosotros nos da lo mismo; son unos números obtenidos en un espacio de tiempo.</P>
+<P>Asumamos que tenemos un dispositivo que transfiere bytes desde y
+hacia la Internet. Este dispositivo tiene un contador que empieza en 0
+al encenderse y se incrementa con cada byte transferido. Este contador
+tiene un valor máximo; si ese valor se alcanza y se cuenta un byte
+más, el contador vuelve a empezar desde cero. Esto es exactamente lo
+mismo que pasa con muchos contadores, como el cuentakilómetros del
+coche. En muchas de las disertaciones sobre redes se habla de bits por
+segundo, así que empezaremos por acostumbrarnos a esto. Asumamos que un
+byte son 8 bits y empecemos a pensar en bits y no en bytes. ¡El
+contador, sin embargo, sigue contando en bytes! En el mundo
+SNMP, la mayoría de los contadores tienen una
+longitud de 32 bits. Esto significa que pueden contar desde 0 hasta
+4294967295. Usaremos estos valores en los ejemplos. El dispositivo, cuando 
+le preguntamos, retorna el valor actual del contador. Como sabemos el
+tiempo transcurrido desde la última vez que le preguntamos, sabemos
+cuantos bytes se han transferido <CODE>***en promedio***</CODE> por
+segundo. Esto no es muy difícil de calcular; primero en palabras,
+luego en operaciones:</P>
+<OL>
+<LI>
+Toma el valor actual del contador y réstale el valor anterior
+<P></P>
+<LI>
+Haz lo mismo con la fecha
+<P></P>
+<LI>
+Divide el resultado del paso (1) por el resultado del paso (2).
+El resultado es la cantidad de bytes por segundo. Si lo
+multiplicas por ocho obtienes la cantidad de bits por segundo
+<P></P></OL>
+<PRE>
+  bps = (contador_actual - contador_anterior) / (fecha_actual - fecha_anterior) * 8</PRE>
+<P>Para algunos será de ayuda traducir esto a un ejemplo automotor.
+No prueben estas velocidades en la práctica, y si lo hacen, no me
+echen la culpa por los resultados.</P>
+<P>Usaremos las siguientes abreviaturas:</P>
+<PRE>
+ M:    metros
+ KM:   kilómetros (= 1000 metros).
+ H:    horas
+ S:    segundos
+ KM/H: kilómetros por hora
+ M/S:  metros por segundo</PRE>
+<P>Vas conduciendo un coche. A las 12:05, miras el contador en el
+salpicadero y ves que el coche ha recorrido 12345
+KM. A las 12:10 vuelves a mirar otra vez, y dice
+12357 KM. Quiere decir, que has recorrido 12
+KM en cinco minutos. Un científico convertiría
+esto en metros por segundos; esto es bastante parecido al problema de
+pasar de bytes transferidos en 5 minutos a bits por segundo.</P>
+<P>Viajamos 12 kilómetros, que son 12000 metros. Tardamos 5 minutos, o
+sea 300 segundos. Nuestra velocidad es 12000M / 300S igual a 40 M/S.</P>
+<P>También podemos calcular la velocidad en KM/H: 12 veces 5 minutos
+es una hora, así que multiplicando los 12 KM por 12 obtenemos 144
+KM/H. No intentes esto en casa, o por donde vivo :-)</P>
+<P>Recuerda que estos números son tan sólo promedios. No hay forma de
+deducir, viendo sólo los números, si fuiste a una velocidad constante.
+Hay un ejemplo más adelante en el tutorial que explica esto.</P>
+<P>Espero que entiendas que no hay diferencia entre calcular la
+velocidad en M/S o bps; sólo la forma en que
+recogemos los datos es distinta. Inclusive, la K de kilo en este
+caso es exactamente la misma, ya que en redes k es 1000</P>
+<P>Ahora vamos a crear una base de datos en la que guardar todos estos
+interesantes valores. El método a usar para arrancar el programa puede
+variar de un sistema de operación a otro, pero asumamos que lo puedes
+resolver tu mismo en caso que se diferente en el sistema que usas.
+Asegúrate de no sobreescribir ningún archivo en tu sistema al
+ejecutarlo y escribe todo como una sola línea (tuve que partirlo para
+que fuera legible), saltándote todos los caracteres '\'</P>
+<PRE>
+   rrdtool create test.rrd             \
+            --start 920804400          \
+            DS:speed:COUNTER:600:U:U   \
+            RRA:AVERAGE:0.5:1:24       \
+            RRA:AVERAGE:0.5:6:10</PRE>
+<P>(o sea, escribe: <CODE>rrdtool create test.rrd --start 920804400 DS ...</CODE>)</P>
+<P>
+<H2><A NAME="¿qué hemos creado">¿Qué hemos creado?</A></H2>
+<P>Hemos creado una base de datos en round robin llamada test
+(test.rrd), que empieza desde el mediodía del día en que empecé a
+escribir este documento (7 de marzo de 1999). En ella se guarda una
+fuente de datos (DS), llamada ``speed'', que se
+lee de un contador. En la misma base de datos se guardan dos archivos
+en round robin (RRAs), uno promedia los datos cada vez que se leen (o
+sea, no hay nada que promediar), y mantiene 24 muestras (24 por 5
+minutos = 2 horas de muestras). El otro promedia 6 muestras (media
+hora), y guarda 10 de estos promedios (o sea, 5 horas). Las opciones
+restantes las veremos más adelante.</P>
+<P>RRDtool usa un formato de ``fecha'' especial que viene del mundo de
+UNIX. Estas ``fechas'' son el número de segundos
+que han pasado desde el primero de enero de 1970, zona UTC. Este
+número de segundos se convierte luego en la fecha local, por lo que
+varia según la franja horaria.</P>
+<P>Lo más probable es que tu no vivas en la misma parte del mundo que
+yo, por lo que tu franja horaria será diferente. En los ejemplos,
+cuando mencione horas, puede que no sean las mismas para ti; esto no
+afecta mucho los resultados, sólo tienes que corregir las horas
+mientras lees. Por ejemplo, las 12:05 para mí son las 11:05 para los
+amigos en la Gran Bretaña.</P>
+<P>Ahora tenemos que llenar nuestra base de datos con valores. Vamos a
+suponer que leímos estos datos:</P>
+<PRE>
+ 12:05  12345 KM
+ 12:10  12357 KM
+ 12:15  12363 KM
+ 12:20  12363 KM
+ 12:25  12363 KM
+ 12:30  12373 KM
+ 12:35  12383 KM
+ 12:40  12393 KM
+ 12:45  12399 KM
+ 12:50  12405 KM
+ 12:55  12411 KM
+ 13:00  12415 KM
+ 13:05  12420 KM
+ 13:10  12422 KM
+ 13:15  12423 KM</PRE>
+<P>Llenaremos la base de datos así:</P>
+<PRE>
+ rrdtool update test.rrd 920804700:12345 920805000:12357 920805300:12363
+ rrdtool update test.rrd 920805600:12363 920805900:12363 920806200:12373
+ rrdtool update test.rrd 920806500:12383 920806800:12393 920807100:12399
+ rrdtool update test.rrd 920807400:12405 920807700:12411 920808000:12415
+ rrdtool update test.rrd 920808300:12420 920808600:12422 920808900:12423</PRE>
+<P>Lo que significa: actualiza nuestra base de datos test con los
+siguientes valores:</P>
+<PRE>
+ fecha 920804700, valor 12345
+ fecha 920805000, valor 12357
+</PRE>
+<PRE>
+
+ etcétera.</PRE>
+<P>Como ves, pueden introducirse más de un valor en la base de datos
+por ejecución del comando. Yo los agrupo de tres en tres para hacerlo
+legible, pero en realidad el máximo depende del sistema de operación.</P>
+<P>Ahora podemos recuperar los datos usando ``rrdtool fetch'':</P>
+<PRE>
+ rrdtool fetch test.rrd AVERAGE --start 920804400 --end 920809200</PRE>
+<P>Debes obtener esto como salida:</P>
+<PRE>
+                    speed
+</PRE>
+<PRE>
+
+ 920804400:        NaN
+ 920804700:        NaN
+ 920805000: 4.0000000000e-02
+ 920805300: 2.0000000000e-02
+ 920805600: 0.0000000000e+00
+ 920805900: 0.0000000000e+00
+ 920806200: 3.3333333333e-02
+ 920806500: 3.3333333333e-02
+ 920806800: 3.3333333333e-02
+ 920807100: 2.0000000000e-02
+ 920807400: 2.0000000000e-02
+ 920807700: 2.0000000000e-02
+ 920808000: 1.3333333333e-02
+ 920808300: 1.6666666667e-02
+ 920808600: 6.6666666667e-03
+ 920808900: 3.3333333333e-03
+ 920809200:        NaN</PRE>
+<P>Si no, hay algo mal. Probablemente tu sistema de operación muestre ``NaN''
+de otra forma; representa ``Not a Number'', o sea ``No es un número''. Si
+aparece ``U'' o ``UNKN'' o algo parecido, es lo mismo. Si hay alguna otra
+diferencia, probablemente te equivocaste al introducir algún P valor
+(asumiendo que mi tutorial está bien, por supuesto :-). En ese caso, borra
+la base de datos y prueba de nuevo.</P>
+<P>Lo que representa exactamente esta salida lo vamos más adelante en el tutorial.</P>
+<P>
+<H2><A NAME="hora de hacer algunos gráficos">Hora de hacer algunos gráficos</A></H2>
+<P>Prueba este comando:</P>
+<PRE>
+ rrdtool graph speed.gif                                 \
+         --start 920804400 --end 920808000               \
+         DEF:myspeed=test.rrd:speed:AVERAGE              \
+         LINE2:myspeed#FF0000</PRE>
+<P>Este comando crea speed.gif, un gráfico de los datos desde las
+12:00 hasta las 13:00. Contiene una definición de la variable myspeed
+y define el color como rojo. Notarás que el gráfico no comienza
+exactamente a las 12:00 sino a las 12:05, y es porque no tenemos datos
+suficientes como para calcular el promedio de velocidad antes de ese
+momento. Esto sólo ocurre en caso de que se pierdan algún muestreo, lo
+que esperamos que no debe ocurrir muy a menudo.</P>
+<P>Si ha funcionado, ¡felicitaciones!. Si no, revisa qué puede estar mal.</P>
+<P>La definición de colores se construye a partir del rojo, verde y
+azul. Especificas cuanto de cada uno de estos componentes vas a usar
+en hexadecimal: 00 significa ``nada de este color'' y FF significa
+``este color a máxima intensidad''. El ``color'' blanco es la mezcla
+del rojo, verde y azul a toda intensidad:
+FFFFFF; el negro es la ausencia de todos los colores: 000000.</P>
+<PRE>
+   rojo    #FF0000
+   verde   #00FF00
+   azul    #0000FF
+   violeta #FF00FF     (mezcla de rojo y azul)
+   gris    #555555     (un tercio de cada uno de los colores)</PRE>
+<P>El archivo GIF que acabas de crear puede
+verse con tu visor de archivos de imagen favorito. Los navegadores lo
+mostrarán usando la URL
+``file://el/camino/de/directorios/hasta/speed.gif''</P>
+<P>
+<H2><A NAME="gráficos con un poco de matemática">Gráficos con un poco de matemática</A></H2>
+<P>Cuando veas la imagen, notarás que el eje horizontal tiene unas
+etiquetas marcando las 12:10, 12:20, 12:30, 12:40 y 12:50. Los otros
+dos momentos (12:00 y 13:00) no se pueden mostrar bien por falta de datos, así que
+el programa se los salta. El eje vertical muestra el rango de los valores que
+entramos. Introdujimos los kilómetros y luego dividimos entre 300
+segundos, por lo que obtuvimos valores bastante bajos. Para ser
+exactos, el primer valor, 12 (12357-12345), dividido entre 300 da
+0.04, lo que RRDtool muestra como ``40m'', o sea ``40/1000''. ¡La
+``m''' no tiene nada que ver con metros, kilómetros o milímetros!.
+RRDtool no sabe nada de unidades, el sólo trabaja con números, no con
+metros.</P>
+<P>Donde nos equivocamos fue en que debimos medir en metros. Así,
+(12357000-12345000)/300 = 12000/300 = 40.</P>
+<P>Vamos a corregirlo. Podríamos recrear la base de datos con los
+valores correctos, pero hay una forma mejor: ¡haciendo los cálculos
+mientras creamos el archivo gif!</P>
+<PRE>
+   rrdtool graph speed2.gif                           \
+      --start 920804400 --end 920808000               \
+      --vertical-label m/s                            \
+      DEF:myspeed=test.rrd:speed:AVERAGE              \
+      CDEF:realspeed=myspeed,1000,*                   \
+      LINE2:realspeed#FF0000</PRE>
+<P>Cuando veas esta imagen, notarás que la ``m'' ha desaparecido, y
+ahora tienes los resultados correctos. Además hemos añadido una
+etiqueta a la imagen. Apartando esto, el archivo GIF es el mismo.</P>
+<P>Las operaciones están en la sección del CDEF
+y están escritas en Notación Polaca Inversa (Reverse Polish Notation o
+``RPN''). En palabras, dice: ``toma la fuente de
+datos myspeed y el numero 1000, y multiplícalos''. No te molestes en
+meterte con RPN todavía, la veremos con más
+detalle más adelante. Además, puede que quieras leer mi tutorial sobre
+los CDEF y el tutorial de Steve Rader sobre RPN, pero primero terminemos con este.</P>
+<P>¡Un momento! Si podemos multiplicar los valores por mil, entonces,
+¡también debería ser posible el mostrar la velocidad en kilómetros por
+hora usando los mismos datos!</P>
+<P>Para cambiar el valor que medimos en metros por segundo, calculamos
+los metros por hora (valor * 3600) y dividimos entre 1000 para sacar
+los kilómetros por hora. Todo junto hace valor * (3600/1000) == valor
+* 3.6.</P>
+<P>Como en nuestra base de datos cometimos un error guardando los
+valores en kilómetros, debemos compensar por ello, multiplicando por
+100, por lo que al aplicar esta corrección nos queda valor * 3600.</P>
+<P>Ahora vamos a crear este gif, agreándole un poco más de magia...</P>
+<PRE>
+   rrdtool graph speed3.gif                           \
+      --start 920804400 --end 920808000               \
+      --vertical-label km/h                           \
+      DEF:myspeed=test.rrd:speed:AVERAGE              \
+      &quot;CDEF:kmh=myspeed,3600,*&quot;                       \
+      CDEF:fast=kmh,100,GT,kmh,0,IF                   \
+      CDEF:good=kmh,100,GT,0,kmh,IF                   \
+      HRULE:100#0000FF:&quot;Maximum allowed&quot;              \
+      AREA:good#00FF00:&quot;Good speed&quot;                   \
+      AREA:fast#FF0000:&quot;Too fast&quot;</PRE>
+<P>Esto luce mucho mejor. La velocidad en KM/H,
+y además tenemos una línea extra mostrando la velocidad máxima
+permitida (en el camino por donde conduzco). También le cambie los
+colores de la velocidad, y ahora paso de ser una línea a un área.</P>
+<P>Los cálculos son más complejos ahora. Para calcular la velocidad ``aceptable'':</P>
+<PRE>
+   Verifica si la velocidad en kmh es mayor que 100     ( kmh,100 ) GT           
+   Si es así, retorna 0, si no, retorna la velocidad    ((( kmh,100 ) GT ), 0, kmh) IF</PRE>
+<P>Para calcular la parte de velocidad ``excesiva'':</P>
+<PRE>
+   Verifica si la velocidad en kmh es mayor que 100     ( kmh,100 ) GT
+   Si es así, retorna la velocidad, si no, retorna 0    ((( kmh,100) GT ), kmh, 0) IF</PRE>
+<P>
+<H2><A NAME="magia gráfica">Magia gráfica</A></H2>
+<P>Me gusta creer que virtualmente no hay limites para lo que RRDtool puede
+hacer con los datos. No voy a explicarlo en detalle, pero mira este GIF:</P>
+<PRE>
+   rrdtool graph speed4.gif                           \
+      --start 920804400 --end 920808000               \
+      --vertical-label km/h                           \
+      DEF:myspeed=test.rrd:speed:AVERAGE              \
+      &quot;CDEF:kmh=myspeed,3600,*&quot;                       \
+      CDEF:fast=kmh,100,GT,100,0,IF                   \
+      CDEF:over=kmh,100,GT,kmh,100,-,0,IF             \
+      CDEF:good=kmh,100,GT,0,kmh,IF                   \
+      HRULE:100#0000FF:&quot;Maximum allowed&quot;              \
+      AREA:good#00FF00:&quot;Good speed&quot;                   \
+      AREA:fast#550000:&quot;Too fast&quot;                     \
+      STACK:over#FF0000:&quot;Over speed&quot;</PRE>
+<P>Vamos a crear una página HTML simple para ver los tres archivos GIF:</P>
+<PRE>
+   &lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;Velocidad&lt;/TITLE&gt;&lt;/HEAD&gt;&lt;BODY&gt;
+   &lt;IMG src=&quot;speed2.gif&quot; alt=&quot;Speed in meters per second&quot;&gt;
+   &lt;BR&gt;
+   &lt;IMG src=&quot;speed3.gif&quot; alt=&quot;Speed in kilometers per hour&quot;&gt;
+   &lt;BR&gt;
+   &lt;IMG src=&quot;speed4.gif&quot; alt=&quot;Traveled too fast?&quot;&gt;
+   &lt;/BODY&gt;&lt;/HTML&gt;</PRE>
+<P>Guárdalo como ``speed.html'' o algo parecido, y examínalo con un navegador.</P>
+<P>Ahora, todo lo que tienes que hacer es medir los datos regularmente
+y actualizar la base de datos. Cuando quieras verlos, vuelve a crear
+los archivos GIF y asegúrate que se carguen de nuevo en tu navegador
+(Nota: presionar el botón de ``refrescar'' puede no ser suficiente; en
+particular, Netscape tiene un problema al respecto, por lo que
+necesitaras darle al botón mientras presionas la tecla de mayúsculas.</P>
+<P>
+<H2><A NAME="actualizaciones de verdad">Actualizaciones de verdad</A></H2>
+<P>Ya hemos usado el comando ``update''; vimos que recibia uno o más
+parámetros en el formato: ``&lt;fecha&gt;:&lt;valor&gt;''. Para
+facilitarte las cosas, puedes obtener la fecha actual colocando
+``N'' en la fecha. También podrías usar la función
+``time'' de Perl para obtenerla. El ejemplo más corto de todo el
+tutorial :)</P>
+<PRE>
+   perl -e 'print time, &quot;\n&quot; '</PRE>
+<P>Ahora, la forma de poner a correr un programa a intervalos
+regulares de tiempo depende del sistema de operación. La
+actualización, en pseudo-código, sería:</P>
+<PRE>
+   Toma el valor, colócalo en la variable &quot;$speed&quot;
+   rrdtool update speed.rrd N:$speed</PRE>
+<P>(Pero no lo hagas sobre nuestra base de datos de pruebas, que aún
+la vamos a usar en otros ejemplos.</P>
+<P>Eso es todo. Ejecutando este script cada 5 minutos, lo único que
+tienes que hacer para ver los gráficos actuales es correr los ejemplos
+anteriores, que también puedes poner en un script. Luego de correrlo,
+basta con cargar index.html</P>
+<P>
+<H2><A NAME="unas palabras sobre snmp">Unas palabras sobre SNMP</A></H2>
+<P>Me imagino que muy pocas personas serán capaces de obtener en su
+ordenador datos reales de su coche cada 5 minutos; los demás nos
+tendremos que conformar con algún otro contador. Puedes, por ejemplo,
+medir la cantidad de páginas que ha hecho una impresora, cuanto café
+has hecho con la cafetera, el medidor del consumo de electricidad, o
+cualquier otra cosa. Cualquier contador incremental puede
+monitorizarse y graficarse con lo que has aprendido hasta ahora. Más
+adelante, veremos también como monitorizar otro tipo de valores, como
+la temperatura. La mayoría usaremos alguna vez un contador que lleve
+la cuenta de cuantos octetos (bytes) a transferido un dispositivo de
+red, así que vamos a ver como hacer esto. Empezaremos describiendo
+como recoger los datos. Hay quien dirá que hay herramientas que pueden
+recoger estos datos por ti. ¡Es cierto! Pero, creo que es importante
+darse cuenta de que no son necesarias. Cuando tienes que determinar
+porqué algo no funciona, necesitas saber cómo funciona en primer lugar.</P>
+<P>Una herramienta que mencionamos brevemente al principio del
+documento es SNMP. SNMP es una forma de comunicarse con tus equipos.
+La herramienta particular que voy a usar más adelante se llama
+``snmpget'', y funciona así:</P>
+<PRE>
+   snmpget dispositivo clave OID</PRE>
+<P>En ``dispositivo'' colocas el nombre o dirección IP del equipo a
+monitorizar. En clave, colocas la ``cadena de caracteres de la
+comunidad de lectura'', como se le denomina en el mundillo SNMP.
+Muchos dispositivos aceptarán ``public'' como
+cadena por defecto, pero por razones de privacidad y seguridad esta
+clave puede estar deshabilitada. Consulta la documentación
+correspondiente al dispositivo o programa.</P>
+<P>Luego esta el tercer parámetro, llamado OID
+(Object IDentifier, identificador de objeto).</P>
+<P>Al principio, cuando empiezas a aprender sobre SNMP, parece muy
+confuso. No lo es tanto cuando le hechas una ojeada a los
+``MIB'' (Manager Information Base, o Base de
+Información Administrativa). Es un árbol invertido que describe los
+datos, empezando en un nodo raíz desde el que parten varias ramas.
+Cada rama termina en otro nodo y puede abrir nuevas sub-ramas. Cada
+rama tiene un nombre, y forman un camino que nos lleva hasta el fondo
+del árbol. En este ejemplo, las ramas que vamos a tomar se llaman iso,
+org, dod, internet, mgmt y mib-2. También pueden accederse por su
+número relativo; en este caso, estos números son 1, 3, 6, 1, 2 y 1:</P>
+<PRE>
+   iso.org.dod.internet.mgmt.mib-2 (1.3.6.1.2.1)</PRE>
+<P>En algunos programas se usa un punto al iniciar el OID. Esto puede
+ser confuso; no hay ningún punto inicial en la especificación de los
+OID... sin embargo, algunos programas usan por defecto un prefijo
+inicial. Para indicar la diferencia entre los OID abreviados (o sea, a
+los que se le pondrá el prefijo inicial) y los completos, estos
+programas necesitan que los OID completos empiecen por un punto. Para
+empeorar las cosas, se usan varios prefijos distintos...</P>
+<P>De acuerdo, sigamos con el inicio de nuestro OID: teníamos
+1.3.6.1.2.1 . Ahora, nos interesa la rama ``interfaces'', que tiene el
+número dos (o sea, 1.3.6.1.2.1.2, o 1.3.6.1.2.1.interfaces).</P>
+<P>Lo primero es hacernos con un programa SNMP. Busca algún 
+paquete pre-compilado para tu plataforma, si no, puedes
+buscar el código fuente y compilarlo tu mismo. En Internet encontrarás
+muchos programas, búscalos con un motor de búsqueda o como prefieras.
+Mi sugerencia es que busques el paquete CMU-SNMP, que esta bastante difundido.</P>
+<P>Asumamos que ya tienes el programa. Empecemos por tomar ciertos
+datos que están disponibles en la mayoría de los sistemas. Recuerda:
+hay un nombre abreviado para la parte del árbol que más nos interesa.</P>
+<P>Voy a usar la versión corta, ya que creo que este documento ya es
+lo bastante largo. Si no te funciona, añádele el prefijo .1.3.6.1.2.1
+y prueba de nuevo. O prueba leyendo el manual; sáltate las partes que
+no entiendas aún, y busca las secciones que hablan de como arrancar y
+usar el programa.</P>
+<PRE>
+   snmpget myrouter public system.sysdescr.0</PRE>
+<P>El dispositivo deberá contestarte con una descripción, probablemente
+vacía, de sí mismo. Si no consigues una respuesta válida, prueba con
+otra ``clave'' u otro dispositivo; no podemos seguir hasta tener un
+resultado.</P>
+<PRE>
+   snmpget myrouter public interfaces.ifnumber.0</PRE>
+<P>Con suerte, usando este comando obtendrás un número como resultado:
+el número de interfaces del dispositivo. Si es así, seguiremos
+adelante con otro programa, llamado ``snmpwalk''</P>
+<PRE>
+   snmpwalk myrouter public interfaces.iftable.ifentry.ifdescr</PRE>
+<P>Si obtienes una lista de interfaces, ya casi hemos llegado. Aquí
+tienes un ejemplo del resultado:</P>
+<PRE>
+   [user at host /home/alex]$ snmpwalk cisco public 2.2.1.2   
+   interfaces.ifTable.ifEntry.ifDescr.1 = &quot;BRI0: B-Channel 1&quot;
+   interfaces.ifTable.ifEntry.ifDescr.2 = &quot;BRI0: B-Channel 2&quot;
+   interfaces.ifTable.ifEntry.ifDescr.3 = &quot;BRI0&quot; Hex: 42 52 49 30
+   interfaces.ifTable.ifEntry.ifDescr.4 = &quot;Ethernet0&quot;
+   interfaces.ifTable.ifEntry.ifDescr.5 = &quot;Loopback0&quot;</PRE>
+<P>En este equipo CISCO, quiero monitorizar la interfaz ``Ethernet0''.
+Viendo que es la cuarta, pruebo con:</P>
+<PRE>
+   [user at host /home/alex]$ snmpget cisco public 2.2.1.10.4 2.2.1.16.4
+</PRE>
+<PRE>
+
+   interfaces.ifTable.ifEntry.ifInOctets.4 = 2290729126
+   interfaces.ifTable.ifEntry.ifOutOctets.4 = 1256486519</PRE>
+<P>Entonces, tengo 2 OIDs que monitorizar, y son (en el formato largo, ahora):</P>
+<PRE>
+   1.3.6.1.2.1.2.2.1.10
+</PRE>
+<PRE>
+
+        y</PRE>
+<PRE>
+
+   1.3.6.1.2.1.2.2.1.16</PRE>
+<P>, ambas con el número de interfaz de 4</P>
+<P>No te engañes, esto no lo logre yo al primer intento. Me tomó un
+tiempo entender lo que significaban todos estos números; ayuda cuando
+se traducen en un texto descriptivo... por lo menos, cuando oigas
+hablar de MIBs y OIDs, ahora sabrás de qué se trata. No te olvides
+del número de interfaz (0 si el valor no depende de una interfaz), y
+prueba con snmpwalk si no obtienes una respuesta clara con snmpget.</P>
+<P>Si entendiste todo esto, y obtienes resultados del dispositivo con
+el que estás probando, sigue adelante con el tutorial. Si no, vuelve a
+leer esta sección; es importante</P>
+<P>
+<H2><A NAME="un ejemplo real">Un ejemplo real</A></H2>
+<P>Ok, empecemos con la diversión. Primero, crea una base de datos
+nueva. Vamos a guardar en ella 2 contadores, ``input'' y ``ouput''. Los
+datos los vamos a guardar en archivos que los promediarán, tomando
+grupos de 1, 6, 24 o 288 muestras. También archivaremos los valores
+máximos. Lo explicaremos con más detalle después. El intervalo de
+tiempo entre las muestras será de 300 segundos (5 minutos).</P>
+<PRE>
+ 1 muestra &quot;promediada&quot; sigue siendo 1 muestra cada 5 minutos
+ 6 muestras promediadas son un promedio de cada 30 minutos
+ 24 muestras promediadas son un promedio de cada 2 horas
+ 288 muestras promediadas son un promedio de cada día</PRE>
+<P>Vamos a tratar de ser compatibles con MRTG, que guarda más o menos
+esta cantidad de datos:</P>
+<PRE>
+ 600 muestras de 5 minutos:          2 días y 2 horas
+ 600 promedios de 30 minutos:        12.5 días
+ 600 promedios de 2 horas:           50 días
+ 600 promedios de 1 día:             732 días</PRE>
+<P>Uniendo todos estos rangos tenemos que en total guardamos datos de
+unos 797 días. RRDtool guarda los datos de una forma distinta a MRTG;
+no empieza el archivo ``semanal'' donde acaba el ``diario'', sino que
+ambos archivos contienen la información más reciente, ¡por lo que con
+RRDtool archivamos más datos que con MRTG!</P>
+<P>Necesitaremos:</P>
+<PRE>
+ 600 muestras de 5 minutos    (2 días y 2 horas)
+ 700 entradas de 30 minutos   (2 días y 2 horas, más 12.5 días)
+ 775 entradas de 2 horas      (lo anterior + 50 días)
+ 797 entradas de 1 día        (lo anterior + 732 días, redondeando)</PRE>
+<PRE>
+   rrdtool create myrouter.rrd         \
+            DS:input:COUNTER:600:U:U   \
+            DS:output:COUNTER:600:U:U  \
+            RRA:AVERAGE:0.5:1:600      \
+            RRA:AVERAGE:0.5:6:700      \
+            RRA:AVERAGE:0.5:24:775     \
+            RRA:AVERAGE:0.5:288:797    \
+            RRA:MAX:0.5:1:600          \
+            RRA:MAX:0.5:6:700          \
+            RRA:MAX:0.5:24:775         \
+            RRA:MAX:0.5:288:797</PRE>
+<P>Lo siguiente es recoger los datos y guardarlos, como en el ejemplo
+siguiente. Esta parcialmente en pseudo-código, por lo que tendrás que
+buscar exactamente como hacerlo funcionar en tu sistema operativo.</P>
+<PRE>
+   mientras no sea el fin del universo
+   hacer
+      tomar el resultado de 
+          snmpget router community 2.2.1.10.4
+      en la variable $in
+      tomar el resultado de
+          snmpget router community 2.2.1.16.4
+      en la variable $out
+      rrdtool update myrouter.rrd N:$in:$out
+      esperar 5 minutos
+   hecho</PRE>
+<P>Luego, tras recoger datos por un día, crea una imagen, usando:</P>
+<PRE>
+   rrdtool graph myrouter-day.gif --start -86400 \
+            DEF:inoctets=myrouter.rrd:input:AVERAGE \
+            DEF:outoctets=myrouter.rrd:output:AVERAGE \
+            AREA:inoctets#00FF00:&quot;In traffic&quot; \
+            LINE1:outoctets#0000FF:&quot;Out traffic&quot;</PRE>
+<P>Este comando debe producir un gráfico del tráfico del día. Un día
+son 24 horas, de 60 minutos, de 60 segundos: 24*60*60=86400, o sea que
+empezamos a ``ahora'' menos 86400 segundos. Definimos (con los DEFs)
+``inoctets'' y ``outoctets'' como los valores promedio de la base da datos
+myrouter.rrd, dibujando un área para el tráfico de entrada y una línea
+para el tráfico de salida.</P>
+<P>Mira la imagen y sigue recogiendo datos por unos cuantos días. Si
+lo deseas, puedes probar con los ejemplos de la base de datos de
+pruebas y ver si puedes hacer trabajar las diversas opciones y
+operaciones.</P>
+<P>Sugerencia:</P>
+<P>Haz un gráfico que muestre el tráfico en bytes por segundo y en
+bits por segundo. Colorea el tráfico Ethernet rojo si sobrepasa los
+cuatro megabits por segundo.</P>
+<P>
+<H2><A NAME="funciones de consolidación">Funciones de consolidación</A></H2>
+<P>Unos cuantos párrafos atrás hablábamos sobre la posibilidad de
+guardar el valor máximo en vez del promedio. Profundicemos un poco en
+este tema.</P>
+<P>Recordemos lo que hablábamos sobre la velocidad de un coche.
+Supongamos que manejamos a 144 KM/H durante 5
+minutos y luego nos detiene la policía durante unos 25 minutos. Al
+finalizar el regaño, tomamos nuestro portátil y creamos una imagen
+desde nuestra base de datos. Si visualizamos la segunda RRA que
+creamos, tendremos el promedio de 6 muestreos. Las velocidades
+registradas serian 144+0+0+0+0+0=144, lo que en promedio nos da una
+velocidad de 24 KM/H., con lo que nos igual nos
+pondrían una multa, sólo que no por exceso de velocidad.</P>
+<P>Obviamente, en este caso, no deberíamos tomar en cuenta los
+promedios. Estos son útiles en varios casos. Por ejemplo, si queremos
+ver cuantos KM hemos viajado, este sería el
+gráfico más indicado. Pero por otro lado, para ver la velocidad ha la
+que hemos viajado, los valores máximos son más adecuados.</P>
+<P>Es lo mismo con los datos que recogemos. Si quieres saber la
+cantidad total, mira los promedios. Si quieres ver la velocidad, mira
+los máximos. Con el tiempo, ambas cantidades se separan cada vez más.
+En la última base de datos que creamos, había dos archivos que
+guardaban los datos de cada día. El archivo que guarda los promedios
+mostrará valores bajos, mientras que el de máximos mostrará valores más
+altos. Para mi coche, mostraría valores promedio de 96/24=4 KM/H
+(viajo unos 96 kilómetros por día), y máximos de 1220 KM/H (la
+velocidad máxima que alcanzo cada día)</P>
+<P>Como ves, una gran diferencia. No mires el segundo gráfico para
+estimar la distancia que recorro, ni al primero para estimar la
+velocidad a la que voy. Esto sólo funciona con muestras muy cercanas,
+pero no si sacas promedios.</P>
+<P>Algunas veces, hago un viaje largo. Si hago un recorrido por
+Europa, conduciendo por unas 12 horas, el primer gráfico subirá
+a unos 60 KM/H. El segundo mostrará unos 180 KM/H. Esto significa que
+recorrí unos 60 KM/H por 24 horas = 1440 KM. Muestra además que fui a
+una velocidad promedio mayor a la normal y a un máximo de 180 KM/H,
+¡no que fui 8 horas a una velocidad fija de 180 KM/H! Este es un
+ejemplo real: tengo que seguir la corriente en las autopistas de
+Alemania, detenerme por gasolina y café de vez en cuando, manejar más
+lentamente por Austria y Holanda, e ir con cuidado en las montañas y
+las villas. Si viéramos los gráficos de los promedios de cada 5
+minutos, la imagen sería completamente distinta; veríamos los mismos
+valores de promedio y de máxima. (suponiendo que las mediciones fueran
+cada 300 segundos). Se podría ver cuando paré, cuando iba en
+primera, cuando iba por las autopistas, etc. La granularidad de los
+datos es más alta, por lo que se tiene más información. Sin embargo,
+esto nos lleva unas 12 muestras por hora, o 288 al día, lo cual es
+mucho para guardar por un periodo de tiempo largo. Por lo tanto,
+sacamos el promedio, guardando eventualmente un solo valor por día.
+Con este único valor, no podemos ver mucho.</P>
+<P>Es importante comprender lo que expuesto en estos últimos párrafos.
+Unos ejes y unas líneas no tienen ningún valor por si mismos; hay que
+saber que representan e interpretar correctamente los valores
+obtenidos. Sean cuales sean los datos, esto siempre será cierto.</P>
+<P>El mayor error que puedes cometer es usar los datos recogidos para
+algo para lo cual no sirven. En ese caso, seria hasta mejor no tener
+gráfico alguno.</P>
+<P>
+<H2><A NAME="repasemos lo que sabemos">Repasemos lo que sabemos</A></H2>
+<P>Ahora ya sabes como crear una base de datos. Puedes guardar valores
+en ella, extraerlos creando un gráfico, hacer operaciones matemáticas
+con ellos desde la base de datos y visualizar los resultados de estas
+en vez de los datos originales. Vimos la diferencia entre los
+promedios y los máximos y cuando debemos usar cada uno (o al menos una
+idea de ello)</P>
+<P>RRDtool puede hacer más de lo que hemos visto hasta ahora. Pero
+antes de continuar, te recomiendo que releas el texto desde el
+principio y pruebes a hacerle algunas modificaciones a los ejemplos.
+Asegúrate de entenderlo todo. El esfuerzo valdrá la pena, y te ayudará,
+no sólo con el resto del documento, sino en tu trabajo diario de
+monitorización, mucho después de terminar con esta introducción.</P>
+<P>
+<H2><A NAME="tipos de fuentes de datos">Tipos de fuentes de datos</A></H2>
+<P>De acuerdo, quieres continuar. Bienvenido de vuelta otra vez y
+prepárate; voy a ir más rápido con los ejemplos y explicaciones.</P>
+<P>Ya vimos que, para ver el cambio de un contador a lo largo del
+tiempo, tenemos que tomar dos números y dividir la diferencia entre el
+tiempo transcurrido entre las mediciones. Para los ejemplos que hemos
+visto es lo lógico, pero hay otras posibilidades. Por ejemplo, mi
+enrutador me puede dar la temperatura actual en tres puntos distintos,
+la entrada de aire, el llamado ``punto caliente'' y la salida de
+ventilación. Estos valores no son contadores; si tomo los valores de
+dos muestreos y lo divido entre 300 segundos, obtendré el cambio de
+temperatura por segundo. ¡Esperemos que sea cero, o tendríamos un
+incendio en el cuarto de ordenadores! :)</P>
+<P>Entonces, ¿que hacemos? Podemos decirle a RRDtool que guarde los
+valores tal como los medimos (esto no es exactamente así, pero se
+aproxima bastante a la verdad). Así, los gráficos se verán mucho
+mejor. Puedo ver cuando el enrutador está trabajando más (en serio,
+funciona; como usa más electricidad, genera más calor y sube la
+temperatura), puedo saber cuando me he dejado las puertas abiertas (el
+cuarto de ordenadores tiene aire acondicionado; con las puertas
+abiertas el aire caliente del resto del edificion entra y sube la
+temperatura en la entrada de aire del enrutador), etc. Antes usamos un
+tipo de datos de ``contador'', ahora usaremos un tipo de datos
+diferente, con un nombre diferente, GAUGE.
+Tenemos otros tipos:</P>
+<PRE>
+ - COUNTER este ya lo conocemos
+ - GAUGE   este acabamos de verlo
+ - DERIVE
+ - ABSOLUTE</PRE>
+<P>Los otros dos tipos son DERIVE y ABSOLUTE. ABSOLUTE puede usarse
+igual que COUNTER, con una diferencia; RRDtool asume que el contador
+se reinicia cada vez que se lee. O en otras palabras; el delta entre
+los valores no hay que calcularlo, mientras que con COUNTER RRDtool
+tiene que sacar él la cuenta. Por ejemplo, nuestro primer ejemplo,
+(12345, 12357, 12363, 12363), sería (unknown, 12, 6, 0) en ABSOLUTE.
+El otro tipo, DERIVE, es como COUNTER, pero al contrario de COUNTER,
+este valor también puede decrecer, por lo que puede tenerse un delta
+negativo.</P>
+<P>Vamos a probarlos todos:</P>
+<PRE>
+   rrdtool create all.rrd --start 978300900 \
+            DS:a:COUNTER:600:U:U \
+            DS:b:GAUGE:600:U:U \
+            DS:c:DERIVE:600:U:U \
+            DS:d:ABSOLUTE:600:U:U \
+            RRA:AVERAGE:0.5:1:10
+   rrdtool update all.rrd \
+            978301200:300:1:600:300    \
+            978301500:600:3:1200:600   \
+            978301800:900:5:1800:900   \
+            978302100:1200:3:2400:1200 \
+            978302400:1500:1:2400:1500 \
+            978302700:1800:2:1800:1800 \
+            978303000:2100:4:0:2100    \
+            978303300:2400:6:600:2400  \
+            978303600:2700:4:600:2700  \
+            978303900:3000:2:1200:3000
+   rrdtool graph all1.gif -s 978300600 -e 978304200 -h 400 \
+            DEF:linea=all.rrd:a:AVERAGE LINE3:linea#FF0000:&quot;Line A&quot; \
+            DEF:lineb=all.rrd:b:AVERAGE LINE3:lineb#00FF00:&quot;Line B&quot; \
+            DEF:linec=all.rrd:c:AVERAGE LINE3:linec#0000FF:&quot;Line C&quot; \
+            DEF:lined=all.rrd:d:AVERAGE LINE3:lined#000000:&quot;Line D&quot;</PRE>
+<P>
+<H2><A NAME="rrdtool bajo el microscopio">RRDtool bajo el microscopio</A></H2>
+<UL>
+<LI>
+La línea A es un contador, por lo que
+debe incrementarse continuamente y RRDtool tiene que calcular las
+diferencias. Además RRDtool tiene que dividir la diferencia entre
+el tiempo transcurrido. Esto debería terminar con una línea recta
+en 1 (los deltas son 300, y los intervalos son de 300)
+<P></P>
+<LI>
+La línea B es de tipo GAUGE. Estos son
+los valores ``reales'', así que el gráfico debe mostrar lo mismo que
+los valores que introducimos: una especie de onda
+
+<P></P>
+<LI>
+La línea C es de tipo DERIVE. Es un
+contador, y puede decrecer. Va entre 2400 y 0, con 1800 en el medio.
+<P></P>
+<LI>
+La línea D es de tipo ABSOLUTE. Esto es,
+es un contador pero no hay que calcular las diferencias. Los
+números son iguales a la línea A, y espero
+que puedas ver la diferencia en los gráficos.
+<P></P></UL>
+<P>Esto equivale a los valores siguientes, empezando a las 23:10 y
+terminando a las 00:10 (las U significan desconocido).</P>
+<PRE>
+ - Línea  A:  u  u  1  1  1  1  1  1  1  1  1  u
+ - Línea  B:  u  1  3  5  3  1  2  4  6  4  2  u
+ - Línea  C:  u  u  2  2  2  0 -2 -6  2  0  2  u
+ - Línea  D:  u  1  2  3  4  5  6  7  8  9 10  u</PRE>
+<P>Si tu archivo GIF muestra todo esto, has
+entrado los datos correctamente, tu programa RRDtool está funcionando
+bien, el visor de gráficos no te engaña y hemos entrado en el 2000 sin
+problemas :) Puedes probar el mismo ejemplo cuatro veces, una por cada línea.</P>
+<P>Revisemos los datos otra vez:</P>
+<UL>
+<LI>
+Línea A: 300, 600, 900 , etc.
+La diferencia del contador es siempre 300, igual que el intervalo de
+tiempo transcurrido entre mediciones. Por lo tanto, el promedio
+siempre es 1. Pero, ¿por qué el primer punto tiene un valor de
+``desconocido''? ¿Acaso no era conocido el valor que pusimos en la
+base de datos? ¡Si! Pero no teníamos un valor inicial para
+calcular la diferencia. Sería un error asumir que el contador
+empezaba en 0, así que no conocemos el valor de la diferencia
+<P></P>
+<LI>
+Línea B: 
+No hay nada que calcular, los valores son los mismos que se
+introdujeron en la base de datos.
+<P></P>
+<LI>
+Línea C: 
+De nuevo, no conocemos el valor
+inicial antes de la primera medición, así que se aplica el mismo
+razonamiento que para la línea A. En este
+caso las diferencias no son constantes, así que la línea no es
+recta. Si hubiésemos puesto los mismos valores que en la línea
+A, el gráfico sería el mismo. Al contrario
+que COUNTER, el valor puede decrecer, y espero mostrarte más
+adelante el por que de la diferencia entre ambos tipos.
+<P></P>
+<LI>
+Línea D: En este caso, el dispositivo nos
+da las diferencias por sí mismo. Por lo tanto, conocemos la
+diferencia inicial, y podemos graficarla. Tenemos los mismos
+valores que en la línea A, pero su
+significado es distinto, por lo que el gráfico también lo es. En
+este caso, las diferencias se incrementan en 300 cada vez,
+mientras que el intervalo de tiempo permanece constante en 300
+segundos, por lo que la división nos da resultados cada vez mayores.
+<P></P></UL>
+<P>
+<H2><A NAME="reinicialización de los contadores">Reinicialización de los contadores</A></H2>
+<P>Todavía nos quedan algunas cosas por ver. Nos quedan algunas
+opciones importantes por cubrir, y aun no hemos hablado de la
+reinicialización de contadores. Empecemos por ahí: Estamos en nuestro
+coche, vemos el contador y muestra 999987. Andamos unos 20 KM, así que
+el contador debe subir a 1000007. Desafortunadamente, el contador
+sólo tiene 6 dígitos, así que en realidad nos muestra 000007. Si
+estuviéramos guardando los valores en un tipo DERIVE, esto
+significaría que el contador retrocedió unos 999980 KM. Por supuesto
+esto no es cierto, por lo que necesitamos alguna protección contra estos
+casos. Esta protección sólo la tenemos para el tipo COUNTER, el cual
+de todas formas era el que teníamos que haber usado para este tipo de
+contador. ¿Cómo funciona? Los valores tipo COUNTER no deben decrecer
+nunca, ¡por lo que RRDtool asume en ese caso que el contador se ha
+reinicializado! Si la diferencia es negativa, esto se compensa sumando
+el valor máximo del contador + 1. Para nuestro coche, tendríamos:</P>
+<PRE>
+ Delta = 7 - 999987 = -999980    (en vez de 1000007-999987=20)
+</PRE>
+<PRE>
+
+ Delta real= -999980 + 999999 + 1 = 20</PRE>
+<P>Al momento de escribir este documento, RRDtool maneja contadores de
+32 o 64 bits de tamaño. Estos contadores pueden manejar los siguientes
+valores:</P>
+<PRE>
+ - 32 bits: 0 ..           4294967295
+ - 64 bits: 0 .. 18446744073709551615</PRE>
+<P>Si estos valores te parecen raros, podemos verlos en formato hexadecimal:</P>
+<PRE>
+ - 32 bits: 0 ..         FFFFFFFF
+ - 64 bits: 0 .. FFFFFFFFFFFFFFFF</PRE>
+<P>RRDtool maneja ambos contadores de la misma manera. Si ocurre un
+desbordamiento y la diferencia es negativa, RRDtool le suma primero
+el máximo del contador ``menor'' (32 bits) + 1 a la diferencia. Si aún
+así la diferencia es negativa, entonces el contador reinicializado era
+mayor (64 bits), por lo que se le suma el valor máximo del contador
+``largo'' + 1 y se le resta el máximo del contador ``pequeño'' que sumamos
+erróneamente. Hay un problema con esto: supongamos que un contador
+largo se ha reinicializado al sumársele una diferencia muy grande;
+entonces es posible que al añadir el valor máximo del contador pequeño
+la diferencia nos dé positivo. En este caso poco probable, los valores
+resultantes no serian correctos. Para que ocurra esto, el incremento
+tiene que ser casi tan grande como el valor máximo del contador, por
+lo que de ocurrir es muy probable que halla varios problemas más en
+la configuración y no merezca la pena preocuparse sólo por este. Aún
+así, he incluido un ejemplo de este caso para que lo puedas juzgar por
+ti mismo.</P>
+<P>A continuación, unos ejemplos de reinicialización de los
+contadores. Prueba de hacer los cálculos por ti mismo, o acepta mis
+resultados si tu calculadora no puede con los números :)</P>
+<P>Números de corrección:</P>
+<PRE>
+ - 32 bits: (4294967295+1) =                                 4294967296
+ - 64 bits: (18446744073709551615+1)-correction1 = 18446744069414584320
+</PRE>
+<PRE>
+
+ Antes:          4294967200
+ Incremento:            100
+ Debería ser:    4294967300
+ Pero es:                 4
+ Diferencia:    -4294967196
+ Corrección #1: -4294967196 + 4294967296 = 100</PRE>
+<PRE>
+
+ Antes:          18446744073709551000
+ Incremento:                      800
+ Debería ser:    18446744073709551800
+ Pero es:                         184
+ Diferencia:    -18446744073709550816
+ Corrección #1: -18446744073709550816 +4294967296 = -18446744069414583520
+ Corrección #2: -18446744069414583520 +18446744069414584320 = 800</PRE>
+<PRE>
+
+ Antes:          18446744073709551615 ( valor máximo )
+ Incremento:     18446744069414584320 ( incremento absurdo, 
+ Debería ser:    36893488143124135935   mínimo para que 
+ Pero es:        18446744069414584319   funcione el ejemplo)       
+ Diferencia:              -4294967296
+ Corrección #1:  -4294967296 + 4294967296 = 0 (positivo,
+                                               por tanto no se hace 
+                                               la segunda corrección)</PRE>
+<PRE>
+
+ Antes:          18446744073709551615 ( valor máximo )
+ Incremento:     18446744069414584319 
+ Debería ser:    36893488143124135934
+ Pero es:        18446744069414584318
+ Diferencia:              -4294967297
+ Corrección #1:  -4294967297 +4294967296 = -1
+ Corrección #2:  -1 +18446744069414584320 = 18446744069414584319</PRE>
+<P>Como puede verse en los últimos ejemplos, necesitas unos valores
+bastante extraños para hacer que RRDtool falle (asumiendo que no tenga
+ningún error el programa, por supuesto), así que esto no debería
+ocurrir. Sin embargo, SNMP o cualquier otro
+método que uses de recogida de datos puede también reportar algún
+valor erróneo ocasionalmente. No podemos prevenir todos los errores,
+pero podemos tomar algunas medidas. El comando ``create'' de RRDtool
+tiene dos parámetros especialmente para esto, que definen los valores
+mínimo y máximo permitidos. Hasta ahora hemos usado ``U'',
+``desconocido''. Si le pasas valores para uno o ambos parámetros y
+RRDtool recibe un valor fuera de esos límites, los ignorará. Para un
+termómetro en grados Celsius, el mínimo absoluto es -273. Para mi
+enrutador, puedo asumir que ese mínimo es mucho mayor, digamos que 10.
+La temperatura máxima la pondría en unos 80 grados; más alto y
+el aparato no funcionaría. Para mi coche, nunca esperaría obtener
+valores negativos, y tampoco esperaría valores mayores a 230.
+Cualquier otra cosa sería un error. Pero recuerda, lo contrario no es
+cierto: si los valores pasan este examen no quiere decir que sean los
+correctos. Siempre examina bien el gráfico si los valores parecen
+extraños.</P>
+<P>
+<H2><A NAME="remuestreo de los datos">Remuestreo de los datos</A></H2>
+<P>Hay una funcionalidad importante de RRDtool que no hemos explicado
+todavía: es virtualmente imposible recoger los datos y pasarselos a
+RRDtool a intervalos exactos de tiempo. Por tanto, RRDtool interpola
+los datos a los intervalos exactos. Si no sabes que significa esto o
+como se hace, he aquí la ayuda que necesitas:</P>
+<P>Supongamos un contador se incremente exactamente en 1 cada segundo.
+Queremos medirlo cada 300 segundos, por lo que deberíamos tener
+valores separados exactamente en 300. Sin embargo, por varias
+circunstancias llegamos unos segundos tarde y el intervalo es 303. La
+diferencia será por tanto 303. Obviamente, RRDtool no debe colocar 303
+en la base de datos y dar así la impresión de que el contador se
+incrementó 303 en 300 segundos. Aquí es donde RRDtool interpola:
+alterá el valor 303 al valor que tendría 3 segundos antes y guarda 300
+en 300 segundos. Digamos que la próxima vez llegamos justo a tiempo;
+por tanto, el intervalo actual es 297 segundos, por lo que el contador
+debería ser 297. De nuevo, RRDtool altera el valor y guarda 300, como
+debe ser.</P>
+<PRE>
+         en RRD                     en realidad
+ tiempo+000:   0 delta=&quot;U&quot;    tiempo+000:   0 delta=&quot;U&quot; 
+ tiempo+300: 300 delta=300    tiempo+300: 300 delta=300
+ tiempo+600: 600 delta=300    tiempo+603: 603 delta=303
+ tiempo+900: 900 delta=300    tiempo+900: 900 delta=297</PRE>
+<P>Creemos dos bases de datos idénticas. He escogido el rango de
+tiempo entre 920805000 y 920805900.</P>
+<PRE>
+   rrdtool create seconds1.rrd   \
+      --start 920804700          \
+      DS:seconds:COUNTER:600:U:U \
+      RRA:AVERAGE:0.5:1:24</PRE>
+<PRE>
+   para Unix: cp seconds1.rrd seconds2.rrd
+   para DOS: copy seconds1.rrd seconds2.rrd
+   para VMS:  y yo que sé :)</PRE>
+<PRE>
+   rrdtool update seconds1.rrd \
+      920805000:000 920805300:300 920805600:600 920805900:900
+   rrdtool update seconds2.rrd \
+      920805000:000 920805300:300 920805603:603 920805900:900</PRE>
+<PRE>
+   rrdtool graph seconds1.gif                       \
+      --start 920804700 --end 920806200             \
+      --height 200                                  \
+      --upper-limit 1.05 --lower-limit 0.95 --rigid \
+      DEF:seconds=seconds1.rrd:seconds:AVERAGE      \
+      CDEF:unknown=seconds,UN                       \
+      LINE2:seconds#0000FF                          \
+      AREA:unknown#FF0000
+   rrdtool graph seconds2.gif                       \
+      --start 920804700 --end 920806200             \
+      --height 200                                  \
+      --upper-limit 1.05 --lower-limit 0.95 --rigid \
+      DEF:seconds=seconds2.rrd:seconds:AVERAGE      \
+      CDEF:unknown=seconds,UN                       \
+      LINE2:seconds#0000FF                          \
+      AREA:unknown#FF0000</PRE>
+<P>Los dos gráficos debe ser iguales.</P>
+<P>
+<HR>
+<H1><A NAME="resumen">RESUMEN</A></H1>
+<P>Es hora de concluir este documento. Ahora debes conocer lo básico
+como para trabajar con RRDtool y leer la documentación. Aún hay mucho
+más por descubrir acerca de RRDtool, y le encontrarás; más y más usos
+para la herramienta. Con los ejemplos y la herramienta puedes crear
+fácilmente muchos gráficos; también puedes usar las interfaces
+disponibles.</P>
+<P>
+<HR>
+<H1><A NAME="lista de correo">LISTA DE CORREO</A></H1>
+<P>Recuerda subscribirte a la lista de correo. Aunque no contestes los
+correos que aparecen en ella, te servirá de ayuda a ti y a los demás.
+Mucho de lo que se sobre MRTG (y por tanto sobre RRDtool), lo aprendí
+tan sólo con leer la lista, sin escribir. No hay por que preguntar las
+preguntas básicas, que ya tienen su respuesta en la FAQ (¡léela!). Con
+miles de usuarios a lo largo del mundo, siempre hay preguntas que tu
+puedes responder con lo aprendido en este y otros documentos.</P>
+<P>
+<HR>
+<H1><A NAME="ver tambiÉn">VER TAMBIÉN</A></H1>
+<P>Las páginas del manual de RRDtool</P>
+<P>
+<HR>
+<H1><A NAME="autor">AUTOR</A></H1>
+<P>Espero que hayas disfrutado con los ejemplos y las descripciones.
+Si es así, ayuda a otros refiriéndolos a este documento cuando te
+hagan preguntas básicas. No sólo obtendrán la respuesta, sino que
+aprenderán muchas otras cosas.</P>
+<P>Alex van den Bogaerdt &lt;<A HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt;</P>
+
+</BODY>
+
+</HTML>

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdtune.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdtune.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdtune.html	Sat Jul 13 21:26:16 2002
@@ -1,108 +1,90 @@
 <HTML>
 <HEAD>
 <TITLE>rrdtune</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
-	<LI><A HREF="#EXAMPLE">EXAMPLE</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
+	<LI><A HREF="#example">EXAMPLE</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-rrdtool tune - Modify some basic properties of a Round Robin Database
-
-<P>
+<H1><A NAME="name">NAME</A></H1>
+<P>rrdtool tune - Modify some basic properties of a Round Robin Database</P>
+<div align="right"><a href="rrdtune.pdf">PDF</a> version.</div><P>
 <HR>
-<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
-<P>
-<STRONG>rrdtool</STRONG>  <STRONG>tune</STRONG>  <EM>filename</EM> 
- 
+<H1><A NAME="synopsis">SYNOPSIS</A></H1>
+<P><STRONG>rrdtool</STRONG> <STRONG>tune</STRONG> <EM>filename</EM> 
 [<STRONG>--heartbeat</STRONG>|<STRONG>-h</STRONG>&nbsp;<EM>ds-name</EM>:<EM>heartbeat</EM>] 
- 
 [<STRONG>--minimum</STRONG>|<STRONG>-i</STRONG>&nbsp;<EM>ds-name</EM>:<EM>min</EM>]
-
 [<STRONG>--maximum</STRONG>|<STRONG>-a</STRONG>&nbsp;<EM>ds-name</EM>:<EM>max</EM>]
-
 [<STRONG>--data-source-type</STRONG>|<STRONG>-d</STRONG>&nbsp;<EM>ds-name</EM>:<EM>DST</EM>]
-
-[<STRONG>--data-source-rename</STRONG>|<STRONG>-r</STRONG>&nbsp;<EM>old-name</EM>:<EM>new-name</EM>]
-
-
-
+[<STRONG>--data-source-rename</STRONG>|<STRONG>-r</STRONG>&nbsp;<EM>old-name</EM>:<EM>new-name</EM>]</P>
 <P>
 <HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-The tune option allows you to alter some of the basic configuration values
-stored in the header area of a Round Robin Database (<STRONG>RRD</STRONG>). All these tunable parameters together decide when data fed into an 
-<STRONG>RRD</STRONG> is to be regarded as invalid. Invalid data is entered into the database as
-*UNKNOWN*.
-
-<P>
-The main application of the <STRONG>tune</STRONG> function is to relax the validation rules on an <STRONG>RRD</STRONG>. This allows to fill a new <STRONG>RRD</STRONG> with data available in larger intervals than what you would normally want
-to permit.
-
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>The tune option allows you to alter some of the basic configuration
+values stored in the header area of a Round Robin Database (<STRONG>RRD</STRONG>).
+All these tunable parameters together decide when data fed into an 
+<STRONG>RRD</STRONG> is to be regarded as invalid. Invalid data is entered into the 
+database as *UNKNOWN*.</P>
+<P>The main application of the <STRONG>tune</STRONG> function is to relax the 
+validation rules on an <STRONG>RRD</STRONG>. This allows to fill a new <STRONG>RRD</STRONG> with
+data available in larger intervals than what you would normally want
+to permit.</P>
 <DL>
-<DT><STRONG><A NAME="item_filename">filename</A></STRONG><DD>
-<P>
+<DT><STRONG><A NAME="item_filename"><EM>filename</EM></A></STRONG><BR>
+<DD>
 The name of the <STRONG>RRD</STRONG> you want to tune.
-
-<DT><STRONG><A NAME="item__heartbeat_h">--heartbeat|-h ds-name:heartbeat</A></STRONG><DD>
-<P>
-modify the <EM>heartbeat</EM> of a data source. By setting this to a high value the rrd will accept
-things like one value per day ...
-
-<DT><STRONG><A NAME="item__minimum_i">--minimum|-i ds-name:min</A></STRONG><DD>
-<P>
-alter the minimum value acceptable as input from the data source. Setting <EM>min</EM> to 'U' will disable this limit.
-
-<DT><STRONG><A NAME="item__maximum_a">--maximum|-a ds-name:max</A></STRONG><DD>
-<P>
-alter the maximum value acceptable as input from the data source. Setting <EM>max</EM> to 'U' will disable this limit.
-
-<DT><STRONG><A NAME="item__data_source_type_d">--data-source-type|-d ds-name:DST</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_%2D%2Dheartbeat%7C%2Dh_ds%2Dname%3Aheartbeat"><STRONG>--heartbeat</STRONG>|<STRONG>-h</STRONG>&nbsp;<EM>ds-name</EM>:<EM>heartbeat</EM></A></STRONG><BR>
+<DD>
+modify the <EM>heartbeat</EM> of a data source. By setting this to a high
+value the rrd will accept things like one value per day ...
+<P></P>
+<DT><STRONG><A NAME="item_%2D%2Dminimum%7C%2Di_ds%2Dname%3Amin"><STRONG>--minimum</STRONG>|<STRONG>-i</STRONG>&nbsp;<EM>ds-name</EM>:<EM>min</EM></A></STRONG><BR>
+<DD>
+alter the minimum value acceptable as input from the data source.
+Setting <EM>min</EM> to 'U' will disable this limit.
+<P></P>
+<DT><STRONG><A NAME="item_%2D%2Dmaximum%7C%2Da_ds%2Dname%3Amax"><STRONG>--maximum</STRONG>|<STRONG>-a</STRONG>&nbsp;<EM>ds-name</EM>:<EM>max</EM></A></STRONG><BR>
+<DD>
+alter the maximum value acceptable as input from the data source.
+Setting <EM>max</EM> to 'U' will disable this limit.
+<P></P>
+<DT><STRONG><A NAME="item_%2D%2Ddata%2Dsource%2Dtype%7C%2Dd_ds%2Dname%3ADST"><STRONG>--data-source-type</STRONG>|<STRONG>-d</STRONG>&nbsp;<EM>ds-name</EM>:<EM>DST</EM></A></STRONG><BR>
+<DD>
 alter the type <STRONG>DST</STRONG> of a data source.
-
-<DT><STRONG><A NAME="item__data_source_rename_r">[--data-source-rename|-r old-name:new-name]</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_%5B%2D%2Ddata%2Dsource%2Drename%7C%2Dr_old%2Dname%">[<STRONG>--data-source-rename</STRONG>|<STRONG>-r</STRONG>&nbsp;<EM>old-name</EM>:<EM>new-name</EM>]</A></STRONG><BR>
+<DD>
 rename a data source
-
-</DL>
+<P></P></DL>
 <P>
 <HR>
-<H1><A NAME="EXAMPLE">EXAMPLE</A></H1>
-<P>
-<CODE>rrdtool tune data.rrd -h in:100000 -h in:100000 -h in:100000</CODE>
-
-
-
-<P>
-Set the minimum required heartbeat for data sources 'in', 'out' and
-'through' to 10000 seconds which is a little over one day in data.rrd. This
-would allow to feed old data from mrtg-2.0 right into rrdtool without
-generating *UNKNOWN* entries.
-
+<H1><A NAME="example">EXAMPLE</A></H1>
+<P><CODE>rrdtool tune data.rrd -h in:100000 -h out:100000 -h through:100000</CODE></P>
+<P>Set the minimum required heartbeat for data sources 'in', 'out' 
+and 'through' to 10000 seconds which is a little over one day in data.rrd.
+This would allow to feed old data from mrtg-2.0 right into
+rrdtool without generating *UNKNOWN* entries.</P>
 <P>
 <HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-Tobias Oetiker &lt;<A
-HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;</P>
 
 </BODY>
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdresize.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdresize.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdresize.txt	Sat Jul 13 21:26:17 2002
@@ -9,7 +9,7 @@
      rrdtool resize - alters the size of an RRA.
 
 SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
-     rrrrrrrrddddttttoooooooollll rrrreeeessssiiiizzzzeeee _f_i_l_e_n_a_m_e _r_r_a-_n_u_m  GGGGRRRROOOOWWWW|SSSSHHHHRRRRIIIINNNNKKKK _r_o_w_s
+     rrrrrrrrddddttttoooooooollll rrrreeeessssiiiizzzzeeee _f_i_l_e_n_a_m_e _r_r_a_-_n_u_m  GGGGRRRROOOOWWWW_|SSSSHHHHRRRRIIIINNNNKKKK _r_o_w_s
 
 DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
      The rrrreeeessssiiiizzzzeeee function is used to modify the number of rows in
@@ -18,8 +18,8 @@
      _f_i_l_e_n_a_m_e
              the name of the RRRRRRRRDDDD you want to alter.
 
-     _r_r_a-_n_u_m the RRRRRRRRAAAA you want to alter. You can find the number
-             using rrrrrrrrddddttttoooooooollll dddduuuummmmpppp.
+     _r_r_a_-_n_u_m the RRRRRRRRAAAA you want to alter. You can find the number
+             using rrrrrrrrddddttttoooooooollll iiiinnnnffffoooo.
 
      GGGGRRRROOOOWWWW    used if you want to add extra rows to an RRA. The
              extra rows will be inserted as the rows that are
@@ -60,7 +60,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      1
+2001-02-20             Last change: 1.0.33                      1
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdcreate.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdcreate.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdcreate.txt	Sat Jul 13 21:26:17 2002
@@ -9,21 +9,21 @@
      rrdtool create - Set up a new Round Robin Database
 
 SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
-     rrrrrrrrddddttttoooooooollll ccccrrrreeeeaaaatttteeee _f_i_l_e_n_a_m_e [--------ssssttttaaaarrrrtttt|----bbbb _s_t_a_r_t _t_i_m_e] [--------
-     sssstttteeeepppp|----ssss _s_t_e_p] [DDDDSSSS::::_d_s-_n_a_m_e::::_D_S_T::::_h_e_a_r_t_b_e_a_t::::_m_i_n::::_m_a_x]
+     rrrrrrrrddddttttoooooooollll ccccrrrreeeeaaaatttteeee _f_i_l_e_n_a_m_e [--------ssssttttaaaarrrrtttt|----bbbb _s_t_a_r_t _t_i_m_e]
+     [--------sssstttteeeepppp|----ssss _s_t_e_p] [DDDDSSSS::::_d_s_-_n_a_m_e::::_D_S_T::::_h_e_a_r_t_b_e_a_t::::_m_i_n::::_m_a_x]
      [RRRRRRRRAAAA::::_C_F::::_x_f_f::::_s_t_e_p_s::::_r_o_w_s]
 
 DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
      The create function of the RRDtool lets you set up new Round
-     Robin Database (RRRRRRRRDDDD) files. The file is created at its
-     final, full size and filled with *_U_N_K_N_O_W_N* data.
+     Robin Database (RRRRRRRRDDDD) files.  The file is created at its
+     final, full size and filled with _*_U_N_K_N_O_W_N_* data.
 
      _f_i_l_e_n_a_m_e
              The name of the RRRRRRRRDDDD you want to create. RRRRRRRRDDDD files
-             should end with the extension ._r_r_d. However, rrrrrrrrddddttttoooooooollll
+             should end with the extension _._r_r_d. However, rrrrrrrrddddttttoooooooollll
              will accept any filename.
 
-     --------ssssttttaaaarrrrtttt|-bbbb _s_t_a_r_t _t_i_m_e (default: now - 10s)
+     --------ssssttttaaaarrrrtttt|----bbbb _s_t_a_r_t _t_i_m_e (default: now - 10s)
              Specifies the time in seconds since 1970-01-01 UTC
              when the first value should be added to the RRRRRRRRDDDD.
              rrrrrrrrddddttttoooooooollll will not accept any data timed before or at
@@ -33,11 +33,11 @@
              _r_r_d_f_e_t_c_h documentation for more ways to specify
              time.
 
-     --------sssstttteeeepppp|-ssss _s_t_e_p (default: 300 seconds)
+     --------sssstttteeeepppp|----ssss _s_t_e_p (default: 300 seconds)
              Specifies the base interval in seconds with which
              data will be fed into the RRRRRRRRDDDD.
 
-     DDDDSSSS::::_d_s-_n_a_m_e::::_D_S_T::::_h_e_a_r_t_b_e_a_t::::_m_i_n::::_m_a_x
+     DDDDSSSS::::_d_s_-_n_a_m_e::::_D_S_T::::_h_e_a_r_t_b_e_a_t::::_m_i_n::::_m_a_x
              A single RRRRRRRRDDDD can accept input from several data
              sources (DDDDSSSS).  (e.g. Incoming and Outgoing traffic
              on a specific communication line). With the DDDDSSSS
@@ -45,22 +45,22 @@
              properties of each data source you want to use to
              feed the RRRRRRRRDDDD.
 
-             _d_s-_n_a_m_e is the name you will use to reference this
-             particular data source from an RRRRRRRRDDDD. A _d_s-_n_a_m_e must
-             be 1 to 19 characters long in the characters [a-
-             zA-Z0-9_].
+             _d_s_-_n_a_m_e is the name you will use to reference this
+             particular data source from an RRRRRRRRDDDD. A _d_s_-_n_a_m_e must
+             be 1 to 19 characters long in the characters [a-zA-
+             Z0-9_].
+
+             _D_S_T defines the Data Source Type. See the section on
+             "How to Measure" below for further insight.  The
+             Datasource Type must be onw of the following:
 
-             _D_S_T defines the Data Source Type. It can be one of
-             the following:
-
-     GGGGAAAAUUUUGGGGEEEE       is for things like temperatures or number of
+             GGGGAAAAUUUUGGGGEEEE
+                 is for things like temperatures or number of
                  people in a room or value of a RedHat share.
 
 
 
-
-
-12/Feb/2000            Last change: 1.0.13                      1
+2001-02-20             Last change: 1.0.33                      1
 
 
 
@@ -71,7 +71,8 @@
 
 
 
-     CCCCOOOOUUUUNNNNTTTTEEEERRRR     is for continuous incrementing counters like the
+             CCCCOOOOUUUUNNNNTTTTEEEERRRR
+                 is for continuous incrementing counters like the
                  InOctets counter in a router. The CCCCOOOOUUUUNNNNTTTTEEEERRRR data
                  source assumes that the counter never decreases,
                  except when a counter overflows.  The update
@@ -82,8 +83,9 @@
                  and acts accordingly by adding an appropriate
                  value to the result.
 
-     DDDDEEEERRRRIIIIVVVVEEEE      will store the the derivative of the line going
-                 from the last to the current value of the data
+             DDDDEEEERRRRIIIIVVVVEEEE
+                 will store the derivative of the line going from
+                 the last to the current value of the data
                  source. This can be useful for gauges, for
                  example, to measure the rate of people entering
                  or leaving a room. Internally, derive works
@@ -92,41 +94,39 @@
                  or 64 bit you might want to use DERIVE and
                  combine it with a MIN value of 0.
 
-     AAAABBBBSSSSOOOOLLLLUUUUTTTTEEEE    is for counters which get reset upon reading.
+             AAAABBBBSSSSOOOOLLLLUUUUTTTTEEEE
+                 is for counters which get reset upon reading.
                  This is used for fast counters which tend to
                  overflow. So instead of reading them normally
                  you reset them after every read to make sure you
                  have a maximal time available before the next
-                 overflow.
+                 overflow. Another usage is for things you count
+                 like number of messages since the last update.
 
-                 _h_e_a_r_t_b_e_a_t defines the maximum number of seconds
-                 that may pass between two updates of this data
-                 source before the value of the data source is
-                 assumed to be *_U_N_K_N_O_W_N*.
-
-                 _m_i_n and _m_a_x are optional entries defining the
-                 expected range of the data supplied by this data
-                 source. If _m_i_n and/or _m_a_x are defined, any value
-                 outside the defined range will be regarded as
-                 *_U_N_K_N_O_W_N*. If you do not know or care about min
-                 and max, set them to U for unknown. Note that
-                 min and max always refer to the processed values
-                 of the DS. For a traffic-CCCCOOOOUUUUNNNNTTTTEEEERRRR type DS this
-                 would be the max and min data-rate expected from
-                 the device.
-
-                 _I_f _i_n_f_o_r_m_a_t_i_o_n _o_n _m_i_n_i_m_a_l/_m_a_x_i_m_a_l _e_x_p_e_c_t_e_d
-                 _v_a_l_u_e_s _i_s _a_v_a_i_l_a_b_l_e, _a_l_w_a_y_s _s_e_t _t_h_e _m_i_n _a_n_d/_o_r
-                 _m_a_x _p_r_o_p_e_r_t_i_e_s. _T_h_i_s _w_i_l_l _h_e_l_p _R_R_D_t_o_o_l _i_n _d_o_i_n_g
-                 _a _s_i_m_p_l_e _s_a_n_i_t_y _c_h_e_c_k _o_n _t_h_e _d_a_t_a _s_u_p_p_l_i_e_d _w_h_e_n
-                 _r_u_n_n_i_n_g _u_p_d_a_t_e.
+             _h_e_a_r_t_b_e_a_t defines the maximum number of seconds that
+             may pass between two updates of this data source
+             before the value of the data source is assumed to be
+             _*_U_N_K_N_O_W_N_*.
 
-     RRRRRRRRAAAA::::_C_F::::_x_f_f::::_s_t_e_p_s::::_r_o_w_s
-             The purpose of an RRRRRRRRDDDD is to store data in the round
+             _m_i_n and _m_a_x are optional entries defining the
+             expected range of the data supplied by this data
+             source. If _m_i_n and/or _m_a_x are defined, any value
+             outside the defined range will be regarded as
+             _*_U_N_K_N_O_W_N_*. If you do not know or care about min and
+             max, set them to U for unknown. Note that min and
+             max always refer to the processed values of the DS.
+             For a traffic-CCCCOOOOUUUUNNNNTTTTEEEERRRR type DS this would be the max
+             and min data-rate expected from the device.
+
+             _I_f _i_n_f_o_r_m_a_t_i_o_n _o_n _m_i_n_i_m_a_l_/_m_a_x_i_m_a_l _e_x_p_e_c_t_e_d _v_a_l_u_e_s _i_s
+             _a_v_a_i_l_a_b_l_e_, _a_l_w_a_y_s _s_e_t _t_h_e _m_i_n _a_n_d_/_o_r _m_a_x _p_r_o_p_e_r_t_i_e_s_.
+             _T_h_i_s _w_i_l_l _h_e_l_p _R_R_D_t_o_o_l _i_n _d_o_i_n_g _a _s_i_m_p_l_e _s_a_n_i_t_y
+             _c_h_e_c_k _o_n _t_h_e _d_a_t_a _s_u_p_p_l_i_e_d _w_h_e_n _r_u_n_n_i_n_g _u_p_d_a_t_e_.
 
 
 
-12/Feb/2000            Last change: 1.0.13                      2
+
+2001-02-20             Last change: 1.0.33                      2
 
 
 
@@ -137,6 +137,8 @@
 
 
 
+     RRRRRRRRAAAA::::_C_F::::_x_f_f::::_s_t_e_p_s::::_r_o_w_s
+             The purpose of an RRRRRRRRDDDD is to store data in the round
              robin archives (RRRRRRRRAAAA). An archive consists of a
              number of data values from all the defined data-
              sources (DDDDSSSS) and is defined with an RRRRRRRRAAAA line.
@@ -147,11 +149,11 @@
 
              The data is also consolidated with the consolidation
              function (_C_F) of the archive. The following
-             consolidation functions are defined:  AAAAVVVVEEEERRRRAAAAGGGGEEEE, MMMMIIIINNNN,
+             consolidation functions are defined: AAAAVVVVEEEERRRRAAAAGGGGEEEE, MMMMIIIINNNN,
              MMMMAAAAXXXX, LLLLAAAASSSSTTTT.
 
              _x_f_f The xfiles factor defines what part of a
-             consolidation interval may be made up from *_U_N_K_N_O_W_N*
+             consolidation interval may be made up from _*_U_N_K_N_O_W_N_*
              data while the consolidated value is still regarded
              as known.
 
@@ -162,37 +164,35 @@
              _r_o_w_s defines how many generations of data values are
              kept in an RRRRRRRRAAAA.
 
-EEEEXXXXAAAAMMMMPPPPLLLLEEEE
-     rrdtool create temperature.rrd --step 300
-     DS:temp:GAUGE:600:-273:5000 RRA:AVERAGE:0.5:1:1200
-     RRA:MIN:0.5:12:2400 RRA:MAX:0.5:12:2400
-     RRA:AVERAGE:0.5:12:2400
-
-     This sets up an RRRRRRRRDDDD called _t_e_m_p_e_r_a_t_u_r_e._r_r_d which accepts one
-     temperature value every 300 seconds. If no new data is
-     supplied for more than 600 seconds, the temperature becomes
-     *_U_N_K_N_O_W_N*.  The minimum acceptable value is -273 and the
-     maximum is 5000.
-
-     A few archives areas are also defined. The first stores the
-     temperatures supplied for 100 hours (1200 * 300 seconds =
-     100 hours). The second RRA stores the minimum temperature
-     recorded over every hour (12 * 300 seconds = 1 hour), for
-     100 days (2400 hours). The third and the fourth RRA's do the
-     same with the for the maximum and average temperature,
-     respectively.
-
-AAAAUUUUTTTTHHHHOOOORRRR
-     Tobias Oetiker <oetiker at ee.ethz.ch>
-
-
-
-
+TTTThhhheeee HHHHEEEEAAAARRRRTTTTBBBBEEEEAAAATTTT aaaannnndddd tttthhhheeee SSSSTTTTEEEEPPPP
+     Here is an explanation by Don Baarda on the inner workings
+     of rrdtool.  It may help you to sort out why all this
+     *UNKNOWN* data is popping up in your databases:
+
+     RRD gets fed samples at arbitrary times. From these it
+     builds Primary Data Points (PDPs) at exact times every
+     "step" interval. The PDPs are then accumulated into RRAs.
+
+     The "heartbeat" defines the maximum acceptable interval
+     between samples. If the interval between samples is less
+     than "heartbeat", then an average rate is calculated and
+     applied for that interval. If the interval between samples
+     is longer than "heartbeat", then that entire interval is
+     considered "unknown". Note that there are other things that
+     can make a sample interval "unknown", such as the rate
+     exceeding limits, or even an "unknown" input sample.
+
+     The known rates during a PDP's "step" interval are used to
+     calculate an average rate for that PDP. Also, if the total
+     "unknown" time during the "step" interval exceeds the
+     "heartbeat", the entire PDP is marked as "unknown". This
+     means that a mixture of known and "unknown" sample time in a
+     single PDP "step" may or may not add up to enough "unknown"
+     time to exceed "heartbeat" and hence mark the whole PDP
 
 
 
-
-12/Feb/2000            Last change: 1.0.13                      3
+2001-02-20             Last change: 1.0.33                      3
 
 
 
@@ -203,22 +203,101 @@
 
 
 
+     "unknown". So "heartbeat" is not only the maximum acceptable
+     interval between samples, but also the maximum acceptable
+     amount of "unknown" time per PDP (obviously this is only
+     significant if you have "heartbeat" less than "step").
+
+     The "heartbeat" can be short (unusual) or long (typical)
+     relative to the "step" interval between PDPs. A short
+     "heartbeat" means you require multiple samples per PDP, and
+     if you don't get them mark the PDP unknown. A long heartbeat
+     can span multiple "steps", which means it is acceptable to
+     have multiple PDPs calculated from a single sample. An
+     extreme example of this might be a "step" of 5mins and a
+     "heartbeat" of one day, in which case a single sample every
+     day will result in all the PDPs for that entire day period
+     being set to the same average rate. _-_- _D_o_n _B_a_a_r_d_a
+     _<_d_o_n_._b_a_a_r_d_a_@_b_a_e_s_y_s_t_e_m_s_._c_o_m_>
+
+HHHHOOOOWWWW TTTTOOOO MMMMEEEEAAAASSSSUUUURRRREEEE
+     Here are a few hints on how to measure:
+
+     Temperature
+         Normally you have some type of meter you can read to get
+         the temperature.  The temperature is not realy connected
+         with a time. The only connection is that the temperature
+         reading happened at a certain time. You can use the
+         GGGGAAAAUUUUGGGGEEEE data source type for this. RRRtool will the record
+         your reading together with the time.
+
+     Mail Messages
+         Assume you have a methode to count the number of
+         messages transported by your mailserver in a certain
+         amount of time, this give you data like '5 messages in
+         the last 65 seconds'. If you look at the count of 5 like
+         and AAAABBBBSSSSOOOOLLLLUUUUTTTTEEEE datatype you can simply update the rrd with
+         the number 5 and the end time of your monitoring period.
+         RRDtool will then record the number of messages per
+         second. If at some later stage you want to know the
+         number of messages transported in a day, you can get the
+         average messages per second from RRDtool for the day in
+         question and multiply this number with the number of
+         seconds in a day. Because all math is run with Doubles,
+         the precision should be acceptable.
+
+     It's always a Rate
+         RRDtool stores rates in amount/second for COUNTER,
+         DERIVE and ABSOLUTE data.  When you plot the data, you
+         will get on the y axis amount/second which you might be
+         tempted to convert to absolute amount volume by
+         multiplying by the delta-time between the points.
+         RRDtool plots continuous data, and as such is not
+         appropriate for plotting absolute volumes as for example
+         "total bytes" sent and received in a router. What you
 
 
 
+2001-02-20             Last change: 1.0.33                      4
 
 
 
 
 
 
+rrdtool                                              RRDCREATE(1)
 
 
 
+         probably want is plot rates that you can scale to for
+         example bytes/hour or plot volumes with another tool
+         that draws bar-plots, where the delta-time is clear on
+         the plot for each point (such that when you read the
+         graph you see for example GB on the y axis, days on the
+         x axis and one bar for each day).
 
+EEEEXXXXAAAAMMMMPPPPLLLLEEEE
+     `rrdtool create temperature.rrd --step 300
+     DS:temp:GAUGE:600:-273:5000 RRA:AVERAGE:0.5:1:1200
+     RRA:MIN:0.5:12:2400 RRA:MAX:0.5:12:2400
+     RRA:AVERAGE:0.5:12:2400'
 
+     This sets up an RRRRRRRRDDDD called _t_e_m_p_e_r_a_t_u_r_e_._r_r_d which accepts one
+     temperature value every 300 seconds. If no new data is
+     supplied for more than 600 seconds, the temperature becomes
+     _*_U_N_K_N_O_W_N_*.  The minimum acceptable value is -273 and the
+     maximum is 5000.
 
+     A few archives areas are also defined. The first stores the
+     temperatures supplied for 100 hours (1200 * 300 seconds =
+     100 hours). The second RRA stores the minimum temperature
+     recorded over every hour (12 * 300 seconds = 1 hour), for
+     100 days (2400 hours). The third and the fourth RRA's do the
+     same with the for the maximum and average temperature,
+     respectively.
 
+AAAAUUUUTTTTHHHHOOOORRRR
+     Tobias Oetiker <oetiker at ee.ethz.ch>
 
 
 
@@ -245,20 +324,7 @@
 
 
 
-
-
-
-
-
-
-
-
-
-
-12/Feb/2000            Last change: 1.0.13                      4
-
-
-
+2001-02-20             Last change: 1.0.33                      5
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdresize.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdresize.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdresize.pod	Sat Jul 13 21:26:17 2002
@@ -2,6 +2,8 @@
 
 rrdtool resize - alters the size of an RRA.
 
+=for html <div align="right"><a href="rrdresize.pdf">PDF</a> version.</div>
+
 =head1 SYNOPSIS
 
 B<rrdtool> B<resize> I<filename> I<rra-num>  B<GROW>I<|>B<SHRINK> I<rows>
@@ -19,7 +21,7 @@
 
 =item I<rra-num> 
 
-the B<RRA> you want to alter. You can find the number using B<rrdtool dump>.
+the B<RRA> you want to alter. You can find the number using B<rrdtool info>.
 
 =item B<GROW> 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/bin_dec_hex.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/bin_dec_hex.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/bin_dec_hex.html	Sat Jul 13 21:26:17 2002
@@ -1,43 +1,38 @@
 <HTML>
 <HEAD>
 <TITLE>bin_dec_hex</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-Binary Decimal Hexadecimal - How does it work
-
-<P>
+<H1><A NAME="name">NAME</A></H1>
+<P>Binary Decimal Hexadecimal - How does it work</P>
+<div align="right"><a href="bin_dec_hex.pdf">PDF</a> version.</div><P>
 <HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-Most people use the decimal numbering system. This system uses ten symbols
-to represent numbers. When those ten symbols are used up, they start all
-over again and increment the position just before this. The digit 0 is only
-shown if it is the only symbol in the sequence, or if it is not the first
-one.
-
-<P>
-If this sounds as crypto to you, this is what I've said in numbers:
-
-<P>
-<PRE>     0
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>Most people use the decimal numbering system. This system uses ten
+symbols to represent numbers. When those ten symbols are used up, they
+start all over again and increment the position just before this. The
+digit 0 is only shown if it is the only symbol in the sequence, or if
+it is not the first one.</P>
+<P>If this sounds as crypto to you, this is what I've said in numbers:</P>
+<PRE>
+     0
      1
      2
      3
@@ -50,28 +45,20 @@
     10
     11
     12
-    13
-</PRE>
-<P>
-and so on.
-
-<P>
-Each time the digit nine should be incremented, it is reset to 0 and the
+    13</PRE>
+<P>and so on.</P>
+<P>Each time the digit nine should be incremented, it is reset to 0 and the
 position before is incremented. Then number 9 can be seen as ``00009'' and
 when we should increment 9, we reset it to zero and increment the digit
-just before the 9 so the number becomes ``00010''. For zero's we write a
+just before the 9 so the number becomes ``00010''. For zero's we write a 
 space if it is not the only digit (so: number 0) and if it is the first
-digit: ``00010'' -&gt; `` 0010'' -&gt; `` 010'' -&gt; `` 10''. It is not ``
-1 ''.
-
-<P>
-This was pretty basic, you already knew this. Why did I tell it ? Well,
-computers do not represent numbers with 10 different digits. They know of
-only two different symbols, being 0 and 1. Apply the same rules to this set
-of digits and you get the binary numbering system:
-
-<P>
-<PRE>     0
+digit: ``00010'' -&gt; `` 0010'' -&gt; ``  010'' -&gt; ``   10''. It is not ``   1 ''.</P>
+<P>This was pretty basic, you already knew this. Why did I tell it ?
+Well, computers do not represent numbers with 10 different digits. They
+know of only two different symbols, being 0 and 1. Apply the same rules
+to this set of digits and you get the binary numbering system:</P>
+<PRE>
+     0
      1
     10
     11
@@ -84,63 +71,47 @@
   1010
   1011
   1100
-  1101
-</PRE>
-<P>
-and so on.
-
-<P>
-If you count the number of rows, you'll see that these are again 14
-different numbers. The numbers are the same and mean the same. It is only a
-different representation. This means that you have to know the
+  1101</PRE>
+<P>and so on.</P>
+<P>If you count the number of rows, you'll see that these are again 14
+different numbers. The numbers are the same and mean the same. It is
+only a different representation. This means that you have to know the
 representation used, or as it is called the numbering system or base.
-Normally if we do not speak about the numbering system used, we're using
-the decimal system. If we are talking about another numbering system, we'll
-have to make that clear. There are a few wide-spread methods to do so. One
-common form is to write <CODE>1010(2)</CODE> which means that you wrote
-down a number in the binary form. It is the number ten. If you would write
-1010 it means the number one thousand and ten.
-
-<P>
-In books, another form is most used. It uses subscript (little chars, more
-or less in between two rows). You can leave out the parentheses in that
-case and write down the number in normal characters followed with a little
-two just behind it.
-
-<P>
-The numbering system used is also called the base. We talk of the number
-1100 base 2, the number 12 base 10.
-
-<P>
-For the binary system, is is common to write leading zero's. The numbers
+Normally if we do not speak about the numbering system used, we're
+using the decimal system. If we are talking about another numbering
+system, we'll have to make that clear. There are a few wide-spread
+methods to do so. One common form is to write <CODE>1010(2)</CODE> which means that
+you wrote down a number in the binary form. It is the number ten.
+If you would write 1010 it means the number one thousand and ten.</P>
+<P>In books, another form is most used. It uses subscript (little chars,
+more or less in between two rows). You can leave out the parentheses
+in that case and write down the number in normal characters followed
+with a little two just behind it.</P>
+<P>The numbering system used is also called the base. We talk of the number
+1100 base 2, the number 12 base 10.</P>
+<P>For the binary system, is is common to write leading zero's. The numbers
 are written down in series of four, eight or sixteen depending on the
-context.
-
-<P>
-We can use the binary form when talking to computers (...programming...)
-but the numbers will have large representations. The number 65535 would be
-written down as <CODE>1111111111111111(2)</CODE> which is 16 times the
-digit 1. This is difficult and prone to errors. Therefore we normally would
-use another base, called hexadecimal. It uses 16 different symbols. First
-the symbols from the decimal system are used, thereafter we continue with
-the alphabetic characters. We get 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D,
-E and F. This system is chosen because the hexadecimal form can be
-converted into the binary system very easy (and back).
-
-<P>
-There is yet another system in use, called the octal system. This was more
-common in the old days but not anymore. You will find it in use on some
-places so get used to it. The same story applies, but now with only eight
-different symbols.
-
-<P>
-<PRE> Binary      (2)
+context.</P>
+<P>We can use the binary form when talking to computers (...programming...)
+but the numbers will have large representations. The number 65535 would
+be written down as <CODE>1111111111111111(2)</CODE> which is 16 times the digit 1.
+This is difficult and prone to errors. Therefore we normally would use
+another base, called hexadecimal. It uses 16 different symbols. First
+the symbols from the decimal system are used, thereafter we continue
+with the alphabetic characters. We get 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A,
+B, C, D, E and F. This system is chosen because the hexadecimal form
+can be converted into the binary system very easy (and back).</P>
+<P>There is yet another system in use, called the octal system. This was
+more common in the old days but not anymore. You will find it in use
+on some places so get used to it. The same story applies, but now with
+only eight different symbols.</P>
+<PRE>
+ Binary      (2)
  Octal       (8)
  Decimal     (10)
- Hexadecimal (16)
-</PRE>
-<P>
-<PRE> (2)    (8) (10) (16)
+ Hexadecimal (16)</PRE>
+<PRE>
+ (2)    (8) (10) (16)
  00000   0    0    0
  00001   1    1    1
  00010   2    2    2 
@@ -162,233 +133,181 @@
  10010  22   18   12
  10011  23   19   13
  10100  24   20   14
- 10101  25   21   15
-</PRE>
-<P>
-Most computers used nowadays are using bytes of eight bits. This means that
-they store eight bits at a time. You can see why the octal system is not
-the most preferred for that: You'd need three digits to represent the eight
-bits and this means that you'd have to use one complete digit to represent
-only two bits (2+3+3=8). This is a waste. For hexadecimal digits, you need
-only two digits which are used completely:
-
-<P>
-<PRE> (2)      (8)  (10) (16)
- 11111111 377  255   FF
-</PRE>
-<P>
-You can see why binary and hexadecimal can be converted quickly: For each
-hexadecimal digit there are exactly four binary digits. Take a binary
-number. Each time take four digits from the right and make a hexadecimal
-digit from it (see the table above). Stop when there are no more digits.
-Other way around: Take a hexadecimal number. For each digit, write down its
-binary equivalent.
-
-<P>
-Computers (or rather the parsers running on them) would have a hard time
-converting a number like <CODE>1234(16).</CODE> Therefore hexadecimal
-numbers get a prefix. This prefix depends on the language you're writing
-in. Some of the prefixes are ``0x'' for C, ``$'' for Pascal, ``#'' for
-HTML. It is common to assume that if a number starts with a zero, it is
-octal. It does not matter what is used as long as you know what it is. I
-will use ``0x'' for hexadecimal, ``%'' for binary and ``0'' for octal. The
-following numbers are all the same, just the way they are written is
-different: 021 0x11 17 <CODE>%00010001</CODE>
-
-<P>
-To do arithmetics and conversions you need to understand one more thing. It
-is something you already know but perhaps you do not ``see'' it yet:
-
-<P>
-If you write down 1234, (so it is decimal) you are talking about the number
-one thousand, two hundred and thirty four. In sort of a formula:
-
-<P>
-<PRE> 1 * 1000 = 1000
+ 10101  25   21   15</PRE>
+<P>Most computers used nowadays are using bytes of eight bits. This means
+that they store eight bits at a time. You can see why the octal system
+is not the most preferred for that: You'd need three digits to represent
+the eight bits and this means that you'd have to use one complete digit
+to represent only two bits (2+3+3=8). This is a waste. For hexadecimal
+digits, you need only two digits which are used completely:</P>
+<PRE>
+ (2)      (8)  (10) (16)
+ 11111111 377  255   FF</PRE>
+<P>You can see why binary and hexadecimal can be converted quickly:
+For each hexadecimal digit there are exactly four binary digits.
+Take a binary number. Each time take four digits from the right and make
+a hexadecimal digit from it (see the table above). Stop when there are
+no more digits.
+Other way around: Take a hexadecimal number. For each digit, write down
+its binary equivalent.</P>
+<P>Computers (or rather the parsers running on them) would have a hard time
+converting a number like 1234(16). Therefore hexadecimal numbers get a
+prefix. This prefix depends on the language you're writing in. Some of
+the prefixes are ``0x'' for C, ``$'' for Pascal, ``#'' for HTML.
+It is common to assume that if a number starts with a zero, it is octal.
+It does not matter what is used as long as you know what it is.
+I will use ``0x'' for hexadecimal, ``%'' for binary and ``0'' for octal.
+The following numbers are all the same, just the way they are written is
+different:  021  0x11  17  %00010001</P>
+<P>To do arithmetics and conversions you need to understand one more thing.
+It is something you already know but perhaps you do not ``see'' it yet:</P>
+<P>If you write down 1234, (so it is decimal) you are talking about the
+number one thousand, two hundred and thirty four. In sort of a formula:</P>
+<PRE>
+ 1 * 1000 = 1000
  2 *  100 =  200
  3 *   10 =   30
- 4 *    1 =    4
-</PRE>
-<P>
-This can also be written as:
-
-<P>
-<PRE> 1 * 10^3
+ 4 *    1 =    4</PRE>
+<P>This can also be written as:</P>
+<PRE>
+ 1 * 10^3
  2 * 10^2
  3 * 10^1
- 4 * 10^0
-</PRE>
-<P>
-where ^ means ``to the power of''.
-
-<P>
-We are using the base 10, and the positions 0,1,2 and 3. The right-most
-position should NOT be multiplied with 10. The second from the right should
-be multiplied one time with 10. The third from the right is multiplied with
-10 two times. This continues for whatever positions are used.
-
-<P>
-It is the same in all other representations:
-
-<P>
-0x1234 will be
-
-<P>
-<PRE> 1 * 16^3
+ 4 * 10^0</PRE>
+<P>where ^ means ``to the power of''.</P>
+<P>We are using the base 10, and the positions 0,1,2 and 3.
+The right-most position should NOT be multiplied with 10. The second
+from the right should be multiplied one time with 10. The third from
+the right is multiplied with 10 two times. This continues for whatever
+positions are used.</P>
+<P>It is the same in all other representations:</P>
+<P>0x1234 will be</P>
+<PRE>
+ 1 * 16^3
  2 * 16^2
  3 * 16^1
- 4 * 16^0
-</PRE>
-<P>
-01234 would be
-
-<P>
-<PRE> 1 * 8^3
+ 4 * 16^0</PRE>
+<P>01234 would be</P>
+<PRE>
+ 1 * 8^3
  2 * 8^2
  3 * 8^1
- 4 * 8^0
-</PRE>
-<P>
-This example can not be done for binary as that system can only use two
-symbols. Another example:
-
-<P>
-<CODE>%1010</CODE> would be
-
-<P>
-<PRE> 1 * 2^3
+ 4 * 8^0</PRE>
+<P>This example can not be done for binary as that system can only use two
+symbols. Another example:</P>
+<P>%1010 would be</P>
+<PRE>
+ 1 * 2^3
  0 * 2^2
  1 * 2^1
- 0 * 2^0
-</PRE>
-<P>
-It would have been more easy to convert it to its hexadecimal form and just
-translate <CODE>%1010</CODE> into 0xA. After a while you get used to it.
-You will not need to do any calculations anymore but just know that 0xA
-means 10.
-
-<P>
-To convert a decimal number into a hexadecimal one you could use the next
+ 0 * 2^0</PRE>
+<P>It would have been more easy to convert it to its hexadecimal form and
+just translate %1010 into 0xA. After a while you get used to it. You will
+not need to do any calculations anymore but just know that 0xA means 10.</P>
+<P>To convert a decimal number into a hexadecimal one you could use the next
 method. It will take some time to be able to do the estimates but it will
-be more and more easy when you use the system more frequent. Another way is
-presented to you thereafter.
-
-<P>
-First you will need to know how many positions will be used in the other
-system. To do so, you need to know the maximum numbers. Well, that's not so
-hard as it looks. In decimal, the maximum number that you can form with two
-digits is ``99''. The maximum for three: ``999''. The next number would
-need an extra position. Reverse this idea and you will see that the number
-can be found by taking 10^3 (10*10*10 is 1000) minus 1 or 10^2 minus one.
-
-<P>
-This can be done for hexadecimal too:
-
-<P>
-<PRE> 16^4 = 0x10000 = 65536
+be more and more easy when you use the system more frequent. Another way
+is presented to you thereafter.</P>
+<P>First you will need to know how many positions will be used in the other
+system. To do so, you need to know the maximum numbers. Well, that's not
+so hard as it looks. In decimal, the maximum number that you can form 
+with two digits is ``99''. The maximum for three: ``999''. The next number
+would need an extra position. Reverse this idea and you will see that
+the number can be found by taking 10^3 (10*10*10 is 1000) minus 1 or
+10^2 minus one.</P>
+<P>This can be done for hexadecimal too:</P>
+<PRE>
+ 16^4 = 0x10000 = 65536
  16^3 =  0x1000 =  4096
  16^2 =   0x100 =   256
- 16^1 =    0x10 =    16
-</PRE>
-<P>
-If a number is smaller than 65536 it will thus fit in four positions. If
-the number is bigger than 4095, you will need to use position 4. How many
-times can you take 4096 from the number without going below zero is the
-first digit you write down. This will always be a number from 1 to 15 (0x1
-to 0xF). Do the same for the other positions.
-
-<P>
-Number is 41029. It is smaller than 16^4 but bigger than 16^3-1. This means
-that we have to use four positions. We can subtract 16^3 from 41029 ten
-times without going below zero. The leftmost digit will be ``A'' so we have
-0xA????. The number is reduced to 41029 - 10*4096 = 41029-40960 = 69. 69 is
-smaller than 16^3 but not bigger than 16^2-1. The second digit is therefore
-``0'' and we know 0xA0??. 69 is smaller than 16^2 and bigger than 16^1-1.
-We can subtract 16^1 (which is just plain 16) four times and write down
-``4'' to get 0xA04?. Take 64 from 69 (69 - 4*16) and the last digit is 5
---&gt; 0xA045.
-
-<P>
-The other method builds the number from the right. Take again 41029. Divide
-by 16 and do not use fractions (only whole numbers).
-
-<P>
-<PRE> 41029 / 16 is 2564 with a remainder of 5. Write down 5.
+ 16^1 =    0x10 =    16</PRE>
+<P>If a number is smaller than 65536 it will thus fit in four positions.
+If the number is bigger than 4095, you will need to use position 4.
+How many times can you take 4096 from the number without going below
+zero is the first digit you write down. This will always be a number
+from 1 to 15 (0x1 to 0xF). Do the same for the other positions.</P>
+<P>Number is 41029. It is smaller than 16^4 but bigger than 16^3-1. This
+means that we have to use four positions.
+We can subtract 16^3 from 41029 ten times without going below zero.
+The leftmost digit will be ``A'' so we have 0xA????.
+The number is reduced to 41029 - 10*4096 = 41029-40960 = 69.
+69 is smaller than 16^3 but not bigger than 16^2-1. The second digit
+is therefore ``0'' and we know 0xA0??.
+69 is smaller than 16^2 and bigger than 16^1-1. We can subtract 16^1
+(which is just plain 16) four times and write down ``4'' to get 0xA04?.
+Take 64 from 69 (69 - 4*16) and the last digit is 5 --&gt; 0xA045.</P>
+<P>The other method builds the number from the right. Take again 41029.
+Divide by 16 and do not use fractions (only whole numbers).</P>
+<PRE>
+ 41029 / 16 is 2564 with a remainder of 5. Write down 5.
  2564 / 16 is 160 with a remainder of 4. Write the 4 before the 5.
  160 / 16 is 10 with no remainder. Prepend 45 with 0.
- 10 / 16 is below one. End here and prepend 0xA. End up with 0xA045.
-</PRE>
-<P>
-Which method to use is up to you. Use whatever works for you. Personally I
-use them both without being able to tell what method I use in each case, it
-just depends on the number, I think. Fact is, some numbers will occur
-frequently while programming, if the number is close then I will use the
-first method (like 32770, translate into 32768 + 2 and just know that it is
-0x8000 + 0x2 = 0x8002).
-
-<P>
-For binary the same approach can be used. The base is 2 and not 16, and the
-number of positions will grow rapidly. Using the second method has the
-advantage that you can see very simple if you should write down a zero or a
-one: if you divide by two the remainder will be zero if it was an even
-number and one if it was an odd number: 41029 / 2 = 20514 remainder 1 20514
-/ 2 = 10257 remainder 0 10257 / 2 = 5128 remainder 1 5128 / 2 = 2564
-remainder 0 2564 / 2 = 1282 remainder 0 1282 / 2 = 641 remainder 0 641 / 2
-= 320 remainder 1 320 / 2 = 160 remainder 0 160 / 2 = 80 remainder 0 80 / 2
-= 40 remainder 0 40 / 2 = 20 remainder 0 20 / 2 = 10 remainder 0 10 / 2 = 5
-remainder 0 5 / 2 = 2 remainder 1 2 / 2 = 1 remainder 0 1 / 2 below 0
-remainder 1
-
-<P>
-Write down the results from right to left: <CODE>%1010000001000101</CODE>
-
-<P>
-Group by four:
-
-<P>
-<PRE> %1010000001000101
+ 10 / 16 is below one. End here and prepend 0xA. End up with 0xA045.</PRE>
+<P>Which method to use is up to you. Use whatever works for you. Personally
+I use them both without being able to tell what method I use in each
+case, it just depends on the number, I think. Fact is, some numbers
+will occur frequently while programming, if the number is close then
+I will use the first method (like 32770, translate into 32768 + 2 and
+just know that it is 0x8000 + 0x2 = 0x8002).</P>
+<P>For binary the same approach can be used. The base is 2 and not 16,
+and the number of positions will grow rapidly. Using the second method
+has the advantage that you can see very simple if you should write down
+a zero or a one: if you divide by two the remainder will be zero if it
+was an even number and one if it was an odd number:
+</P>
+<PRE>
+
+ 41029 / 2 = 20514 remainder 1
+ 20514 / 2 = 10257 remainder 0
+ 10257 / 2 =  5128 remainder 1
+  5128 / 2 =  2564 remainder 0
+  2564 / 2 =  1282 remainder 0
+  1282 / 2 =   641 remainder 0
+   641 / 2 =   320 remainder 1
+   320 / 2 =   160 remainder 0
+   160 / 2 =    80 remainder 0
+    80 / 2 =    40 remainder 0
+    40 / 2 =    20 remainder 0
+    20 / 2 =    10 remainder 0
+    10 / 2 =     5 remainder 0
+     5 / 2 =     2 remainder 1
+     2 / 2 =     1 remainder 0
+     1 / 2 below 0 remainder 1</PRE>
+<P>Write down the results from right to left: %1010000001000101</P>
+<P>Group by four:</P>
+<PRE>
+ %1010000001000101
  %101000000100 0101
  %10100000 0100 0101
- %1010 0000 0100 0101
-</PRE>
-<P>
-Convert into hexadecimal: 0xA045
-
-<P>
-Group <CODE>%1010000001000101</CODE> by three and convert into octal:
-
-<P>
-<PRE> %1010000001000101
+ %1010 0000 0100 0101</PRE>
+<P>Convert into hexadecimal: 0xA045</P>
+<P>Group %1010000001000101 by three and convert into octal:</P>
+<PRE>
+ %1010000001000101
  %1010000001000 101
  %1010000001 000 101
  %1010000 001 000 101
  %1010 000 001 000 101
  %1 010 000 001 000 101
  %001 010 000 001 000 101
-    1   2   0   1   0   5 --&gt; 0120105
-</PRE>
-<P>
-<PRE> So: %1010000001000101 = 0120105 = 0xA045 = 41029
+    1   2   0   1   0   5 --&gt; 0120105</PRE>
+<PRE>
+ So: %1010000001000101 = 0120105 = 0xA045 = 41029
  Or: 1010000001000101(2) = 120105(8) = A045(16) = 41029(10)
- Or: 1010000001000101(2) = 120105(8) = A045(16) = 41029
-</PRE>
-<P>
-At first while adding numbers, you'll convert them to their decimal form
-and then back into their original form after doing the addition. If you use
-the other numbering system often, you will see that you'll be able to do
-arithmetics in the base that is used. In any representation it is the same,
-add the numbers on the right, write down the rightmost digit from the
-result, remember the other digits and use them in the next round. Continue
-with the second digits from the right and so on:
-
-<P>
-<PRE>    %1010 + %0111 --&gt; 10 + 7 --&gt; 17 --&gt; %00010001
-</PRE>
-<P>
-will become
-
-<P>
-<PRE>    %1010
+ Or: 1010000001000101(2) = 120105(8) = A045(16) = 41029</PRE>
+<P>At first while adding numbers, you'll convert them to their decimal
+form and then back into their original form after doing the addition.
+If you use the other numbering system often, you will see that you'll
+be able to do arithmetics in the base that is used.
+In any representation it is the same, add the numbers on the right,
+write down the rightmost digit from the result, remember the other
+digits and use them in the next round. Continue with the second digits
+from the right and so on:</P>
+<PRE>
+    %1010 + %0111 --&gt; 10 + 7 --&gt; 17 --&gt; %00010001</PRE>
+<P>will become</P>
+<PRE>
+    %1010
     %0111 +
      ||||
      |||+-- add 0 + 1, result is 1, nothing to remember
@@ -397,39 +316,30 @@
      +----- add 1 + 0 + 1(remembered), result = 0, remember 1
             nothing to add, 1 remembered, result = 1
  --------
-   %10001 is the result, I like to write it as %00010001
-</PRE>
-<P>
-For low values, try to do the calculations yourself, check them with a
-calculator. The more you do the calculations yourself, the more you find
-that you didn't make mistakes. In the end, you'll do calculi in other bases
-as easy as you do in decimal.
-
-<P>
-When the numbers get bigger, you'll have to realize that a computer is not
-called a computer just to have a nice name. There are many different
+   %10001 is the result, I like to write it as %00010001</PRE>
+<P>For low values, try to do the calculations yourself, check them with
+a calculator. The more you do the calculations yourself, the more you
+find that you didn't make mistakes. In the end, you'll do calculi in
+other bases as easy as you do in decimal.</P>
+<P>When the numbers get bigger, you'll have to realize that a computer is
+not called a computer just to have a nice name. There are many different
 calculators available. Use them. For Unix you could use ``bc'' which is
-called so as it is short for Binary Calculator. It calculates not only in
-decimal, but in all bases you'll ever use (among them Binary).
-
-<P>
-For people on Windows: Start the calculator
-(start-&gt;programs-&gt;accessories-&gt;calculator) and if necessary click
-view-&gt;scientific. You now have a scientific calculator and can compute
-in binary or hexadecimal.
-
+called so as it is short for Binary Calculator. It calculates not only
+in decimal, but in all bases you'll ever use (among them Binary).</P>
+<P>For people on Windows:
+Start the calculator (start-&gt;programs-&gt;accessories-&gt;calculator)
+and if necessary click view-&gt;scientific. You now have a scientific
+calculator and can compute in binary or hexadecimal.</P>
 <P>
 <HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-I hope you enjoyed the examples and their descriptions. If you do, help
-other people by pointing them to this document when they are asking basic
-questions. They will not only get their answer but at the same time learn a
-whole lot more.
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>I hope you enjoyed the examples and their descriptions. If you do, help
+other people by pointing them to this document when they are asking
+basic questions. They will not only get their answer but at the same
+time learn a whole lot more.</P>
+<P>Alex van den Bogaerdt 
+&lt;<A HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt;</P>
 
-<P>
-Alex van den Bogaerdt &lt;<A
-HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt;
 </BODY>
 
 </HTML>

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdcreate.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdcreate.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdcreate.pod	Sat Jul 13 21:26:18 2002
@@ -2,6 +2,8 @@
 
 rrdtool create - Set up a new Round Robin Database
 
+=for html <div align="right"><a href="rrdcreate.pdf">PDF</a> version.</div>
+
 =head1 SYNOPSIS
 
 B<rrdtool> B<create> I<filename> 
@@ -50,7 +52,8 @@
 source from an B<RRD>. A I<ds-name> must be 1 to 19 characters long in
 the characters [a-zA-Z0-9_].
 
-I<DST> defines the Data Source Type. It can be one of the following:
+I<DST> defines the Data Source Type. See the section on "How to Measure" below for further insight.
+The Datasource Type must be onw of the following:
 
 =over 4
 
@@ -70,18 +73,20 @@
 
 =item B<DERIVE>
 
-will store the the derivative of the line going from the last to the current
-value of the data source. This can be useful for gauges, for example, to
-measure the rate of people entering or leaving a room. Internally, derive works exaclty like
-COUNTER but without overflow checks. So if your counter does not reset at 32 or 64 bit
-you might want to use DERIVE and combine it with a MIN value of 0.
+will store the derivative of the line going from the last to the
+current value of the data source. This can be useful for gauges, for
+example, to measure the rate of people entering or leaving a
+room. Internally, derive works exaclty like COUNTER but without
+overflow checks. So if your counter does not reset at 32 or 64 bit you
+might want to use DERIVE and combine it with a MIN value of 0.
 
 =item B<ABSOLUTE> 
 
 is for counters which get reset upon reading. This is used for fast counters
 which tend to overflow. So instead of reading them normally you reset them
 after every read to make sure you have a maximal time available before the
-next overflow.
+next overflow. Another usage is for things you count like number of messages
+since the last update.
 
 =back
 
@@ -125,6 +130,90 @@
 
 =back
 
+=head1 The HEARTBEAT and the STEP
+
+Here is an explanation by Don Baarda on the inner workings of rrdtool.
+It may help you to sort out why all this *UNKNOWN* data is popping
+up in your databases:
+
+RRD gets fed samples at arbitrary times. From these it builds Primary
+Data Points (PDPs) at exact times every "step" interval. The PDPs are
+then accumulated into RRAs.
+
+The "heartbeat" defines the maximum acceptable interval between
+samples. If the interval between samples is less than "heartbeat",
+then an average rate is calculated and applied for that interval. If
+the interval between samples is longer than "heartbeat", then that
+entire interval is considered "unknown". Note that there are other
+things that can make a sample interval "unknown", such as the rate
+exceeding limits, or even an "unknown" input sample.
+
+The known rates during a PDP's "step" interval are used to calculate
+an average rate for that PDP. Also, if the total "unknown" time during
+the "step" interval exceeds the "heartbeat", the entire PDP is marked
+as "unknown". This means that a mixture of known and "unknown" sample
+time in a single PDP "step" may or may not add up to enough "unknown"
+time to exceed "heartbeat" and hence mark the whole PDP "unknown". So
+"heartbeat" is not only the maximum acceptable interval between
+samples, but also the maximum acceptable amount of "unknown" time per
+PDP (obviously this is only significant if you have "heartbeat" less
+than "step").
+
+The "heartbeat" can be short (unusual) or long (typical) relative to
+the "step" interval between PDPs. A short "heartbeat" means you
+require multiple samples per PDP, and if you don't get them mark the
+PDP unknown. A long heartbeat can span multiple "steps", which means
+it is acceptable to have multiple PDPs calculated from a single
+sample. An extreme example of this might be a "step" of 5mins and a
+"heartbeat" of one day, in which case a single sample every day will
+result in all the PDPs for that entire day period being set to the
+same average rate. I<-- Don Baarda E<lt>don.baarda at baesystems.comE<gt>>
+
+
+=head1 HOW TO MEASURE
+
+Here are a few hints on how to measure:
+
+=over
+
+
+=item Temperature
+
+Normally you have some type of meter you can read to get the temperature.
+The temperature is not realy connected with a time. The only connection is
+that the temperature reading happened at a certain time. You can use the
+B<GAUGE> data source type for this. RRRtool will the record your reading
+together with the time.
+
+=item Mail Messages
+
+Assume you have a methode to count the number of messages transported by
+your mailserver in a certain amount of time, this give you data like '5
+messages in the last 65 seconds'. If you look at the count of 5 like and
+B<ABSOLUTE> datatype you can simply update the rrd with the number 5 and the
+end time of your monitoring period. RRDtool will then record the number of
+messages per second. If at some later stage you want to know the number of
+messages transported in a day, you can get the average messages per second
+from RRDtool for the day in question and multiply this number with the
+number of seconds in a day. Because all math is run with Doubles, the
+precision should be acceptable.
+
+=item It's always a Rate
+
+RRDtool stores rates in amount/second for COUNTER, DERIVE and ABSOLUTE data.
+When you plot the data, you will get on the y axis amount/second which you
+might be tempted to convert to absolute amount volume by multiplying by the
+delta-time between the points. RRDtool plots continuous data, and as such is
+not appropriate for plotting absolute volumes as for example "total bytes"
+sent and received in a router. What you probably want is plot rates that you
+can scale to for example bytes/hour or plot volumes with another tool that
+draws bar-plots, where the delta-time is clear on the plot for each point
+(such that when you read the graph you see for example GB on the y axis,
+days on the x axis and one bar for each day).
+
+=back
+
+
 =head1 EXAMPLE
 
 C<rrdtool create temperature.rrd --step 300 DS:temp:GAUGE:600:-273:5000

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdupdate.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdupdate.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdupdate.html	Sat Jul 13 21:26:18 2002
@@ -1,118 +1,89 @@
 <HTML>
 <HEAD>
 <TITLE>rrdupdate</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
-	<LI><A HREF="#EXAMPLE">EXAMPLE</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
+	<LI><A HREF="#example">EXAMPLE</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-rrdtool update - Store a new set of values into the rrd
-
-<P>
+<H1><A NAME="name">NAME</A></H1>
+<P>rrdtool update - Store a new set of values into the rrd</P>
+<div align="right"><a href="rrdupdate.pdf">PDF</a> version.</div><P>
 <HR>
-<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
-<P>
-<STRONG>rrdtool</STRONG>  <STRONG>update</STRONG>  <EM>filename</EM> 
- 
+<H1><A NAME="synopsis">SYNOPSIS</A></H1>
+<P><STRONG>rrdtool</STRONG> <STRONG>update</STRONG> <EM>filename</EM> 
 [<STRONG>--template</STRONG>|<STRONG>-t</STRONG>&nbsp;<EM>ds-name</EM>[<STRONG>:</STRONG><EM>ds-name</EM>]...] 
- 
 <STRONG>N</STRONG>|<EM>timestamp</EM><STRONG>:</STRONG><EM>value</EM>[<STRONG>:</STRONG><EM>value</EM>...] 
- 
-[<EM>timestamp</EM><STRONG>:</STRONG><EM>value</EM>[<STRONG>:</STRONG><EM>value</EM>...]&nbsp;...]
-
-
-
+[<EM>timestamp</EM><STRONG>:</STRONG><EM>value</EM>[<STRONG>:</STRONG><EM>value</EM>...]&nbsp;...]</P>
 <P>
 <HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-The <STRONG>update</STRONG> function feeds new data values into an <STRONG>RRD</STRONG>. The data gets time aligned according to the properties of the <STRONG>RRD</STRONG> to which the data is written.
-
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>The <STRONG>update</STRONG> function feeds new data values into an <STRONG>RRD</STRONG>. The
+data gets time aligned according to the properties of the <STRONG>RRD</STRONG> to
+which the data is written.</P>
 <DL>
-<DT><STRONG><A NAME="item_filename">filename</A></STRONG><DD>
-<P>
+<DT><STRONG><A NAME="item_filename"><EM>filename</EM></A></STRONG><BR>
+<DD>
 The name of the <STRONG>RRD</STRONG> you want to update.
-
-<DT><STRONG><A NAME="item__template_t">--template|-t ds-name[:ds-name]...</A></STRONG><DD>
-<P>
-by default, the update function expects the data input in the order, the
-data sources are defined in the RRD. This is not very error resistant, as
-you might be sending the wrong data into a RRD.
-
-<P>
-The template switch allows you to specify which data sources you are going
-to update and in which order. If the data sources specified in the template
-are not available in the rrd file, the update process will abort with an
-error message.
-
-<DT><STRONG><A NAME="item_N">N|timestamp:value[:value...]</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_%2D%2Dtemplate%7C%2Dt_ds%2Dname%5B%3Ads%2Dname%5D%"><STRONG>--template</STRONG>|<STRONG>-t</STRONG> <EM>ds-name</EM>[<STRONG>:</STRONG><EM>ds-name</EM>]...</A></STRONG><BR>
+<DD>
+by default, the update function expects the data input in the order,
+the data sources are defined in the RRD. This is not very error
+resistant, as you might be sending the wrong data into a RRD.
+<P>The template switch allows you to specify which data sources you are
+going to update and in which order. If the data sources specified in
+the template are not available in the rrd file, the update process
+will abort with an error message.</P>
+<P></P>
+<DT><STRONG><A NAME="item_N%7Ctimestamp%3Avalue%5B%3Avalue%2E%2E%2E%5D"><STRONG>N</STRONG>|<EM>timestamp</EM><STRONG>:</STRONG><EM>value</EM>[<STRONG>:</STRONG><EM>value</EM>...]</A></STRONG><BR>
+<DD>
 The data used for updating the RRD was acquired at a certain time. This
 time can either be defined in seconds since 1970-01-01. Or by using the
 letter 'N' the update time is set to be the current time. Negative time
-values are subtracted from the current time. Getting the timing right to
-the second is especially important when you are working with data-sources
-of type <STRONG>COUNTER</STRONG>,
-<STRONG>DERIVE</STRONG> or <STRONG>ABSOLUTE</STRONG>. 
-
-<P>
-The remaining elements of the argument are DS updates. The order of this
-list is the same as the order the data sources were defined in the rra. If
-there is no data for a certain data-source, the letter 
-<STRONG>U</STRONG> (eg. N:0.1:U:1) can be defined.
-
-<P>
-The format of the value acquired from the data source is dependent of the
-data source type chosen. Normally it will be numeric, but the data
-acquisition modules my impose their very own parsing of this parameter as
-long as the colon (<STRONG>:</STRONG>) remains the data source value separator.
-
-</DL>
+values are subtracted from the current time.
+Getting the timing right to the second is especially
+important when you are working with data-sources of type <STRONG>COUNTER</STRONG>,
+<STRONG>DERIVE</STRONG> or <STRONG>ABSOLUTE</STRONG>.
+<P>The remaining elements of the argument are DS updates. The order of this list is
+the same as the order the data sources were defined in the rra.
+If there is no data for a certain data-source, the letter 
+<STRONG>U</STRONG> (eg. N:0.1:U:1) can be defined.</P>
+<P>The format of the value acquired from the data source is dependent of the
+data source type chosen. Normally it will be numeric, but the data acquisition
+modules my impose their very own parsing of this parameter as long as the colon
+(<STRONG>:</STRONG>) remains the data source value separator.</P>
+<P></P></DL>
 <P>
 <HR>
-<H1><A NAME="EXAMPLE">EXAMPLE</A></H1>
-<P>
-<CODE>rrdtool update demo1.rrd N:3.44:3.15:U:23</CODE>
-
-
-
-<P>
-Update the database file demo1.rrd with 3 known and one <EM>*UNKNOWN*</EM>
-value. Use the current time as the update time.
-
-<P>
-<CODE>rrdtool update demo2.rrd 887457267:U 887457521:22 88745790:2.7</CODE>
-
-
-
-<P>
-Update the database file demo2.rrd which expects data from a single
-data-source, three times. First with an <EM>*UNKNOWN*</EM> value then with two normal readings. The update interval seems to be around
-300 seconds.
-
+<H1><A NAME="example">EXAMPLE</A></H1>
+<P><CODE>rrdtool update demo1.rrd N:3.44:3.15:U:23</CODE></P>
+<P>Update the database file demo1.rrd with 3 known and one <EM>*UNKNOWN*</EM>
+value. Use the current time as the update time.</P>
+<P><CODE>rrdtool update demo2.rrd 887457267:U 887457521:22 88745790:2.7</CODE></P>
+<P>Update the database file demo2.rrd which expects data from a single
+data-source, three times. First with an <EM>*UNKNOWN*</EM> value then with two
+normal readings. The update interval seems to be around 300 seconds.</P>
 <P>
 <HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-Tobias Oetiker &lt;<A
-HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;</P>
 
 </BODY>
 

Added: trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.es.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.es.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.es.txt	Sat Jul 13 21:26:18 2002
@@ -0,0 +1,1650 @@
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+NNNNAAAAMMMMEEEE
+     rrdtutorial - Tutorial sobre RRDtool por Alex van den
+     Bogaerdt (Traducido al castellano por Jes'us Couto Fandi~no)
+
+DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN //// DDDDEEEESSSSCCCCRRRRIIIIPPPPCCCCIIII''OO''OONNNN
+     RRDtool es un programa escrito por Tobias Oetiker con la
+     colaboraci'on de muchas personas en diversas partes del
+     mundo. Alex van den Bogaerdt escribi'o este documento para
+     ayudarte a entender que es RRDtool y que es lo que puede
+     hacer por ti.
+
+     La documentaci'on que viene con RRDtool puede ser demasiado
+     t'ecnica para algunos. Este tutorial existe para ayudarte a
+     entender las funciones b'asicas de RRdtool. Debe servirte de
+     preparaci'on para leer la documentaci'on, y adem'as explica
+     algunas ideas generales sobre estad'istica, con un enfoque
+     particular hacia las redes.
+
+TTTTUUUUTTTTOOOORRRRIIIIAAAALLLL
+     IIIImmmmppppoooorrrrttttaaaannnntttteeee
+
+     ,iPor favor, no te adelantes en la lectura de este documento!
+     Esta primera parte explica los fundamentos b'asicos. Puede
+     ser aburrida, pero si te saltas los fundamentos, los
+     ejemplos no te van a tener mucho sentido.
+
+     ''cc''ccQQQQuuuu''ee''ee eeeessss RRRRRRRRDDDDttttoooooooollll????
+
+     RRDtool significa "herramienta de bases de datos en round
+     robin".  "Round robin" es una t'ecnica que implica un n'umero
+     fijo de datos, y un apuntador al elemento m'as reciente.
+     Piensa en un circulo con unos cuantos puntos dibujados
+     alrededor del borde; estos puntos son los lugares donde se
+     pueden guardar los datos. Dibuja ahora una flecha desde el
+     centro del c'irculo a uno de los puntos; este es el
+     apuntador.  Cuando se lee o escribe el dato actualmente
+     apuntado, la flecha se mueve al pr'oximo elemento. Como
+     estamos en un c'irculo, no hay ni principio ni fin; siempre
+     puedes seguir, eternamente. Al cabo de un tiempo ya se
+     habr'an usado todas las posiciones disponibles y el proceso
+     empieza a reutilizar las antiguas. De esta forma, la base de
+     datos no crece en tama~no y, por lo tanto, no requiere ning'un
+     mantenimiento.  RRDtool trabaja con estas bases de datos en
+     "round-robin", guardando y recuperando datos de ellas.
+
+     ''cc''ccQQQQuuuu''ee''ee ddddaaaattttoooossss ppppuuuueeeeddddeeeennnn gggguuuuaaaarrrrddddaaaarrrrsssseeee eeeennnn uuuunnnnaaaa RRRRRRRRDDDD????
+
+     Lo que se te ocurra. Debes poder medir alg'un valor dado en
+     distintos momentos en el tiempo y proveer a RRDtool de estos
+     valores. Si puedes hacer esto, RRDtool puede guardar los
+     datos. Los valores tienen que ser num'ericos, pero no
+     necesariamente enteros, como en MRTG.
+
+
+
+2001-02-20             Last change: 1.0.33                      1
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     Muchos ejemplos mencionan SNMP, que es el acr'onimo de
+     "Simple Network Management Protocol" (Protocolo Simple de
+     Administraci'on de Redes). Lo de "simple" se refiere al
+     protocolo - no se supone que sea f'acil administrar o
+     monitorizar una red. Cuando hayas terminado con este
+     documento, deber'as saber lo suficiente para entender cuando
+     oigas a otros hablar sobre SNMP. Por ahora, simplemente
+     considera a SNMP como una forma de preguntarle a los
+     dispositivos por los valores de ciertos contadores que
+     mantienen. Son estos valores de estos contadores los que
+     vamos a almacenar en la RRD.
+
+     ''cc''ccQQQQuuuu''ee''ee ppppuuuueeeeddddoooo hhhhaaaacccceeeerrrr ccccoooonnnn eeeessssttttaaaa hhhheeeerrrrrrrraaaammmmiiiieeeennnnttttaaaa????
+
+     RRDtool se deriva de MRTG (Multi Router Traffic Grapher,
+     Graficador De Tr'afico de M'ultiples Enrutadores).  MRTG
+     empez'o como un peque~no script para poder graficar el uso de
+     una conexi'on a la Internet. Luego evolucion'o, permitiendo
+     graficar otras fuentes de datos, como temperatura,
+     velocidad, voltajes, cantidad de p'aginas impresas, etc... Lo
+     m'as probable es que empieces a usar RRDtool para guardar y
+     procesar datos conseguidos a trav'es de SNMP, y que los datos
+     sean el n'umero de bytes (o bits) transferidos desde y hacia
+     una red u ordenador. RRDtool te permite crear una base de
+     datos, guardar los datos en ellas, recuperarlos y crear
+     gr'aficos en formato GIF o PNG, para mostrarlos en un
+     navegador web. Esas im'agenes dependen de los datos que hayas
+     guardado y pueden, por ejemplo, ser un sumario del promedio
+     de uso de la red, o los picos de tr'afico que ocurrieron.
+     Tambi'en lo puedes usar para mostrar el nivel de las mareas,
+     la radiaci'on solar, el consumo de electricidad, el n'umero de
+     visitantes en una exposici'on en un momento dado, los niveles
+     de ruido cerca del aeropuerto, la temperatura en tu lugar de
+     vacaciones favorito, o en la nevera, o cualquier otra cosa
+     que te puedas imaginar, mientras tengas alg'un sensor con el
+     cual medir los datos y seas capaz de pasarle los n'umeros a
+     RRDtool.
+
+     ''cc''ccYYYY ssssiiii aaaa''uu''uunnnn tttteeeennnnggggoooo pppprrrroooobbbblllleeeemmmmaaaassss ddddeeeessssppppuuuu''ee''eessss ddddeeee lllleeeeeeeerrrr eeeesssstttteeee ddddooooccccuuuummmmeeeennnnttttoooo????
+
+     Lo primero, ,il'eelo otra vez!. Puede que te hayas perdido de
+     algo.  Si no puedes compilar el c'odigo fuente y usas un
+     sistema operativo bastante com'un, casi seguro que no es la
+     culpa de RRDtool.  Probablemente consigas versiones pre-
+     compiladas por la Internet. Si provienen de una fuente
+     confiable, 'usalas. Si, por otro lado, el programa funciona,
+     pero no te da los resultados que tu esperabas, puede ser un
+     problema con la configuraci'on; rev'isala y comp'arala con los
+     ejemplos.
+
+     Hay una lista de correo electr'onico y una archivo de la
+     misma. Lee la lista durante unas cuantas semanas, y busca en
+
+
+
+2001-02-20             Last change: 1.0.33                      2
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     el archivo. Es descort'es hacer una pregunta sin haber
+     revisado el archivo; ,ipuede que tu problema ya haya sido
+     resuelto antes! Normalmente ocurre as'i en todas las listas
+     de correo, no s'olo esta. Examina la documentaci'on que vino
+     con RRDtool para ver donde est'a el archivo y como usarlo.
+
+     Te sugiero que te tomes un momento y te subscribas a la
+     lista ahora mismo, enviando un mensaje a rrd-users-
+     request at list.ee.ethz.ch con t'itulo `subscribe'. Si
+     eventualmente deseas salirte de la lista, env'ia otro correo
+     a la misma direcci'on, con t'itulo `unsubscribe'.
+
+     ''cc''ccCCCC''oo''oommmmoooo mmmmeeee vvvvaaaassss aaaa aaaayyyyuuuuddddaaaarrrr????
+
+     D'andote descripciones y ejemplos detallados. Asumimos que el
+     seguir las instrucciones en el orden en que se presentan
+     aqu'i te dar'a suficiente conocimiento  de RRDtool como para
+     que experimentes por tu cuenta. Si no funciona a la primera,
+     puede que te hallas saltado algo; siguiendo los ejemplos
+     obtendr'as algo de experiencia pr'actica y, lo que es m'as
+     importante, un poco de informaci'on sobre como funciona el
+     programa.
+
+     Necesitar'as saber algo sobre n'umeros hexadecimales. Si no,
+     empieza por leer "bin_dec_hex" antes de continuar.
+
+     TTTTuuuu pppprrrriiiimmmmeeeerrrraaaa bbbbaaaasssseeee ddddeeee ddddaaaattttoooossss eeeennnn rrrroooouuuunnnndddd----rrrroooobbbbiiiinnnn
+
+     En mi opini'on, la mejor forma de aprender algo es
+     haci'endolo. 'cPor qu'e no empezamos ya? Vamos a crear una base
+     de datos, poner unos cuantos valores en ella y extraerlos
+     despu'es. La salida que obtengas debe ser igual a la que
+     aparece en este documento.
+
+     Empezaremos con algo f'acil, comparando un coche con un
+     enrutador, o por decirlo de otra forma, comparando
+     kil'ometros con bits y bytes. A nosotros nos da lo mismo; son
+     unos n'umeros obtenidos en un espacio de tiempo.
+
+     Asumamos que tenemos un dispositivo que transfiere bytes
+     desde y hacia la Internet. Este dispositivo tiene un
+     contador que empieza en 0 al encenderse y se incrementa con
+     cada byte transferido. Este contador tiene un valor m'aximo;
+     si ese valor se alcanza y se cuenta un byte m'as, el contador
+     vuelve a empezar desde cero. Esto es exactamente lo mismo
+     que pasa con muchos contadores, como el cuentakil'ometros del
+     coche. En muchas de las disertaciones sobre redes se habla
+     de bits por segundo, as'i que empezaremos por acostumbrarnos
+     a esto. Asumamos que un byte son 8 bits y empecemos a pensar
+     en bits y no en bytes. ,iEl contador, sin embargo, sigue
+     contando en bytes! En el mundo SNMP, la mayor'ia de los
+     contadores tienen una longitud de 32 bits. Esto significa
+
+
+
+2001-02-20             Last change: 1.0.33                      3
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     que pueden contar desde 0 hasta 4294967295. Usaremos estos
+     valores en los ejemplos. El dispositivo, cuando le
+     preguntamos, retorna el valor actual del contador. Como
+     sabemos el tiempo transcurrido desde la 'ultima vez que le
+     preguntamos, sabemos cuantos bytes se han transferido `***en
+     promedio***' por segundo. Esto no es muy dif'icil de
+     calcular; primero en palabras, luego en operaciones:
+
+     1.  Toma el valor actual del contador y r'estale el valor
+         anterior
+
+     2.  Haz lo mismo con la fecha
+
+     3.  Divide el resultado del paso (1) por el resultado del
+         paso (2).  El resultado es la cantidad de bytes por
+         segundo. Si lo multiplicas por ocho obtienes la cantidad
+         de bits por segundo
+
+       bps = (contador_actual - contador_anterior) / (fecha_actual - fecha_anterior) * 8
+
+     Para algunos ser'a de ayuda traducir esto a un ejemplo
+     automotor.  No prueben estas velocidades en la pr'actica, y
+     si lo hacen, no me echen la culpa por los resultados.
+
+     Usaremos las siguientes abreviaturas:
+
+      M:    metros
+      KM:   kil'ometros (= 1000 metros).
+      H:    horas
+      S:    segundos
+      KM/H: kil'ometros por hora
+      M/S:  metros por segundo
+
+     Vas conduciendo un coche. A las 12:05, miras el contador en
+     el salpicadero y ves que el coche ha recorrido 12345 KM. A
+     las 12:10 vuelves a mirar otra vez, y dice 12357 KM. Quiere
+     decir, que has recorrido 12 KM en cinco minutos. Un
+     cient'ifico convertir'ia esto en metros por segundos; esto es
+     bastante parecido al problema de pasar de bytes transferidos
+     en 5 minutos a bits por segundo.
+
+     Viajamos 12 kil'ometros, que son 12000 metros. Tardamos 5
+     minutos, o sea 300 segundos. Nuestra velocidad es 12000M /
+     300S igual a 40 M/S.
+
+     Tambi'en podemos calcular la velocidad en KM/H: 12 veces 5
+     minutos es una hora, as'i que multiplicando los 12 KM por 12
+     obtenemos 144 KM/H. No intentes esto en casa, o por donde
+     vivo :-)
+
+     Recuerda que estos n'umeros son tan s'olo promedios. No hay
+     forma de deducir, viendo s'olo los n'umeros, si fuiste a una
+
+
+
+2001-02-20             Last change: 1.0.33                      4
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     velocidad constante.  Hay un ejemplo m'as adelante en el
+     tutorial que explica esto.
+
+     Espero que entiendas que no hay diferencia entre calcular la
+     velocidad en M/S o bps; s'olo la forma en que recogemos los
+     datos es distinta. Inclusive, la K de kilo en este caso es
+     exactamente la misma, ya que en redes k es 1000
+
+     Ahora vamos a crear una base de datos en la que guardar
+     todos estos interesantes valores. El m'etodo a usar para
+     arrancar el programa puede variar de un sistema de operaci'on
+     a otro, pero asumamos que lo puedes resolver tu mismo en
+     caso que se diferente en el sistema que usas.  Aseg'urate de
+     no sobreescribir ning'un archivo en tu sistema al ejecutarlo
+     y escribe todo como una sola l'inea (tuve que partirlo para
+     que fuera legible), salt'andote todos los caracteres '\'
+
+        rrdtool create test.rrd             \
+                 --start 920804400          \
+                 DS:speed:COUNTER:600:U:U   \
+                 RRA:AVERAGE:0.5:1:24       \
+                 RRA:AVERAGE:0.5:6:10
+
+     (o sea, escribe: `rrdtool create test.rrd --start 920804400
+     DS ...')
+
+     ''cc''ccQQQQuuuu''ee''ee hhhheeeemmmmoooossss ccccrrrreeeeaaaaddddoooo????
+
+     Hemos creado una base de datos en round robin llamada test
+     (test.rrd), que empieza desde el mediod'ia del d'ia en que
+     empec'e a escribir este documento (7 de marzo de 1999). En
+     ella se guarda una fuente de datos (DS), llamada "speed",
+     que se lee de un contador. En la misma base de datos se
+     guardan dos archivos en round robin (RRAs), uno promedia los
+     datos cada vez que se leen (o sea, no hay nada que
+     promediar), y mantiene 24 muestras (24 por 5 minutos = 2
+     horas de muestras). El otro promedia 6 muestras (media
+     hora), y guarda 10 de estos promedios (o sea, 5 horas). Las
+     opciones restantes las veremos m'as adelante.
+
+     RRDtool usa un formato de "fecha" especial que viene del
+     mundo de UNIX. Estas "fechas" son el n'umero de segundos que
+     han pasado desde el primero de enero de 1970, zona UTC. Este
+     n'umero de segundos se convierte luego en la fecha local, por
+     lo que varia seg'un la franja horaria.
+
+     Lo m'as probable es que tu no vivas en la misma parte del
+     mundo que yo, por lo que tu franja horaria ser'a diferente.
+     En los ejemplos, cuando mencione horas, puede que no sean
+     las mismas para ti; esto no afecta mucho los resultados,
+     s'olo tienes que corregir las horas mientras lees. Por
+     ejemplo, las 12:05 para m'i son las 11:05 para los amigos en
+
+
+
+2001-02-20             Last change: 1.0.33                      5
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     la Gran Breta~na.
+
+     Ahora tenemos que llenar nuestra base de datos con valores.
+     Vamos a suponer que le'imos estos datos:
+
+      12:05  12345 KM
+      12:10  12357 KM
+      12:15  12363 KM
+      12:20  12363 KM
+      12:25  12363 KM
+      12:30  12373 KM
+      12:35  12383 KM
+      12:40  12393 KM
+      12:45  12399 KM
+      12:50  12405 KM
+      12:55  12411 KM
+      13:00  12415 KM
+      13:05  12420 KM
+      13:10  12422 KM
+      13:15  12423 KM
+
+     Llenaremos la base de datos as'i:
+
+      rrdtool update test.rrd 920804700:12345 920805000:12357 920805300:12363
+      rrdtool update test.rrd 920805600:12363 920805900:12363 920806200:12373
+      rrdtool update test.rrd 920806500:12383 920806800:12393 920807100:12399
+      rrdtool update test.rrd 920807400:12405 920807700:12411 920808000:12415
+      rrdtool update test.rrd 920808300:12420 920808600:12422 920808900:12423
+
+     Lo que significa: actualiza nuestra base de datos test con
+     los siguientes valores:
+
+      fecha 920804700, valor 12345
+      fecha 920805000, valor 12357
+
+      etc'etera.
+
+     Como ves, pueden introducirse m'as de un valor en la base de
+     datos por ejecuci'on del comando. Yo los agrupo de tres en
+     tres para hacerlo legible, pero en realidad el m'aximo
+     depende del sistema de operaci'on.
+
+     Ahora podemos recuperar los datos usando ``rrdtool fetch'':
+
+      rrdtool fetch test.rrd AVERAGE --start 920804400 --end 920809200
+
+     Debes obtener esto como salida:
+
+                         speed
+
+
+
+
+
+
+2001-02-20             Last change: 1.0.33                      6
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+      920804400:        NaN
+      920804700:        NaN
+      920805000: 4.0000000000e-02
+      920805300: 2.0000000000e-02
+      920805600: 0.0000000000e+00
+      920805900: 0.0000000000e+00
+      920806200: 3.3333333333e-02
+      920806500: 3.3333333333e-02
+      920806800: 3.3333333333e-02
+      920807100: 2.0000000000e-02
+      920807400: 2.0000000000e-02
+      920807700: 2.0000000000e-02
+      920808000: 1.3333333333e-02
+      920808300: 1.6666666667e-02
+      920808600: 6.6666666667e-03
+      920808900: 3.3333333333e-03
+      920809200:        NaN
+
+     Si no, hay algo mal. Probablemente tu sistema de operaci'on
+     muestre ``NaN'' de otra forma; representa "Not a Number", o
+     sea "No es un n'umero". Si aparece ``U'' o ``UNKN'' o algo
+     parecido, es lo mismo. Si hay alguna otra diferencia,
+     probablemente te equivocaste al introducir alg'un P valor
+     (asumiendo que mi tutorial est'a bien, por supuesto :-). En
+     ese caso, borra la base de datos y prueba de nuevo.
+
+     Lo que representa exactamente esta salida lo vamos m'as
+     adelante en el tutorial.
+
+     HHHHoooorrrraaaa ddddeeee hhhhaaaacccceeeerrrr aaaallllgggguuuunnnnoooossss ggggrrrr''aa''aaffffiiiiccccoooossss
+
+     Prueba este comando:
+
+      rrdtool graph speed.gif                                 \
+              --start 920804400 --end 920808000               \
+              DEF:myspeed=test.rrd:speed:AVERAGE              \
+              LINE2:myspeed#FF0000
+
+     Este comando crea speed.gif, un gr'afico de los datos desde
+     las 12:00 hasta las 13:00. Contiene una definici'on de la
+     variable myspeed y define el color como rojo. Notar'as que el
+     gr'afico no comienza exactamente a las 12:00 sino a las
+     12:05, y es porque no tenemos datos suficientes como para
+     calcular el promedio de velocidad antes de ese momento. Esto
+     s'olo ocurre en caso de que se pierdan alg'un muestreo, lo que
+     esperamos que no debe ocurrir muy a menudo.
+
+     Si ha funcionado, ,ifelicitaciones!. Si no, revisa qu'e puede
+     estar mal.
+
+     La definici'on de colores se construye a partir del rojo,
+     verde y azul. Especificas cuanto de cada uno de estos
+
+
+
+2001-02-20             Last change: 1.0.33                      7
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     componentes vas a usar en hexadecimal: 00 significa "nada de
+     este color" y FF significa "este color a m'axima intensidad".
+     El "color" blanco es la mezcla del rojo, verde y azul a toda
+     intensidad: FFFFFF; el negro es la ausencia de todos los
+     colores: 000000.
+
+        rojo    #FF0000
+        verde   #00FF00
+        azul    #0000FF
+        violeta #FF00FF     (mezcla de rojo y azul)
+        gris    #555555     (un tercio de cada uno de los colores)
+
+     El archivo GIF que acabas de crear puede verse con tu visor
+     de archivos de imagen favorito. Los navegadores lo mostrar'an
+     usando la URL
+     ``file://el/camino/de/directorios/hasta/speed.gif''
+
+     GGGGrrrr''aa''aaffffiiiiccccoooossss ccccoooonnnn uuuunnnn ppppooooccccoooo ddddeeee mmmmaaaatttteeeemmmm''aa''aattttiiiiccccaaaa
+
+     Cuando veas la imagen, notar'as que el eje horizontal tiene
+     unas etiquetas marcando las 12:10, 12:20, 12:30, 12:40 y
+     12:50. Los otros dos momentos (12:00 y 13:00) no se pueden
+     mostrar bien por falta de datos, as'i que el programa se los
+     salta. El eje vertical muestra el rango de los valores que
+     entramos. Introdujimos los kil'ometros y luego dividimos
+     entre 300 segundos, por lo que obtuvimos valores bastante
+     bajos. Para ser exactos, el primer valor, 12 (12357-12345),
+     dividido entre 300 da 0.04, lo que RRDtool muestra como
+     ``40m'', o sea ``40/1000''. ,iLa ``m''' no tiene nada que ver
+     con metros, kil'ometros o mil'imetros!.  RRDtool no sabe nada
+     de unidades, el s'olo trabaja con n'umeros, no con metros.
+
+     Donde nos equivocamos fue en que debimos medir en metros.
+     As'i, (12357000-12345000)/300 = 12000/300 = 40.
+
+     Vamos a corregirlo. Podr'iamos recrear la base de datos con
+     los valores correctos, pero hay una forma mejor: ,ihaciendo
+     los c'alculos mientras creamos el archivo gif!
+
+        rrdtool graph speed2.gif                           \
+           --start 920804400 --end 920808000               \
+           --vertical-label m/s                            \
+           DEF:myspeed=test.rrd:speed:AVERAGE              \
+           CDEF:realspeed=myspeed,1000,*                   \
+           LINE2:realspeed#FF0000
+
+     Cuando veas esta imagen, notar'as que la ``m'' ha
+     desaparecido, y ahora tienes los resultados correctos.
+     Adem'as hemos a~nadido una etiqueta a la imagen. Apartando
+     esto, el archivo GIF es el mismo.
+
+
+
+
+
+2001-02-20             Last change: 1.0.33                      8
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     Las operaciones est'an en la secci'on del CDEF y est'an
+     escritas en Notaci'on Polaca Inversa (Reverse Polish Notation
+     o ``RPN''). En palabras, dice: "toma la fuente de datos
+     myspeed y el numero 1000, y multipl'icalos". No te molestes
+     en meterte con RPN todav'ia, la veremos con m'as detalle m'as
+     adelante. Adem'as, puede que quieras leer mi tutorial sobre
+     los CDEF y el tutorial de Steve Rader sobre RPN, pero
+     primero terminemos con este.
+
+     ,iUn momento! Si podemos multiplicar los valores por mil,
+     entonces, ,itambi'en deber'ia ser posible el mostrar la
+     velocidad en kil'ometros por hora usando los mismos datos!
+
+     Para cambiar el valor que medimos en metros por segundo,
+     calculamos los metros por hora (valor * 3600) y dividimos
+     entre 1000 para sacar los kil'ometros por hora. Todo junto
+     hace valor * (3600/1000) == valor * 3.6.
+
+     Como en nuestra base de datos cometimos un error guardando
+     los valores en kil'ometros, debemos compensar por ello,
+     multiplicando por 100, por lo que al aplicar esta correcci'on
+     nos queda valor * 3600.
+
+     Ahora vamos a crear este gif, agre'andole un poco m'as de
+     magia...
+
+        rrdtool graph speed3.gif                           \
+           --start 920804400 --end 920808000               \
+           --vertical-label km/h                           \
+           DEF:myspeed=test.rrd:speed:AVERAGE              \
+           "CDEF:kmh=myspeed,3600,*"                       \
+           CDEF:fast=kmh,100,GT,kmh,0,IF                   \
+           CDEF:good=kmh,100,GT,0,kmh,IF                   \
+           HRULE:100#0000FF:"Maximum allowed"              \
+           AREA:good#00FF00:"Good speed"                   \
+           AREA:fast#FF0000:"Too fast"
+
+     Esto luce mucho mejor. La velocidad en KM/H, y adem'as
+     tenemos una l'inea extra mostrando la velocidad m'axima
+     permitida (en el camino por donde conduzco). Tambi'en le
+     cambie los colores de la velocidad, y ahora paso de ser una
+     l'inea a un 'area.
+
+     Los c'alculos son m'as complejos ahora. Para calcular la
+     velocidad "aceptable":
+
+        Verifica si la velocidad en kmh es mayor que 100     ( kmh,100 ) GT
+        Si es as'i, retorna 0, si no, retorna la velocidad    ((( kmh,100 ) GT ), 0, kmh) IF
+
+     Para calcular la parte de velocidad "excesiva":
+
+
+
+
+
+2001-02-20             Last change: 1.0.33                      9
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+        Verifica si la velocidad en kmh es mayor que 100     ( kmh,100 ) GT
+        Si es as'i, retorna la velocidad, si no, retorna 0    ((( kmh,100) GT ), kmh, 0) IF
+
+
+     MMMMaaaaggggiiiiaaaa ggggrrrr''aa''aaffffiiiiccccaaaa
+
+     Me gusta creer que virtualmente no hay limites para lo que
+     RRDtool puede hacer con los datos. No voy a explicarlo en
+     detalle, pero mira este GIF:
+
+        rrdtool graph speed4.gif                           \
+           --start 920804400 --end 920808000               \
+           --vertical-label km/h                           \
+           DEF:myspeed=test.rrd:speed:AVERAGE              \
+           "CDEF:kmh=myspeed,3600,*"                       \
+           CDEF:fast=kmh,100,GT,100,0,IF                   \
+           CDEF:over=kmh,100,GT,kmh,100,-,0,IF             \
+           CDEF:good=kmh,100,GT,0,kmh,IF                   \
+           HRULE:100#0000FF:"Maximum allowed"              \
+           AREA:good#00FF00:"Good speed"                   \
+           AREA:fast#550000:"Too fast"                     \
+           STACK:over#FF0000:"Over speed"
+
+     Vamos a crear una p'agina HTML simple para ver los tres
+     archivos GIF:
+
+        <HTML><HEAD><TITLE>Velocidad</TITLE></HEAD><BODY>
+        <IMG src="speed2.gif" alt="Speed in meters per second">
+        <BR>
+        <IMG src="speed3.gif" alt="Speed in kilometers per hour">
+        <BR>
+        <IMG src="speed4.gif" alt="Traveled too fast?">
+        </BODY></HTML>
+
+     Gu'ardalo como ``speed.html'' o algo parecido, y exam'inalo
+     con un navegador.
+
+     Ahora, todo lo que tienes que hacer es medir los datos
+     regularmente y actualizar la base de datos. Cuando quieras
+     verlos, vuelve a crear los archivos GIF y aseg'urate que se
+     carguen de nuevo en tu navegador (Nota: presionar el bot'on
+     de "refrescar" puede no ser suficiente; en particular,
+     Netscape tiene un problema al respecto, por lo que
+     necesitaras darle al bot'on mientras presionas la tecla de
+     may'usculas.
+
+     AAAAccccttttuuuuaaaalllliiiizzzzaaaacccciiiioooonnnneeeessss ddddeeee vvvveeeerrrrddddaaaadddd
+
+     Ya hemos usado el comando ``update''; vimos que recibia uno
+     o m'as par'ametros en el formato: ``<fecha>:<valor>''. Para
+     facilitarte las cosas, puedes obtener la fecha actual
+     colocando ``N'' en la fecha. Tambi'en podr'ias usar la funci'on
+
+
+
+2001-02-20             Last change: 1.0.33                     10
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     ``time'' de Perl para obtenerla. El ejemplo m'as corto de
+     todo el tutorial :)
+
+        perl -e 'print time, "\n" '
+
+     Ahora, la forma de poner a correr un programa a intervalos
+     regulares de tiempo depende del sistema de operaci'on. La
+     actualizaci'on, en pseudo-c'odigo, ser'ia:
+
+        Toma el valor, col'ocalo en la variable "$speed"
+        rrdtool update speed.rrd N:$speed
+
+     (Pero no lo hagas sobre nuestra base de datos de pruebas,
+     que a'un la vamos a usar en otros ejemplos.
+
+     Eso es todo. Ejecutando este script cada 5 minutos, lo 'unico
+     que tienes que hacer para ver los gr'aficos actuales es
+     correr los ejemplos anteriores, que tambi'en puedes poner en
+     un script. Luego de correrlo, basta con cargar index.html
+
+     UUUUnnnnaaaassss ppppaaaallllaaaabbbbrrrraaaassss ssssoooobbbbrrrreeee SSSSNNNNMMMMPPPP
+
+     Me imagino que muy pocas personas ser'an capaces de obtener
+     en su ordenador datos reales de su coche cada 5 minutos; los
+     dem'as nos tendremos que conformar con alg'un otro contador.
+     Puedes, por ejemplo, medir la cantidad de p'aginas que ha
+     hecho una impresora, cuanto caf'e has hecho con la cafetera,
+     el medidor del consumo de electricidad, o cualquier otra
+     cosa. Cualquier contador incremental puede monitorizarse y
+     graficarse con lo que has aprendido hasta ahora. M'as
+     adelante, veremos tambi'en como monitorizar otro tipo de
+     valores, como la temperatura. La mayor'ia usaremos alguna vez
+     un contador que lleve la cuenta de cuantos octetos (bytes) a
+     transferido un dispositivo de red, as'i que vamos a ver como
+     hacer esto. Empezaremos describiendo como recoger los datos.
+     Hay quien dir'a que hay herramientas que pueden recoger estos
+     datos por ti. ,iEs cierto! Pero, creo que es importante darse
+     cuenta de que no son necesarias. Cuando tienes que
+     determinar porqu'e algo no funciona, necesitas saber c'omo
+     funciona en primer lugar.
+
+     Una herramienta que mencionamos brevemente al principio del
+     documento es SNMP. SNMP es una forma de comunicarse con tus
+     equipos.  La herramienta particular que voy a usar m'as
+     adelante se llama ``snmpget'', y funciona as'i:
+
+        snmpget dispositivo clave OID
+
+     En "dispositivo" colocas el nombre o direcci'on IP del equipo
+     a monitorizar. En clave, colocas la "cadena de caracteres de
+     la comunidad de lectura", como se le denomina en el mundillo
+     SNMP.  Muchos dispositivos aceptar'an "public" como cadena
+
+
+
+2001-02-20             Last change: 1.0.33                     11
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     por defecto, pero por razones de privacidad y seguridad esta
+     clave puede estar deshabilitada. Consulta la documentaci'on
+     correspondiente al dispositivo o programa.
+
+     Luego esta el tercer par'ametro, llamado OID (Object
+     IDentifier, identificador de objeto).
+
+     Al principio, cuando empiezas a aprender sobre SNMP, parece
+     muy confuso. No lo es tanto cuando le hechas una ojeada a
+     los ``MIB'' (Manager Information Base, o Base de Informaci'on
+     Administrativa). Es un 'arbol invertido que describe los
+     datos, empezando en un nodo ra'iz desde el que parten varias
+     ramas.  Cada rama termina en otro nodo y puede abrir nuevas
+     sub-ramas. Cada rama tiene un nombre, y forman un camino que
+     nos lleva hasta el fondo del 'arbol. En este ejemplo, las
+     ramas que vamos a tomar se llaman iso, org, dod, internet,
+     mgmt y mib-2. Tambi'en pueden accederse por su n'umero
+     relativo; en este caso, estos n'umeros son 1, 3, 6, 1, 2 y 1:
+
+        iso.org.dod.internet.mgmt.mib-2 (1.3.6.1.2.1)
+
+     En algunos programas se usa un punto al iniciar el OID. Esto
+     puede ser confuso; no hay ning'un punto inicial en la
+     especificaci'on de los OID... sin embargo, algunos programas
+     usan por defecto un prefijo inicial. Para indicar la
+     diferencia entre los OID abreviados (o sea, a los que se le
+     pondr'a el prefijo inicial) y los completos, estos programas
+     necesitan que los OID completos empiecen por un punto. Para
+     empeorar las cosas, se usan varios prefijos distintos...
+
+     De acuerdo, sigamos con el inicio de nuestro OID: ten'iamos
+     1.3.6.1.2.1 . Ahora, nos interesa la rama ``interfaces'',
+     que tiene el n'umero dos (o sea, 1.3.6.1.2.1.2, o
+     1.3.6.1.2.1.interfaces).
+
+     Lo primero es hacernos con un programa SNMP. Busca alg'un
+     paquete pre-compilado para tu plataforma, si no, puedes
+     buscar el c'odigo fuente y compilarlo tu mismo. En Internet
+     encontrar'as muchos programas, b'uscalos con un motor de
+     b'usqueda o como prefieras.  Mi sugerencia es que busques el
+     paquete CMU-SNMP, que esta bastante difundido.
+
+     Asumamos que ya tienes el programa. Empecemos por tomar
+     ciertos datos que est'an disponibles en la mayor'ia de los
+     sistemas. Recuerda: hay un nombre abreviado para la parte
+     del 'arbol que m'as nos interesa.
+
+     Voy a usar la versi'on corta, ya que creo que este documento
+     ya es lo bastante largo. Si no te funciona, a~n'adele el
+     prefijo .1.3.6.1.2.1 y prueba de nuevo. O prueba leyendo el
+     manual; s'altate las partes que no entiendas a'un, y busca las
+     secciones que hablan de como arrancar y usar el programa.
+
+
+
+2001-02-20             Last change: 1.0.33                     12
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+        snmpget myrouter public system.sysdescr.0
+
+     El dispositivo deber'a contestarte con una descripci'on,
+     probablemente vac'ia, de s'i mismo. Si no consigues una
+     respuesta v'alida, prueba con otra "clave" u otro
+     dispositivo; no podemos seguir hasta tener un resultado.
+
+        snmpget myrouter public interfaces.ifnumber.0
+
+     Con suerte, usando este comando obtendr'as un n'umero como
+     resultado: el n'umero de interfaces del dispositivo. Si es
+     as'i, seguiremos adelante con otro programa, llamado
+     "snmpwalk"
+
+        snmpwalk myrouter public interfaces.iftable.ifentry.ifdescr
+
+     Si obtienes una lista de interfaces, ya casi hemos llegado.
+     Aqu'i tienes un ejemplo del resultado:
+
+        [user at host /home/alex]$ snmpwalk cisco public 2.2.1.2
+        interfaces.ifTable.ifEntry.ifDescr.1 = "BRI0: B-Channel 1"
+        interfaces.ifTable.ifEntry.ifDescr.2 = "BRI0: B-Channel 2"
+        interfaces.ifTable.ifEntry.ifDescr.3 = "BRI0" Hex: 42 52 49 30
+        interfaces.ifTable.ifEntry.ifDescr.4 = "Ethernet0"
+        interfaces.ifTable.ifEntry.ifDescr.5 = "Loopback0"
+
+     En este equipo CISCO, quiero monitorizar la interfaz
+     "Ethernet0".  Viendo que es la cuarta, pruebo con:
+
+        [user at host /home/alex]$ snmpget cisco public 2.2.1.10.4 2.2.1.16.4
+
+        interfaces.ifTable.ifEntry.ifInOctets.4 = 2290729126
+        interfaces.ifTable.ifEntry.ifOutOctets.4 = 1256486519
+
+     Entonces, tengo 2 OIDs que monitorizar, y son (en el formato
+     largo, ahora):
+
+        1.3.6.1.2.1.2.2.1.10
+
+             y
+
+        1.3.6.1.2.1.2.2.1.16
+
+     , ambas con el n'umero de interfaz de 4
+
+     No te enga~nes, esto no lo logre yo al primer intento. Me
+     tom'o un tiempo entender lo que significaban todos estos
+     n'umeros; ayuda cuando se traducen en un texto descriptivo...
+     por lo menos, cuando oigas hablar de MIBs y OIDs, ahora
+     sabr'as de qu'e se trata. No te olvides del n'umero de interfaz
+     (0 si el valor no depende de una interfaz), y prueba con
+     snmpwalk si no obtienes una respuesta clara con snmpget.
+
+
+
+2001-02-20             Last change: 1.0.33                     13
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     Si entendiste todo esto, y obtienes resultados del
+     dispositivo con el que est'as probando, sigue adelante con el
+     tutorial. Si no, vuelve a leer esta secci'on; es importante
+
+     UUUUnnnn eeeejjjjeeeemmmmpppplllloooo rrrreeeeaaaallll
+
+     Ok, empecemos con la diversi'on. Primero, crea una base de
+     datos nueva. Vamos a guardar en ella 2 contadores, "input" y
+     "ouput". Los datos los vamos a guardar en archivos que los
+     promediar'an, tomando grupos de 1, 6, 24 o 288 muestras.
+     Tambi'en archivaremos los valores m'aximos. Lo explicaremos
+     con m'as detalle despu'es. El intervalo de tiempo entre las
+     muestras ser'a de 300 segundos (5 minutos).
+
+      1 muestra "promediada" sigue siendo 1 muestra cada 5 minutos
+      6 muestras promediadas son un promedio de cada 30 minutos
+      24 muestras promediadas son un promedio de cada 2 horas
+      288 muestras promediadas son un promedio de cada d'ia
+
+     Vamos a tratar de ser compatibles con MRTG, que guarda m'as o
+     menos esta cantidad de datos:
+
+      600 muestras de 5 minutos:          2 d'ias y 2 horas
+      600 promedios de 30 minutos:        12.5 d'ias
+      600 promedios de 2 horas:           50 d'ias
+      600 promedios de 1 d'ia:             732 d'ias
+
+     Uniendo todos estos rangos tenemos que en total guardamos
+     datos de unos 797 d'ias. RRDtool guarda los datos de una
+     forma distinta a MRTG; no empieza el archivo "semanal" donde
+     acaba el "diario", sino que ambos archivos contienen la
+     informaci'on m'as reciente, ,ipor lo que con RRDtool archivamos
+     m'as datos que con MRTG!
+
+     Necesitaremos:
+
+      600 muestras de 5 minutos    (2 d'ias y 2 horas)
+      700 entradas de 30 minutos   (2 d'ias y 2 horas, m'as 12.5 d'ias)
+      775 entradas de 2 horas      (lo anterior + 50 d'ias)
+      797 entradas de 1 d'ia        (lo anterior + 732 d'ias, redondeando)
+
+        rrdtool create myrouter.rrd         \
+                 DS:input:COUNTER:600:U:U   \
+                 DS:output:COUNTER:600:U:U  \
+                 RRA:AVERAGE:0.5:1:600      \
+                 RRA:AVERAGE:0.5:6:700      \
+                 RRA:AVERAGE:0.5:24:775     \
+                 RRA:AVERAGE:0.5:288:797    \
+                 RRA:MAX:0.5:1:600          \
+                 RRA:MAX:0.5:6:700          \
+                 RRA:MAX:0.5:24:775         \
+                 RRA:MAX:0.5:288:797
+
+
+
+2001-02-20             Last change: 1.0.33                     14
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     Lo siguiente es recoger los datos y guardarlos, como en el
+     ejemplo siguiente. Esta parcialmente en pseudo-c'odigo, por
+     lo que tendr'as que buscar exactamente como hacerlo funcionar
+     en tu sistema operativo.
+
+        mientras no sea el fin del universo
+        hacer
+           tomar el resultado de
+               snmpget router community 2.2.1.10.4
+           en la variable $in
+           tomar el resultado de
+               snmpget router community 2.2.1.16.4
+           en la variable $out
+           rrdtool update myrouter.rrd N:$in:$out
+           esperar 5 minutos
+        hecho
+
+     Luego, tras recoger datos por un d'ia, crea una imagen,
+     usando:
+
+        rrdtool graph myrouter-day.gif --start -86400 \
+                 DEF:inoctets=myrouter.rrd:input:AVERAGE \
+                 DEF:outoctets=myrouter.rrd:output:AVERAGE \
+                 AREA:inoctets#00FF00:"In traffic" \
+                 LINE1:outoctets#0000FF:"Out traffic"
+
+     Este comando debe producir un gr'afico del tr'afico del d'ia.
+     Un d'ia son 24 horas, de 60 minutos, de 60 segundos:
+     24*60*60=86400, o sea que empezamos a "ahora" menos 86400
+     segundos. Definimos (con los DEFs) "inoctets" y "outoctets"
+     como los valores promedio de la base da datos myrouter.rrd,
+     dibujando un 'area para el tr'afico de entrada y una l'inea
+     para el tr'afico de salida.
+
+     Mira la imagen y sigue recogiendo datos por unos cuantos
+     d'ias. Si lo deseas, puedes probar con los ejemplos de la
+     base de datos de pruebas y ver si puedes hacer trabajar las
+     diversas opciones y operaciones.
+
+     Sugerencia:
+
+     Haz un gr'afico que muestre el tr'afico en bytes por segundo y
+     en bits por segundo. Colorea el tr'afico Ethernet rojo si
+     sobrepasa los cuatro megabits por segundo.
+
+     FFFFuuuunnnncccciiiioooonnnneeeessss ddddeeee ccccoooonnnnssssoooolllliiiiddddaaaacccciiii''oo''oonnnn
+
+     Unos cuantos p'arrafos atr'as habl'abamos sobre la posibilidad
+     de guardar el valor m'aximo en vez del promedio.
+     Profundicemos un poco en este tema.
+
+
+
+
+
+2001-02-20             Last change: 1.0.33                     15
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     Recordemos lo que habl'abamos sobre la velocidad de un coche.
+     Supongamos que manejamos a 144 KM/H durante 5 minutos y
+     luego nos detiene la polic'ia durante unos 25 minutos. Al
+     finalizar el rega~no, tomamos nuestro port'atil y creamos una
+     imagen desde nuestra base de datos. Si visualizamos la
+     segunda RRA que creamos, tendremos el promedio de 6
+     muestreos. Las velocidades registradas serian
+     144+0+0+0+0+0=144, lo que en promedio nos da una velocidad
+     de 24 KM/H., con lo que nos igual nos pondr'ian una multa,
+     s'olo que no por exceso de velocidad.
+
+     Obviamente, en este caso, no deber'iamos tomar en cuenta los
+     promedios. Estos son 'utiles en varios casos. Por ejemplo, si
+     queremos ver cuantos KM hemos viajado, este ser'ia el gr'afico
+     m'as indicado. Pero por otro lado, para ver la velocidad ha
+     la que hemos viajado, los valores m'aximos son m'as adecuados.
+
+     Es lo mismo con los datos que recogemos. Si quieres saber la
+     cantidad total, mira los promedios. Si quieres ver la
+     velocidad, mira los m'aximos. Con el tiempo, ambas cantidades
+     se separan cada vez m'as.  En la 'ultima base de datos que
+     creamos, hab'ia dos archivos que guardaban los datos de cada
+     d'ia. El archivo que guarda los promedios mostrar'a valores
+     bajos, mientras que el de m'aximos mostrar'a valores m'as
+     altos. Para mi coche, mostrar'ia valores promedio de 96/24=4
+     KM/H (viajo unos 96 kil'ometros por d'ia), y m'aximos de 1220
+     KM/H (la velocidad m'axima que alcanzo cada d'ia)
+
+     Como ves, una gran diferencia. No mires el segundo gr'afico
+     para estimar la distancia que recorro, ni al primero para
+     estimar la velocidad a la que voy. Esto s'olo funciona con
+     muestras muy cercanas, pero no si sacas promedios.
+
+     Algunas veces, hago un viaje largo. Si hago un recorrido por
+     Europa, conduciendo por unas 12 horas, el primer gr'afico
+     subir'a a unos 60 KM/H. El segundo mostrar'a unos 180 KM/H.
+     Esto significa que recorr'i unos 60 KM/H por 24 horas = 1440
+     KM. Muestra adem'as que fui a una velocidad promedio mayor a
+     la normal y a un m'aximo de 180 KM/H, ,ino que fui 8 horas a
+     una velocidad fija de 180 KM/H! Este es un ejemplo real:
+     tengo que seguir la corriente en las autopistas de Alemania,
+     detenerme por gasolina y caf'e de vez en cuando, manejar m'as
+     lentamente por Austria y Holanda, e ir con cuidado en las
+     monta~nas y las villas. Si vi'eramos los gr'aficos de los
+     promedios de cada 5 minutos, la imagen ser'ia completamente
+     distinta; ver'iamos los mismos valores de promedio y de
+     m'axima. (suponiendo que las mediciones fueran cada 300
+     segundos). Se podr'ia ver cuando par'e, cuando iba en primera,
+     cuando iba por las autopistas, etc. La granularidad de los
+     datos es m'as alta, por lo que se tiene m'as informaci'on. Sin
+     embargo, esto nos lleva unas 12 muestras por hora, o 288 al
+     d'ia, lo cual es mucho para guardar por un periodo de tiempo
+
+
+
+2001-02-20             Last change: 1.0.33                     16
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     largo. Por lo tanto, sacamos el promedio, guardando
+     eventualmente un solo valor por d'ia.  Con este 'unico valor,
+     no podemos ver mucho.
+
+     Es importante comprender lo que expuesto en estos 'ultimos
+     p'arrafos.  Unos ejes y unas l'ineas no tienen ning'un valor
+     por si mismos; hay que saber que representan e interpretar
+     correctamente los valores obtenidos. Sean cuales sean los
+     datos, esto siempre ser'a cierto.
+
+     El mayor error que puedes cometer es usar los datos
+     recogidos para algo para lo cual no sirven. En ese caso,
+     seria hasta mejor no tener gr'afico alguno.
+
+     RRRReeeeppppaaaasssseeeemmmmoooossss lllloooo qqqquuuueeee ssssaaaabbbbeeeemmmmoooossss
+
+     Ahora ya sabes como crear una base de datos. Puedes guardar
+     valores en ella, extraerlos creando un gr'afico, hacer
+     operaciones matem'aticas con ellos desde la base de datos y
+     visualizar los resultados de estas en vez de los datos
+     originales. Vimos la diferencia entre los promedios y los
+     m'aximos y cuando debemos usar cada uno (o al menos una idea
+     de ello)
+
+     RRDtool puede hacer m'as de lo que hemos visto hasta ahora.
+     Pero antes de continuar, te recomiendo que releas el texto
+     desde el principio y pruebes a hacerle algunas
+     modificaciones a los ejemplos.  Aseg'urate de entenderlo
+     todo. El esfuerzo valdr'a la pena, y te ayudar'a, no s'olo con
+     el resto del documento, sino en tu trabajo diario de
+     monitorizaci'on, mucho despu'es de terminar con esta
+     introducci'on.
+
+     TTTTiiiippppoooossss ddddeeee ffffuuuueeeennnntttteeeessss ddddeeee ddddaaaattttoooossss
+
+     De acuerdo, quieres continuar. Bienvenido de vuelta otra vez
+     y prep'arate; voy a ir m'as r'apido con los ejemplos y
+     explicaciones.
+
+     Ya vimos que, para ver el cambio de un contador a lo largo
+     del tiempo, tenemos que tomar dos n'umeros y dividir la
+     diferencia entre el tiempo transcurrido entre las
+     mediciones. Para los ejemplos que hemos visto es lo l'ogico,
+     pero hay otras posibilidades. Por ejemplo, mi enrutador me
+     puede dar la temperatura actual en tres puntos distintos, la
+     entrada de aire, el llamado "punto caliente" y la salida de
+     ventilaci'on. Estos valores no son contadores; si tomo los
+     valores de dos muestreos y lo divido entre 300 segundos,
+     obtendr'e el cambio de temperatura por segundo. ,iEsperemos
+     que sea cero, o tendr'iamos un incendio en el cuarto de
+     ordenadores! :)
+
+
+
+
+2001-02-20             Last change: 1.0.33                     17
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     Entonces, 'cque hacemos? Podemos decirle a RRDtool que guarde
+     los valores tal como los medimos (esto no es exactamente
+     as'i, pero se aproxima bastante a la verdad). As'i, los
+     gr'aficos se ver'an mucho mejor. Puedo ver cuando el enrutador
+     est'a trabajando m'as (en serio, funciona; como usa m'as
+     electricidad, genera m'as calor y sube la temperatura), puedo
+     saber cuando me he dejado las puertas abiertas (el cuarto de
+     ordenadores tiene aire acondicionado; con las puertas
+     abiertas el aire caliente del resto del edificion entra y
+     sube la temperatura en la entrada de aire del enrutador),
+     etc. Antes usamos un tipo de datos de "contador", ahora
+     usaremos un tipo de datos diferente, con un nombre
+     diferente, GAUGE.  Tenemos otros tipos:
+
+      - COUNTER este ya lo conocemos
+      - GAUGE   este acabamos de verlo
+      - DERIVE
+      - ABSOLUTE
+
+     Los otros dos tipos son DERIVE y ABSOLUTE. ABSOLUTE puede
+     usarse igual que COUNTER, con una diferencia; RRDtool asume
+     que el contador se reinicia cada vez que se lee. O en otras
+     palabras; el delta entre los valores no hay que calcularlo,
+     mientras que con COUNTER RRDtool tiene que sacar 'el la
+     cuenta. Por ejemplo, nuestro primer ejemplo, (12345, 12357,
+     12363, 12363), ser'ia (unknown, 12, 6, 0) en ABSOLUTE.  El
+     otro tipo, DERIVE, es como COUNTER, pero al contrario de
+     COUNTER, este valor tambi'en puede decrecer, por lo que puede
+     tenerse un delta negativo.
+
+     Vamos a probarlos todos:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2001-02-20             Last change: 1.0.33                     18
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+        rrdtool create all.rrd --start 978300900 \
+                 DS:a:COUNTER:600:U:U \
+                 DS:b:GAUGE:600:U:U \
+                 DS:c:DERIVE:600:U:U \
+                 DS:d:ABSOLUTE:600:U:U \
+                 RRA:AVERAGE:0.5:1:10
+        rrdtool update all.rrd \
+                 978301200:300:1:600:300    \
+                 978301500:600:3:1200:600   \
+                 978301800:900:5:1800:900   \
+                 978302100:1200:3:2400:1200 \
+                 978302400:1500:1:2400:1500 \
+                 978302700:1800:2:1800:1800 \
+                 978303000:2100:4:0:2100    \
+                 978303300:2400:6:600:2400  \
+                 978303600:2700:4:600:2700  \
+                 978303900:3000:2:1200:3000
+        rrdtool graph all1.gif -s 978300600 -e 978304200 -h 400 \
+                 DEF:linea=all.rrd:a:AVERAGE LINE3:linea#FF0000:"Line A" \
+                 DEF:lineb=all.rrd:b:AVERAGE LINE3:lineb#00FF00:"Line B" \
+                 DEF:linec=all.rrd:c:AVERAGE LINE3:linec#0000FF:"Line C" \
+                 DEF:lined=all.rrd:d:AVERAGE LINE3:lined#000000:"Line D"
+
+
+     RRRRRRRRDDDDttttoooooooollll bbbbaaaajjjjoooo eeeellll mmmmiiiiccccrrrroooossssccccooooppppiiiioooo
+
+     +o   La l'inea A es un contador, por lo que debe incrementarse
+         continuamente y RRDtool tiene que calcular las
+         diferencias. Adem'as RRDtool tiene que dividir la
+         diferencia entre el tiempo transcurrido. Esto deber'ia
+         terminar con una l'inea recta en 1 (los deltas son 300, y
+         los intervalos son de 300)
+
+     +o   La l'inea B es de tipo GAUGE. Estos son los valores
+         "reales", as'i que el gr'afico debe mostrar lo mismo que
+         los valores que introducimos: una especie de onda
+
+     +o   La l'inea C es de tipo DERIVE. Es un contador, y puede
+         decrecer. Va entre 2400 y 0, con 1800 en el medio.
+
+     +o   La l'inea D es de tipo ABSOLUTE. Esto es, es un contador
+         pero no hay que calcular las diferencias. Los n'umeros
+         son iguales a la l'inea A, y espero que puedas ver la
+         diferencia en los gr'aficos.
+
+     Esto equivale a los valores siguientes, empezando a las
+     23:10 y terminando a las 00:10 (las U significan
+     desconocido).
+
+
+
+
+
+
+
+2001-02-20             Last change: 1.0.33                     19
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+      - L'inea  A:  u  u  1  1  1  1  1  1  1  1  1  u
+      - L'inea  B:  u  1  3  5  3  1  2  4  6  4  2  u
+      - L'inea  C:  u  u  2  2  2  0 -2 -6  2  0  2  u
+      - L'inea  D:  u  1  2  3  4  5  6  7  8  9 10  u
+
+     Si tu archivo GIF muestra todo esto, has entrado los datos
+     correctamente, tu programa RRDtool est'a funcionando bien, el
+     visor de gr'aficos no te enga~na y hemos entrado en el 2000
+     sin problemas :) Puedes probar el mismo ejemplo cuatro
+     veces, una por cada l'inea.
+
+     Revisemos los datos otra vez:
+
+     +o   L'inea A: 300, 600, 900 , etc.  La diferencia del
+         contador es siempre 300, igual que el intervalo de
+         tiempo transcurrido entre mediciones. Por lo tanto, el
+         promedio siempre es 1. Pero, 'cpor qu'e el primer punto
+         tiene un valor de "desconocido"? 'cAcaso no era conocido
+         el valor que pusimos en la base de datos? ,iSi! Pero no
+         ten'iamos un valor inicial para calcular la diferencia.
+         Ser'ia un error asumir que el contador empezaba en 0, as'i
+         que no conocemos el valor de la diferencia
+
+     +o   L'inea B: No hay nada que calcular, los valores son los
+         mismos que se introdujeron en la base de datos.
+
+     +o   L'inea C: De nuevo, no conocemos el valor inicial antes
+         de la primera medici'on, as'i que se aplica el mismo
+         razonamiento que para la l'inea A. En este caso las
+         diferencias no son constantes, as'i que la l'inea no es
+         recta. Si hubi'esemos puesto los mismos valores que en la
+         l'inea A, el gr'afico ser'ia el mismo. Al contrario que
+         COUNTER, el valor puede decrecer, y espero mostrarte m'as
+         adelante el por que de la diferencia entre ambos tipos.
+
+     +o   L'inea D: En este caso, el dispositivo nos da las
+         diferencias por s'i mismo. Por lo tanto, conocemos la
+         diferencia inicial, y podemos graficarla. Tenemos los
+         mismos valores que en la l'inea A, pero su significado es
+         distinto, por lo que el gr'afico tambi'en lo es. En este
+         caso, las diferencias se incrementan en 300 cada vez,
+         mientras que el intervalo de tiempo permanece constante
+         en 300 segundos, por lo que la divisi'on nos da
+         resultados cada vez mayores.
+
+     RRRReeeeiiiinnnniiiicccciiiiaaaalllliiiizzzzaaaacccciiii''oo''oonnnn ddddeeee lllloooossss ccccoooonnnnttttaaaaddddoooorrrreeeessss
+
+     Todav'ia nos quedan algunas cosas por ver. Nos quedan algunas
+     opciones importantes por cubrir, y aun no hemos hablado de
+     la reinicializaci'on de contadores. Empecemos por ah'i:
+     Estamos en nuestro coche, vemos el contador y muestra
+     999987. Andamos unos 20 KM, as'i que el contador debe subir a
+
+
+
+2001-02-20             Last change: 1.0.33                     20
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     1000007. Desafortunadamente, el contador s'olo tiene 6
+     d'igitos, as'i que en realidad nos muestra 000007. Si
+     estuvi'eramos guardando los valores en un tipo DERIVE, esto
+     significar'ia que el contador retrocedi'o unos 999980 KM. Por
+     supuesto esto no es cierto, por lo que necesitamos alguna
+     protecci'on contra estos casos. Esta protecci'on s'olo la
+     tenemos para el tipo COUNTER, el cual de todas formas era el
+     que ten'iamos que haber usado para este tipo de contador.
+     'cC'omo funciona? Los valores tipo COUNTER no deben decrecer
+     nunca, ,ipor lo que RRDtool asume en ese caso que el contador
+     se ha reinicializado! Si la diferencia es negativa, esto se
+     compensa sumando el valor m'aximo del contador + 1. Para
+     nuestro coche, tendr'iamos:
+
+      Delta = 7 - 999987 = -999980    (en vez de 1000007-999987=20)
+
+      Delta real= -999980 + 999999 + 1 = 20
+
+     Al momento de escribir este documento, RRDtool maneja
+     contadores de 32 o 64 bits de tama~no. Estos contadores
+     pueden manejar los siguientes valores:
+
+      - 32 bits: 0 ..           4294967295
+      - 64 bits: 0 .. 18446744073709551615
+
+     Si estos valores te parecen raros, podemos verlos en formato
+     hexadecimal:
+
+      - 32 bits: 0 ..         FFFFFFFF
+      - 64 bits: 0 .. FFFFFFFFFFFFFFFF
+
+     RRDtool maneja ambos contadores de la misma manera. Si
+     ocurre un desbordamiento y la diferencia es negativa,
+     RRDtool le suma primero el m'aximo del contador "menor" (32
+     bits) + 1 a la diferencia. Si a'un as'i la diferencia es
+     negativa, entonces el contador reinicializado era mayor (64
+     bits), por lo que se le suma el valor m'aximo del contador
+     "largo" + 1 y se le resta el m'aximo del contador "peque~no"
+     que sumamos err'oneamente. Hay un problema con esto:
+     supongamos que un contador largo se ha reinicializado al
+     sum'arsele una diferencia muy grande; entonces es posible que
+     al a~nadir el valor m'aximo del contador peque~no la diferencia
+     nos d'e positivo. En este caso poco probable, los valores
+     resultantes no serian correctos. Para que ocurra esto, el
+     incremento tiene que ser casi tan grande como el valor
+     m'aximo del contador, por lo que de ocurrir es muy probable
+     que halla varios problemas m'as en la configuraci'on y no
+     merezca la pena preocuparse s'olo por este. A'un as'i, he
+     incluido un ejemplo de este caso para que lo puedas juzgar
+     por ti mismo.
+
+
+
+
+
+2001-02-20             Last change: 1.0.33                     21
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     A continuaci'on, unos ejemplos de reinicializaci'on de los
+     contadores. Prueba de hacer los c'alculos por ti mismo, o
+     acepta mis resultados si tu calculadora no puede con los
+     n'umeros :)
+
+     N'umeros de correcci'on:
+
+      - 32 bits: (4294967295+1) =                                 4294967296
+      - 64 bits: (18446744073709551615+1)-correction1 = 18446744069414584320
+
+      Antes:          4294967200
+      Incremento:            100
+      Deber'ia ser:    4294967300
+      Pero es:                 4
+      Diferencia:    -4294967196
+      Correcci'on #1: -4294967196 + 4294967296 = 100
+
+      Antes:          18446744073709551000
+      Incremento:                      800
+      Deber'ia ser:    18446744073709551800
+      Pero es:                         184
+      Diferencia:    -18446744073709550816
+      Correcci'on #1: -18446744073709550816 +4294967296 = -18446744069414583520
+      Correcci'on #2: -18446744069414583520 +18446744069414584320 = 800
+
+      Antes:          18446744073709551615 ( valor m'aximo )
+      Incremento:     18446744069414584320 ( incremento absurdo,
+      Deber'ia ser:    36893488143124135935   m'inimo para que
+      Pero es:        18446744069414584319   funcione el ejemplo)
+      Diferencia:              -4294967296
+      Correcci'on #1:  -4294967296 + 4294967296 = 0 (positivo,
+                                                    por tanto no se hace
+                                                    la segunda correcci'on)
+
+      Antes:          18446744073709551615 ( valor m'aximo )
+      Incremento:     18446744069414584319
+      Deber'ia ser:    36893488143124135934
+      Pero es:        18446744069414584318
+      Diferencia:              -4294967297
+      Correcci'on #1:  -4294967297 +4294967296 = -1
+      Correcci'on #2:  -1 +18446744069414584320 = 18446744069414584319
+
+     Como puede verse en los 'ultimos ejemplos, necesitas unos
+     valores bastante extra~nos para hacer que RRDtool falle
+     (asumiendo que no tenga ning'un error el programa, por
+     supuesto), as'i que esto no deber'ia ocurrir. Sin embargo,
+     SNMP o cualquier otro m'etodo que uses de recogida de datos
+     puede tambi'en reportar alg'un valor err'oneo ocasionalmente.
+     No podemos prevenir todos los errores, pero podemos tomar
+     algunas medidas. El comando "create" de RRDtool tiene dos
+     par'ametros especialmente para esto, que definen los valores
+     m'inimo y m'aximo permitidos. Hasta ahora hemos usado "U",
+
+
+
+2001-02-20             Last change: 1.0.33                     22
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+     "desconocido". Si le pasas valores para uno o ambos
+     par'ametros y RRDtool recibe un valor fuera de esos l'imites,
+     los ignorar'a. Para un term'ometro en grados Celsius, el
+     m'inimo absoluto es -273. Para mi enrutador, puedo asumir que
+     ese m'inimo es mucho mayor, digamos que 10.  La temperatura
+     m'axima la pondr'ia en unos 80 grados; m'as alto y el aparato
+     no funcionar'ia. Para mi coche, nunca esperar'ia obtener
+     valores negativos, y tampoco esperar'ia valores mayores a
+     230.  Cualquier otra cosa ser'ia un error. Pero recuerda, lo
+     contrario no es cierto: si los valores pasan este examen no
+     quiere decir que sean los correctos. Siempre examina bien el
+     gr'afico si los valores parecen extra~nos.
+
+     RRRReeeemmmmuuuueeeessssttttrrrreeeeoooo ddddeeee lllloooossss ddddaaaattttoooossss
+
+     Hay una funcionalidad importante de RRDtool que no hemos
+     explicado todav'ia: es virtualmente imposible recoger los
+     datos y pasarselos a RRDtool a intervalos exactos de tiempo.
+     Por tanto, RRDtool interpola los datos a los intervalos
+     exactos. Si no sabes que significa esto o como se hace, he
+     aqu'i la ayuda que necesitas:
+
+     Supongamos un contador se incremente exactamente en 1 cada
+     segundo.  Queremos medirlo cada 300 segundos, por lo que
+     deber'iamos tener valores separados exactamente en 300. Sin
+     embargo, por varias circunstancias llegamos unos segundos
+     tarde y el intervalo es 303. La diferencia ser'a por tanto
+     303. Obviamente, RRDtool no debe colocar 303 en la base de
+     datos y dar as'i la impresi'on de que el contador se
+     increment'o 303 en 300 segundos. Aqu'i es donde RRDtool
+     interpola: alter'a el valor 303 al valor que tendr'ia 3
+     segundos antes y guarda 300 en 300 segundos. Digamos que la
+     pr'oxima vez llegamos justo a tiempo; por tanto, el intervalo
+     actual es 297 segundos, por lo que el contador deber'ia ser
+     297. De nuevo, RRDtool altera el valor y guarda 300, como
+     debe ser.
+
+              en RRD                     en realidad
+      tiempo+000:   0 delta="U"    tiempo+000:   0 delta="U"
+      tiempo+300: 300 delta=300    tiempo+300: 300 delta=300
+      tiempo+600: 600 delta=300    tiempo+603: 603 delta=303
+      tiempo+900: 900 delta=300    tiempo+900: 900 delta=297
+
+     Creemos dos bases de datos id'enticas. He escogido el rango
+     de tiempo entre 920805000 y 920805900.
+
+        rrdtool create seconds1.rrd   \
+           --start 920804700          \
+           DS:seconds:COUNTER:600:U:U \
+           RRA:AVERAGE:0.5:1:24
+
+
+
+
+
+2001-02-20             Last change: 1.0.33                     23
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+        para Unix: cp seconds1.rrd seconds2.rrd
+        para DOS: copy seconds1.rrd seconds2.rrd
+        para VMS:  y yo que s'e :)
+
+        rrdtool update seconds1.rrd \
+           920805000:000 920805300:300 920805600:600 920805900:900
+        rrdtool update seconds2.rrd \
+           920805000:000 920805300:300 920805603:603 920805900:900
+
+        rrdtool graph seconds1.gif                       \
+           --start 920804700 --end 920806200             \
+           --height 200                                  \
+           --upper-limit 1.05 --lower-limit 0.95 --rigid \
+           DEF:seconds=seconds1.rrd:seconds:AVERAGE      \
+           CDEF:unknown=seconds,UN                       \
+           LINE2:seconds#0000FF                          \
+           AREA:unknown#FF0000
+        rrdtool graph seconds2.gif                       \
+           --start 920804700 --end 920806200             \
+           --height 200                                  \
+           --upper-limit 1.05 --lower-limit 0.95 --rigid \
+           DEF:seconds=seconds2.rrd:seconds:AVERAGE      \
+           CDEF:unknown=seconds,UN                       \
+           LINE2:seconds#0000FF                          \
+           AREA:unknown#FF0000
+
+     Los dos gr'aficos debe ser iguales.
+
+RRRREEEESSSSUUUUMMMMEEEENNNN
+     Es hora de concluir este documento. Ahora debes conocer lo
+     b'asico como para trabajar con RRDtool y leer la
+     documentaci'on. A'un hay mucho m'as por descubrir acerca de
+     RRDtool, y le encontrar'as; m'as y m'as usos para la
+     herramienta. Con los ejemplos y la herramienta puedes crear
+     f'acilmente muchos gr'aficos; tambi'en puedes usar las
+     interfaces disponibles.
+
+LLLLIIIISSSSTTTTAAAA DDDDEEEE CCCCOOOORRRRRRRREEEEOOOO
+     Recuerda subscribirte a la lista de correo. Aunque no
+     contestes los correos que aparecen en ella, te servir'a de
+     ayuda a ti y a los dem'as.  Mucho de lo que se sobre MRTG (y
+     por tanto sobre RRDtool), lo aprend'i tan s'olo con leer la
+     lista, sin escribir. No hay por que preguntar las preguntas
+     b'asicas, que ya tienen su respuesta en la FAQ (,il'eela!). Con
+     miles de usuarios a lo largo del mundo, siempre hay
+     preguntas que tu puedes responder con lo aprendido en este y
+     otros documentos.
+
+VVVVEEEERRRR TTTTAAAAMMMMBBBBIIII''EE''EENNNN
+     Las p'aginas del manual de RRDtool
+
+
+
+
+
+2001-02-20             Last change: 1.0.33                     24
+
+
+
+
+
+
+rrdtool                                         RRDTUTORIAL.ES(1)
+
+
+
+AAAAUUUUTTTTOOOORRRR
+     Espero que hayas disfrutado con los ejemplos y las
+     descripciones.  Si es as'i, ayuda a otros refiri'endolos a
+     este documento cuando te hagan preguntas b'asicas. No s'olo
+     obtendr'an la respuesta, sino que aprender'an muchas otras
+     cosas.
+
+     Alex van den Bogaerdt <alex at ergens.op.het.net>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2001-02-20             Last change: 1.0.33                     25
+
+
+

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdtune.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdtune.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdtune.txt	Sat Jul 13 21:26:19 2002
@@ -10,10 +10,10 @@
      Database
 
 SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
-     rrrrrrrrddddttttoooooooollll ttttuuuunnnneeee _f_i_l_e_n_a_m_e [--------hhhheeeeaaaarrrrttttbbbbeeeeaaaatttt|----hhhh _d_s-_n_a_m_e:_h_e_a_r_t_b_e_a_t] [----
-     ----mmmmiiiinnnniiiimmmmuuuummmm|----iiii _d_s-_n_a_m_e:_m_i_n] [--------mmmmaaaaxxxxiiiimmmmuuuummmm|----aaaa _d_s-_n_a_m_e:_m_a_x] [--------
-     ddddaaaattttaaaa----ssssoooouuuurrrrcccceeee----ttttyyyyppppeeee|----dddd _d_s-_n_a_m_e:_D_S_T] [--------ddddaaaattttaaaa----ssssoooouuuurrrrcccceeee----
-     rrrreeeennnnaaaammmmeeee|----rrrr _o_l_d-_n_a_m_e:_n_e_w-_n_a_m_e]
+     rrrrrrrrddddttttoooooooollll ttttuuuunnnneeee _f_i_l_e_n_a_m_e [--------hhhheeeeaaaarrrrttttbbbbeeeeaaaatttt|----hhhh _d_s_-_n_a_m_e:_h_e_a_r_t_b_e_a_t]
+     [--------mmmmiiiinnnniiiimmmmuuuummmm|----iiii _d_s_-_n_a_m_e:_m_i_n] [--------mmmmaaaaxxxxiiiimmmmuuuummmm|----aaaa _d_s_-_n_a_m_e:_m_a_x]
+     [--------ddddaaaattttaaaa----ssssoooouuuurrrrcccceeee----ttttyyyyppppeeee|----dddd _d_s_-_n_a_m_e:_D_S_T]
+     [--------ddddaaaattttaaaa----ssssoooouuuurrrrcccceeee----rrrreeeennnnaaaammmmeeee|----rrrr _o_l_d_-_n_a_m_e:_n_e_w_-_n_a_m_e]
 
 DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
      The tune option allows you to alter some of the basic
@@ -31,36 +31,36 @@
      _f_i_l_e_n_a_m_e
              The name of the RRRRRRRRDDDD you want to tune.
 
-     --------hhhheeeeaaaarrrrttttbbbbeeeeaaaatttt|-hhhh _d_s-_n_a_m_e:_h_e_a_r_t_b_e_a_t
+     --------hhhheeeeaaaarrrrttttbbbbeeeeaaaatttt|----hhhh _d_s_-_n_a_m_e:_h_e_a_r_t_b_e_a_t
              modify the _h_e_a_r_t_b_e_a_t of a data source. By setting
              this to a high value the rrd will accept things like
              one value per day ...
 
-     --------mmmmiiiinnnniiiimmmmuuuummmm|-iiii _d_s-_n_a_m_e:_m_i_n
+     --------mmmmiiiinnnniiiimmmmuuuummmm|----iiii _d_s_-_n_a_m_e:_m_i_n
              alter the minimum value acceptable as input from the
              data source.  Setting _m_i_n to 'U' will disable this
              limit.
 
-     --------mmmmaaaaxxxxiiiimmmmuuuummmm|-aaaa _d_s-_n_a_m_e:_m_a_x
+     --------mmmmaaaaxxxxiiiimmmmuuuummmm|----aaaa _d_s_-_n_a_m_e:_m_a_x
              alter the maximum value acceptable as input from the
              data source.  Setting _m_a_x to 'U' will disable this
              limit.
 
-     --------ddddaaaattttaaaa----ssssoooouuuurrrrcccceeee----ttttyyyyppppeeee|-dddd _d_s-_n_a_m_e:_D_S_T
+     --------ddddaaaattttaaaa----ssssoooouuuurrrrcccceeee----ttttyyyyppppeeee|----dddd _d_s_-_n_a_m_e:_D_S_T
              alter the type DDDDSSSSTTTT of a data source.
 
-     [--------ddddaaaattttaaaa----ssssoooouuuurrrrcccceeee----rrrreeeennnnaaaammmmeeee|-rrrr _o_l_d-_n_a_m_e:_n_e_w-_n_a_m_e]
+     [--------ddddaaaattttaaaa----ssssoooouuuurrrrcccceeee----rrrreeeennnnaaaammmmeeee|----rrrr _o_l_d_-_n_a_m_e:_n_e_w_-_n_a_m_e]
              rename a data source
 
 EEEEXXXXAAAAMMMMPPPPLLLLEEEE
-     rrdtool tune data.rrd -h in:100000 -h in:100000 -h in:100000
+     `rrdtool tune data.rrd -h in:100000 -h out:100000 -h
+     through:100000'
 
-     Set the minimum required heartbeat for data sources 'in',
-     'out' and 'through' to 10000 seconds which is a little over
 
 
 
-24/Oct/1999            Last change: 1.0.13                      1
+
+2001-02-20             Last change: 1.0.33                      1
 
 
 
@@ -71,6 +71,8 @@
 
 
 
+     Set the minimum required heartbeat for data sources 'in',
+     'out' and 'through' to 10000 seconds which is a little over
      one day in data.rrd.  This would allow to feed old data from
      mrtg-2.0 right into rrdtool without generating *UNKNOWN*
      entries.
@@ -124,9 +126,7 @@
 
 
 
-
-
-24/Oct/1999            Last change: 1.0.13                      2
+2001-02-20             Last change: 1.0.33                      2
 
 
 

Added: trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.es.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.es.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.es.pod	Sat Jul 13 21:26:19 2002
@@ -0,0 +1,1183 @@
+=head1 NAME
+
+rrdtutorial - Tutorial sobre RRDtool por Alex van den Bogaerdt
+(Traducido al castellano por Jesús Couto Fandiño)
+
+=for html <div align="right">Versión <a href="rrdtutorial.es.pdf">PDF</a></div>
+
+=for html <div align="right"><a href="rrdtutorial.html">Enlish</a></div>
+
+=head1 DESCRIPTION / DESCRIPCIÓN
+
+RRDtool es un programa escrito por Tobias Oetiker con la
+colaboración de muchas personas en diversas partes del mundo. Alex van
+den Bogaerdt escribió este documento para ayudarte a entender que es
+RRDtool y que es lo que puede hacer por ti.
+
+La documentación que viene con RRDtool puede ser demasiado técnica
+para algunos. Este tutorial existe para ayudarte a entender las
+funciones básicas de RRdtool. Debe servirte de preparación para leer la
+documentación, y además explica algunas ideas generales sobre
+estadística, con un enfoque particular hacia las redes.
+
+=head1 TUTORIAL
+
+=head2 Importante
+
+¡Por favor, no te adelantes en la lectura de este documento! Esta
+primera parte explica los fundamentos básicos. Puede ser aburrida,
+pero si te saltas los fundamentos, los ejemplos no te van a tener
+mucho sentido.
+
+=head2 ¿Qué es RRDtool?
+
+RRDtool significa "herramienta de bases de datos en round robin".
+"Round robin" es una técnica que implica un número fijo de datos, y un
+apuntador al elemento más reciente. Piensa en un circulo con unos
+cuantos puntos dibujados alrededor del borde; estos puntos son los
+lugares donde se pueden guardar los datos. Dibuja ahora una flecha
+desde el centro del círculo a uno de los puntos; este es el apuntador.
+Cuando se lee o escribe el dato actualmente apuntado, la flecha se
+mueve al próximo elemento. Como estamos en un círculo, no hay ni
+principio ni fin; siempre puedes seguir, eternamente. Al cabo de un
+tiempo ya se habrán usado todas las posiciones disponibles y el
+proceso empieza a reutilizar las antiguas. De esta forma, la base de datos
+no crece en tamaño y, por lo tanto, no requiere ningún mantenimiento.
+RRDtool trabaja con estas bases de datos en "round-robin", guardando y
+recuperando datos de ellas.
+
+=head2 ¿Qué datos pueden guardarse en una RRD?
+
+Lo que se te ocurra. Debes poder medir algún valor dado en distintos
+momentos en el tiempo y proveer a RRDtool de estos valores. Si puedes
+hacer esto, RRDtool puede guardar los datos. Los valores tienen que
+ser numéricos, pero no necesariamente enteros, como en MRTG.
+
+Muchos ejemplos mencionan SNMP, que es el acrónimo de
+"Simple Network Management Protocol" (Protocolo Simple de
+Administración de Redes). Lo de "simple" se refiere al protocolo - no
+se supone que sea fácil administrar o monitorizar una red. Cuando
+hayas terminado con este documento, deberás saber lo suficiente para
+entender cuando oigas a otros hablar sobre
+SNMP. Por ahora, simplemente considera a
+SNMP como una forma de preguntarle a los dispositivos
+por los valores de ciertos contadores que mantienen. Son estos valores
+de estos contadores los que vamos a almacenar en la RRD.
+
+=head2 ¿Qué puedo hacer con esta herramienta?
+
+RRDtool se deriva de MRTG (Multi Router
+Traffic Grapher, Graficador De Tráfico de Múltiples Enrutadores).
+MRTG empezó como un pequeño script para poder
+graficar el uso de una conexión a la Internet. Luego evolucionó,
+permitiendo graficar otras fuentes de datos, como temperatura,
+velocidad, voltajes, cantidad de páginas impresas, etc... Lo más
+probable es que empieces a usar RRDtool para guardar y procesar datos
+conseguidos a través de SNMP, y que los datos
+sean el número de bytes (o bits) transferidos desde y hacia una red u
+ordenador. RRDtool te permite crear una base de datos, guardar los
+datos en ellas, recuperarlos y crear gráficos en formato GIF o PNG,
+para mostrarlos en un navegador web. Esas imágenes dependen de los
+datos que hayas guardado y pueden, por ejemplo, ser un sumario del
+promedio de uso de la red, o los picos de tráfico que ocurrieron.
+También lo puedes usar para mostrar el nivel de las mareas, la
+radiación solar, el consumo de electricidad, el número de visitantes
+en una exposición en un momento dado, los niveles de ruido cerca del
+aeropuerto, la temperatura en tu lugar de vacaciones favorito, o en
+la nevera, o cualquier otra cosa que te puedas imaginar, mientras
+tengas algún sensor con el cual medir los datos y seas capaz de
+pasarle los números a RRDtool.
+
+=head2 ¿Y si aún tengo problemas después de leer este documento?
+
+Lo primero, ¡léelo otra vez!. Puede que te hayas perdido de algo.
+Si no puedes compilar el código fuente y usas un sistema operativo
+bastante común, casi seguro que no es la culpa de RRDtool.
+Probablemente consigas versiones pre-compiladas por la Internet. Si
+provienen de una fuente confiable, úsalas. Si, por otro lado, el
+programa funciona, pero no te da los resultados que tu esperabas,
+puede ser un problema con la configuración; revísala y
+compárala con los ejemplos.
+
+Hay una lista de correo electrónico y una archivo de la misma. Lee
+la lista durante unas cuantas semanas, y busca en el archivo. Es
+descortés hacer una pregunta sin haber revisado el archivo; ¡puede que
+tu problema ya haya sido resuelto antes! Normalmente ocurre así en todas
+las listas de correo, no sólo esta. Examina la documentación que vino
+con RRDtool para ver donde está el archivo y como usarlo.
+
+Te sugiero que te tomes un momento y te subscribas a la lista ahora
+mismo, enviando un mensaje a rrd-users-request at list.ee.ethz.ch
+con título C<subscribe>. Si eventualmente deseas salirte de la lista,
+envía otro correo a la misma dirección, con título C<unsubscribe>.
+
+=head2 ¿Cómo me vas a ayudar?
+
+Dándote descripciones y ejemplos detallados. Asumimos que el seguir
+las instrucciones en el orden en que se presentan aquí te dará
+suficiente conocimiento  de RRDtool como para que experimentes por tu
+cuenta. Si no funciona a la primera, puede que te hallas saltado algo;
+siguiendo los ejemplos obtendrás algo de experiencia práctica y, lo
+que es más importante, un poco de información sobre como funciona el
+programa.
+
+Necesitarás saber algo sobre números hexadecimales. Si no, empieza
+por leer "bin_dec_hex" antes de continuar.
+
+=head2 Tu primera base de datos en round-robin
+
+En mi opinión, la mejor forma de aprender algo es haciéndolo. ¿Por
+qué no empezamos ya? Vamos a crear una base de datos, poner unos cuantos
+valores en ella y extraerlos después. La salida que obtengas debe ser
+igual a la que aparece en este documento.
+
+Empezaremos con algo fácil, comparando un coche con un enrutador, o
+por decirlo de otra forma, comparando kilómetros con bits y bytes. A
+nosotros nos da lo mismo; son unos números obtenidos en un espacio de tiempo.
+
+Asumamos que tenemos un dispositivo que transfiere bytes desde y
+hacia la Internet. Este dispositivo tiene un contador que empieza en 0
+al encenderse y se incrementa con cada byte transferido. Este contador
+tiene un valor máximo; si ese valor se alcanza y se cuenta un byte
+más, el contador vuelve a empezar desde cero. Esto es exactamente lo
+mismo que pasa con muchos contadores, como el cuentakilómetros del
+coche. En muchas de las disertaciones sobre redes se habla de bits por
+segundo, así que empezaremos por acostumbrarnos a esto. Asumamos que un
+byte son 8 bits y empecemos a pensar en bits y no en bytes. ¡El
+contador, sin embargo, sigue contando en bytes! En el mundo
+SNMP, la mayoría de los contadores tienen una
+longitud de 32 bits. Esto significa que pueden contar desde 0 hasta
+4294967295. Usaremos estos valores en los ejemplos. El dispositivo, cuando 
+le preguntamos, retorna el valor actual del contador. Como sabemos el
+tiempo transcurrido desde la última vez que le preguntamos, sabemos
+cuantos bytes se han transferido C<***en promedio***> por
+segundo. Esto no es muy difícil de calcular; primero en palabras,
+luego en operaciones:
+
+=over 4
+
+=item 1.
+
+Toma el valor actual del contador y réstale el valor anterior
+
+=item 2.
+
+Haz lo mismo con la fecha
+
+=item 3.
+
+Divide el resultado del paso (1) por el resultado del paso (2).
+El resultado es la cantidad de bytes por segundo. Si lo
+multiplicas por ocho obtienes la cantidad de bits por segundo
+
+=back
+
+  bps = (contador_actual - contador_anterior) / (fecha_actual - fecha_anterior) * 8
+
+Para algunos será de ayuda traducir esto a un ejemplo automotor.
+No prueben estas velocidades en la práctica, y si lo hacen, no me
+echen la culpa por los resultados.
+
+Usaremos las siguientes abreviaturas:
+
+ M:    metros
+ KM:   kilómetros (= 1000 metros).
+ H:    horas
+ S:    segundos
+ KM/H: kilómetros por hora
+ M/S:  metros por segundo
+
+
+Vas conduciendo un coche. A las 12:05, miras el contador en el
+salpicadero y ves que el coche ha recorrido 12345
+KM. A las 12:10 vuelves a mirar otra vez, y dice
+12357 KM. Quiere decir, que has recorrido 12
+KM en cinco minutos. Un científico convertiría
+esto en metros por segundos; esto es bastante parecido al problema de
+pasar de bytes transferidos en 5 minutos a bits por segundo.
+
+Viajamos 12 kilómetros, que son 12000 metros. Tardamos 5 minutos, o
+sea 300 segundos. Nuestra velocidad es 12000M / 300S igual a 40 M/S.
+
+También podemos calcular la velocidad en KM/H: 12 veces 5 minutos
+es una hora, así que multiplicando los 12 KM por 12 obtenemos 144
+KM/H. No intentes esto en casa, o por donde vivo :-)
+
+Recuerda que estos números son tan sólo promedios. No hay forma de
+deducir, viendo sólo los números, si fuiste a una velocidad constante.
+Hay un ejemplo más adelante en el tutorial que explica esto.
+
+Espero que entiendas que no hay diferencia entre calcular la
+velocidad en M/S o bps; sólo la forma en que
+recogemos los datos es distinta. Inclusive, la K de kilo en este
+caso es exactamente la misma, ya que en redes k es 1000
+
+Ahora vamos a crear una base de datos en la que guardar todos estos
+interesantes valores. El método a usar para arrancar el programa puede
+variar de un sistema de operación a otro, pero asumamos que lo puedes
+resolver tu mismo en caso que se diferente en el sistema que usas.
+Asegúrate de no sobreescribir ningún archivo en tu sistema al
+ejecutarlo y escribe todo como una sola línea (tuve que partirlo para
+que fuera legible), saltándote todos los caracteres '\'
+
+   rrdtool create test.rrd             \
+            --start 920804400          \
+            DS:speed:COUNTER:600:U:U   \
+            RRA:AVERAGE:0.5:1:24       \
+            RRA:AVERAGE:0.5:6:10
+
+(o sea, escribe: C<rrdtool create test.rrd --start 920804400 DS ...>)
+
+=head2 ¿Qué hemos creado?
+
+Hemos creado una base de datos en round robin llamada test
+(test.rrd), que empieza desde el mediodía del día en que empecé a
+escribir este documento (7 de marzo de 1999). En ella se guarda una
+fuente de datos (DS), llamada "speed", que se
+lee de un contador. En la misma base de datos se guardan dos archivos
+en round robin (RRAs), uno promedia los datos cada vez que se leen (o
+sea, no hay nada que promediar), y mantiene 24 muestras (24 por 5
+minutos = 2 horas de muestras). El otro promedia 6 muestras (media
+hora), y guarda 10 de estos promedios (o sea, 5 horas). Las opciones
+restantes las veremos más adelante.
+
+RRDtool usa un formato de "fecha" especial que viene del mundo de
+UNIX. Estas "fechas" son el número de segundos
+que han pasado desde el primero de enero de 1970, zona UTC. Este
+número de segundos se convierte luego en la fecha local, por lo que
+varia según la franja horaria.
+
+Lo más probable es que tu no vivas en la misma parte del mundo que
+yo, por lo que tu franja horaria será diferente. En los ejemplos,
+cuando mencione horas, puede que no sean las mismas para ti; esto no
+afecta mucho los resultados, sólo tienes que corregir las horas
+mientras lees. Por ejemplo, las 12:05 para mí son las 11:05 para los
+amigos en la Gran Bretaña.
+
+Ahora tenemos que llenar nuestra base de datos con valores. Vamos a
+suponer que leímos estos datos:
+
+ 12:05  12345 KM
+ 12:10  12357 KM
+ 12:15  12363 KM
+ 12:20  12363 KM
+ 12:25  12363 KM
+ 12:30  12373 KM
+ 12:35  12383 KM
+ 12:40  12393 KM
+ 12:45  12399 KM
+ 12:50  12405 KM
+ 12:55  12411 KM
+ 13:00  12415 KM
+ 13:05  12420 KM
+ 13:10  12422 KM
+ 13:15  12423 KM
+
+Llenaremos la base de datos así:
+
+ rrdtool update test.rrd 920804700:12345 920805000:12357 920805300:12363
+ rrdtool update test.rrd 920805600:12363 920805900:12363 920806200:12373
+ rrdtool update test.rrd 920806500:12383 920806800:12393 920807100:12399
+ rrdtool update test.rrd 920807400:12405 920807700:12411 920808000:12415
+ rrdtool update test.rrd 920808300:12420 920808600:12422 920808900:12423
+
+Lo que significa: actualiza nuestra base de datos test con los
+siguientes valores:
+
+ fecha 920804700, valor 12345
+ fecha 920805000, valor 12357
+ 
+ etcétera.
+
+Como ves, pueden introducirse más de un valor en la base de datos
+por ejecución del comando. Yo los agrupo de tres en tres para hacerlo
+legible, pero en realidad el máximo depende del sistema de operación.
+
+Ahora podemos recuperar los datos usando ``rrdtool fetch'':
+
+ rrdtool fetch test.rrd AVERAGE --start 920804400 --end 920809200
+
+Debes obtener esto como salida:
+
+                    speed
+ 
+ 920804400:        NaN
+ 920804700:        NaN
+ 920805000: 4.0000000000e-02
+ 920805300: 2.0000000000e-02
+ 920805600: 0.0000000000e+00
+ 920805900: 0.0000000000e+00
+ 920806200: 3.3333333333e-02
+ 920806500: 3.3333333333e-02
+ 920806800: 3.3333333333e-02
+ 920807100: 2.0000000000e-02
+ 920807400: 2.0000000000e-02
+ 920807700: 2.0000000000e-02
+ 920808000: 1.3333333333e-02
+ 920808300: 1.6666666667e-02
+ 920808600: 6.6666666667e-03
+ 920808900: 3.3333333333e-03
+ 920809200:        NaN
+
+Si no, hay algo mal. Probablemente tu sistema de operación muestre ``NaN''
+de otra forma; representa "Not a Number", o sea "No es un número". Si
+aparece ``U'' o ``UNKN'' o algo parecido, es lo mismo. Si hay alguna otra
+diferencia, probablemente te equivocaste al introducir algún P valor
+(asumiendo que mi tutorial está bien, por supuesto :-). En ese caso, borra
+la base de datos y prueba de nuevo.
+
+Lo que representa exactamente esta salida lo vamos más adelante en el tutorial.
+
+=head2 Hora de hacer algunos gráficos
+
+Prueba este comando:
+
+ rrdtool graph speed.gif                                 \
+         --start 920804400 --end 920808000               \
+         DEF:myspeed=test.rrd:speed:AVERAGE              \
+         LINE2:myspeed#FF0000
+
+Este comando crea speed.gif, un gráfico de los datos desde las
+12:00 hasta las 13:00. Contiene una definición de la variable myspeed
+y define el color como rojo. Notarás que el gráfico no comienza
+exactamente a las 12:00 sino a las 12:05, y es porque no tenemos datos
+suficientes como para calcular el promedio de velocidad antes de ese
+momento. Esto sólo ocurre en caso de que se pierdan algún muestreo, lo
+que esperamos que no debe ocurrir muy a menudo.
+
+Si ha funcionado, ¡felicitaciones!. Si no, revisa qué puede estar mal.
+
+La definición de colores se construye a partir del rojo, verde y
+azul. Especificas cuanto de cada uno de estos componentes vas a usar
+en hexadecimal: 00 significa "nada de este color" y FF significa
+"este color a máxima intensidad". El "color" blanco es la mezcla
+del rojo, verde y azul a toda intensidad:
+FFFFFF; el negro es la ausencia de todos los colores: 000000.
+
+   rojo    #FF0000
+   verde   #00FF00
+   azul    #0000FF
+   violeta #FF00FF     (mezcla de rojo y azul)
+   gris    #555555     (un tercio de cada uno de los colores)
+
+El archivo GIF que acabas de crear puede
+verse con tu visor de archivos de imagen favorito. Los navegadores lo
+mostrarán usando la URL
+``file://el/camino/de/directorios/hasta/speed.gif''
+
+=head2 Gráficos con un poco de matemática
+
+Cuando veas la imagen, notarás que el eje horizontal tiene unas
+etiquetas marcando las 12:10, 12:20, 12:30, 12:40 y 12:50. Los otros
+dos momentos (12:00 y 13:00) no se pueden mostrar bien por falta de datos, así que
+el programa se los salta. El eje vertical muestra el rango de los valores que
+entramos. Introdujimos los kilómetros y luego dividimos entre 300
+segundos, por lo que obtuvimos valores bastante bajos. Para ser
+exactos, el primer valor, 12 (12357-12345), dividido entre 300 da
+0.04, lo que RRDtool muestra como ``40m'', o sea ``40/1000''. ¡La
+``m''' no tiene nada que ver con metros, kilómetros o milímetros!.
+RRDtool no sabe nada de unidades, el sólo trabaja con números, no con
+metros.
+
+Donde nos equivocamos fue en que debimos medir en metros. Así,
+(12357000-12345000)/300 = 12000/300 = 40.
+
+Vamos a corregirlo. Podríamos recrear la base de datos con los
+valores correctos, pero hay una forma mejor: ¡haciendo los cálculos
+mientras creamos el archivo gif!
+
+   rrdtool graph speed2.gif                           \
+      --start 920804400 --end 920808000               \
+      --vertical-label m/s                            \
+      DEF:myspeed=test.rrd:speed:AVERAGE              \
+      CDEF:realspeed=myspeed,1000,*                   \
+      LINE2:realspeed#FF0000
+
+Cuando veas esta imagen, notarás que la ``m'' ha desaparecido, y
+ahora tienes los resultados correctos. Además hemos añadido una
+etiqueta a la imagen. Apartando esto, el archivo GIF es el mismo.
+
+Las operaciones están en la sección del CDEF
+y están escritas en Notación Polaca Inversa (Reverse Polish Notation o
+``RPN''). En palabras, dice: "toma la fuente de
+datos myspeed y el numero 1000, y multiplícalos". No te molestes en
+meterte con RPN todavía, la veremos con más
+detalle más adelante. Además, puede que quieras leer mi tutorial sobre
+los CDEF y el tutorial de Steve Rader sobre RPN, pero primero terminemos con este.
+
+¡Un momento! Si podemos multiplicar los valores por mil, entonces,
+¡también debería ser posible el mostrar la velocidad en kilómetros por
+hora usando los mismos datos!
+
+Para cambiar el valor que medimos en metros por segundo, calculamos
+los metros por hora (valor * 3600) y dividimos entre 1000 para sacar
+los kilómetros por hora. Todo junto hace valor * (3600/1000) == valor
+* 3.6.
+
+Como en nuestra base de datos cometimos un error guardando los
+valores en kilómetros, debemos compensar por ello, multiplicando por
+100, por lo que al aplicar esta corrección nos queda valor * 3600.
+
+Ahora vamos a crear este gif, agreándole un poco más de magia...
+
+   rrdtool graph speed3.gif                           \
+      --start 920804400 --end 920808000               \
+      --vertical-label km/h                           \
+      DEF:myspeed=test.rrd:speed:AVERAGE              \
+      "CDEF:kmh=myspeed,3600,*"                       \
+      CDEF:fast=kmh,100,GT,kmh,0,IF                   \
+      CDEF:good=kmh,100,GT,0,kmh,IF                   \
+      HRULE:100#0000FF:"Maximum allowed"              \
+      AREA:good#00FF00:"Good speed"                   \
+      AREA:fast#FF0000:"Too fast"
+
+Esto luce mucho mejor. La velocidad en KM/H,
+y además tenemos una línea extra mostrando la velocidad máxima
+permitida (en el camino por donde conduzco). También le cambie los
+colores de la velocidad, y ahora paso de ser una línea a un área.
+
+Los cálculos son más complejos ahora. Para calcular la velocidad "aceptable":
+
+   Verifica si la velocidad en kmh es mayor que 100     ( kmh,100 ) GT           
+   Si es así, retorna 0, si no, retorna la velocidad    ((( kmh,100 ) GT ), 0, kmh) IF
+
+Para calcular la parte de velocidad "excesiva":
+
+   Verifica si la velocidad en kmh es mayor que 100     ( kmh,100 ) GT
+   Si es así, retorna la velocidad, si no, retorna 0    ((( kmh,100) GT ), kmh, 0) IF
+
+=head2 Magia gráfica
+
+Me gusta creer que virtualmente no hay limites para lo que RRDtool puede
+hacer con los datos. No voy a explicarlo en detalle, pero mira este GIF:
+
+   rrdtool graph speed4.gif                           \
+      --start 920804400 --end 920808000               \
+      --vertical-label km/h                           \
+      DEF:myspeed=test.rrd:speed:AVERAGE              \
+      "CDEF:kmh=myspeed,3600,*"                       \
+      CDEF:fast=kmh,100,GT,100,0,IF                   \
+      CDEF:over=kmh,100,GT,kmh,100,-,0,IF             \
+      CDEF:good=kmh,100,GT,0,kmh,IF                   \
+      HRULE:100#0000FF:"Maximum allowed"              \
+      AREA:good#00FF00:"Good speed"                   \
+      AREA:fast#550000:"Too fast"                     \
+      STACK:over#FF0000:"Over speed"
+
+Vamos a crear una página HTML simple para ver los tres archivos GIF:
+
+   <HTML><HEAD><TITLE>Velocidad</TITLE></HEAD><BODY>
+   <IMG src="speed2.gif" alt="Speed in meters per second">
+   <BR>
+   <IMG src="speed3.gif" alt="Speed in kilometers per hour">
+   <BR>
+   <IMG src="speed4.gif" alt="Traveled too fast?">
+   </BODY></HTML>
+
+Guárdalo como ``speed.html'' o algo parecido, y examínalo con un navegador.
+
+Ahora, todo lo que tienes que hacer es medir los datos regularmente
+y actualizar la base de datos. Cuando quieras verlos, vuelve a crear
+los archivos GIF y asegúrate que se carguen de nuevo en tu navegador
+(Nota: presionar el botón de "refrescar" puede no ser suficiente; en
+particular, Netscape tiene un problema al respecto, por lo que
+necesitaras darle al botón mientras presionas la tecla de mayúsculas.
+
+=head2 Actualizaciones de verdad
+
+Ya hemos usado el comando ``update''; vimos que recibia uno o más
+parámetros en el formato: ``E<lt>fechaE<gt>:E<lt>valorE<gt>''. Para
+facilitarte las cosas, puedes obtener la fecha actual colocando
+``N'' en la fecha. También podrías usar la función
+``time'' de Perl para obtenerla. El ejemplo más corto de todo el
+tutorial :)
+
+   perl -e 'print time, "\n" '
+
+Ahora, la forma de poner a correr un programa a intervalos
+regulares de tiempo depende del sistema de operación. La
+actualización, en pseudo-código, sería:
+
+   Toma el valor, colócalo en la variable "$speed"
+   rrdtool update speed.rrd N:$speed
+
+(Pero no lo hagas sobre nuestra base de datos de pruebas, que aún
+la vamos a usar en otros ejemplos.
+
+Eso es todo. Ejecutando este script cada 5 minutos, lo único que
+tienes que hacer para ver los gráficos actuales es correr los ejemplos
+anteriores, que también puedes poner en un script. Luego de correrlo,
+basta con cargar index.html
+
+=head2 Unas palabras sobre SNMP
+
+Me imagino que muy pocas personas serán capaces de obtener en su
+ordenador datos reales de su coche cada 5 minutos; los demás nos
+tendremos que conformar con algún otro contador. Puedes, por ejemplo,
+medir la cantidad de páginas que ha hecho una impresora, cuanto café
+has hecho con la cafetera, el medidor del consumo de electricidad, o
+cualquier otra cosa. Cualquier contador incremental puede
+monitorizarse y graficarse con lo que has aprendido hasta ahora. Más
+adelante, veremos también como monitorizar otro tipo de valores, como
+la temperatura. La mayoría usaremos alguna vez un contador que lleve
+la cuenta de cuantos octetos (bytes) a transferido un dispositivo de
+red, así que vamos a ver como hacer esto. Empezaremos describiendo
+como recoger los datos. Hay quien dirá que hay herramientas que pueden
+recoger estos datos por ti. ¡Es cierto! Pero, creo que es importante
+darse cuenta de que no son necesarias. Cuando tienes que determinar
+porqué algo no funciona, necesitas saber cómo funciona en primer lugar.
+
+Una herramienta que mencionamos brevemente al principio del
+documento es SNMP. SNMP es una forma de comunicarse con tus equipos.
+La herramienta particular que voy a usar más adelante se llama
+``snmpget'', y funciona así:
+
+   snmpget dispositivo clave OID
+
+En "dispositivo" colocas el nombre o dirección IP del equipo a
+monitorizar. En clave, colocas la "cadena de caracteres de la
+comunidad de lectura", como se le denomina en el mundillo SNMP.
+Muchos dispositivos aceptarán "public" como
+cadena por defecto, pero por razones de privacidad y seguridad esta
+clave puede estar deshabilitada. Consulta la documentación
+correspondiente al dispositivo o programa.
+
+Luego esta el tercer parámetro, llamado OID
+(Object IDentifier, identificador de objeto).
+
+Al principio, cuando empiezas a aprender sobre SNMP, parece muy
+confuso. No lo es tanto cuando le hechas una ojeada a los
+``MIB'' (Manager Information Base, o Base de
+Información Administrativa). Es un árbol invertido que describe los
+datos, empezando en un nodo raíz desde el que parten varias ramas.
+Cada rama termina en otro nodo y puede abrir nuevas sub-ramas. Cada
+rama tiene un nombre, y forman un camino que nos lleva hasta el fondo
+del árbol. En este ejemplo, las ramas que vamos a tomar se llaman iso,
+org, dod, internet, mgmt y mib-2. También pueden accederse por su
+número relativo; en este caso, estos números son 1, 3, 6, 1, 2 y 1:
+
+   iso.org.dod.internet.mgmt.mib-2 (1.3.6.1.2.1)
+
+En algunos programas se usa un punto al iniciar el OID. Esto puede
+ser confuso; no hay ningún punto inicial en la especificación de los
+OID... sin embargo, algunos programas usan por defecto un prefijo
+inicial. Para indicar la diferencia entre los OID abreviados (o sea, a
+los que se le pondrá el prefijo inicial) y los completos, estos
+programas necesitan que los OID completos empiecen por un punto. Para
+empeorar las cosas, se usan varios prefijos distintos...
+
+De acuerdo, sigamos con el inicio de nuestro OID: teníamos
+1.3.6.1.2.1 . Ahora, nos interesa la rama ``interfaces'', que tiene el
+número dos (o sea, 1.3.6.1.2.1.2, o 1.3.6.1.2.1.interfaces).
+
+Lo primero es hacernos con un programa SNMP. Busca algún 
+paquete pre-compilado para tu plataforma, si no, puedes
+buscar el código fuente y compilarlo tu mismo. En Internet encontrarás
+muchos programas, búscalos con un motor de búsqueda o como prefieras.
+Mi sugerencia es que busques el paquete CMU-SNMP, que esta bastante difundido.
+
+Asumamos que ya tienes el programa. Empecemos por tomar ciertos
+datos que están disponibles en la mayoría de los sistemas. Recuerda:
+hay un nombre abreviado para la parte del árbol que más nos interesa.
+
+Voy a usar la versión corta, ya que creo que este documento ya es
+lo bastante largo. Si no te funciona, añádele el prefijo .1.3.6.1.2.1
+y prueba de nuevo. O prueba leyendo el manual; sáltate las partes que
+no entiendas aún, y busca las secciones que hablan de como arrancar y
+usar el programa.
+
+   snmpget myrouter public system.sysdescr.0
+
+El dispositivo deberá contestarte con una descripción, probablemente
+vacía, de sí mismo. Si no consigues una respuesta válida, prueba con
+otra "clave" u otro dispositivo; no podemos seguir hasta tener un
+resultado.
+
+   snmpget myrouter public interfaces.ifnumber.0
+
+Con suerte, usando este comando obtendrás un número como resultado:
+el número de interfaces del dispositivo. Si es así, seguiremos
+adelante con otro programa, llamado "snmpwalk"
+
+   snmpwalk myrouter public interfaces.iftable.ifentry.ifdescr
+
+Si obtienes una lista de interfaces, ya casi hemos llegado. Aquí
+tienes un ejemplo del resultado:
+
+   [user at host /home/alex]$ snmpwalk cisco public 2.2.1.2   
+   interfaces.ifTable.ifEntry.ifDescr.1 = "BRI0: B-Channel 1"
+   interfaces.ifTable.ifEntry.ifDescr.2 = "BRI0: B-Channel 2"
+   interfaces.ifTable.ifEntry.ifDescr.3 = "BRI0" Hex: 42 52 49 30
+   interfaces.ifTable.ifEntry.ifDescr.4 = "Ethernet0"
+   interfaces.ifTable.ifEntry.ifDescr.5 = "Loopback0"
+
+En este equipo CISCO, quiero monitorizar la interfaz "Ethernet0".
+Viendo que es la cuarta, pruebo con:
+
+   [user at host /home/alex]$ snmpget cisco public 2.2.1.10.4 2.2.1.16.4
+ 
+   interfaces.ifTable.ifEntry.ifInOctets.4 = 2290729126
+   interfaces.ifTable.ifEntry.ifOutOctets.4 = 1256486519
+
+Entonces, tengo 2 OIDs que monitorizar, y son (en el formato largo, ahora):
+
+   1.3.6.1.2.1.2.2.1.10
+ 
+        y
+ 
+   1.3.6.1.2.1.2.2.1.16
+
+, ambas con el número de interfaz de 4
+
+No te engañes, esto no lo logre yo al primer intento. Me tomó un
+tiempo entender lo que significaban todos estos números; ayuda cuando
+se traducen en un texto descriptivo... por lo menos, cuando oigas
+hablar de MIBs y OIDs, ahora sabrás de qué se trata. No te olvides
+del número de interfaz (0 si el valor no depende de una interfaz), y
+prueba con snmpwalk si no obtienes una respuesta clara con snmpget.
+
+Si entendiste todo esto, y obtienes resultados del dispositivo con
+el que estás probando, sigue adelante con el tutorial. Si no, vuelve a
+leer esta sección; es importante
+
+=head2 Un ejemplo real
+
+Ok, empecemos con la diversión. Primero, crea una base de datos
+nueva. Vamos a guardar en ella 2 contadores, "input" y "ouput". Los
+datos los vamos a guardar en archivos que los promediarán, tomando
+grupos de 1, 6, 24 o 288 muestras. También archivaremos los valores
+máximos. Lo explicaremos con más detalle después. El intervalo de
+tiempo entre las muestras será de 300 segundos (5 minutos).
+
+ 1 muestra "promediada" sigue siendo 1 muestra cada 5 minutos
+ 6 muestras promediadas son un promedio de cada 30 minutos
+ 24 muestras promediadas son un promedio de cada 2 horas
+ 288 muestras promediadas son un promedio de cada día
+
+Vamos a tratar de ser compatibles con MRTG, que guarda más o menos
+esta cantidad de datos:
+
+ 600 muestras de 5 minutos:          2 días y 2 horas
+ 600 promedios de 30 minutos:        12.5 días
+ 600 promedios de 2 horas:           50 días
+ 600 promedios de 1 día:             732 días
+
+Uniendo todos estos rangos tenemos que en total guardamos datos de
+unos 797 días. RRDtool guarda los datos de una forma distinta a MRTG;
+no empieza el archivo "semanal" donde acaba el "diario", sino que
+ambos archivos contienen la información más reciente, ¡por lo que con
+RRDtool archivamos más datos que con MRTG!
+
+Necesitaremos:
+
+ 600 muestras de 5 minutos    (2 días y 2 horas)
+ 700 entradas de 30 minutos   (2 días y 2 horas, más 12.5 días)
+ 775 entradas de 2 horas      (lo anterior + 50 días)
+ 797 entradas de 1 día        (lo anterior + 732 días, redondeando)
+
+   rrdtool create myrouter.rrd         \
+            DS:input:COUNTER:600:U:U   \
+            DS:output:COUNTER:600:U:U  \
+            RRA:AVERAGE:0.5:1:600      \
+            RRA:AVERAGE:0.5:6:700      \
+            RRA:AVERAGE:0.5:24:775     \
+            RRA:AVERAGE:0.5:288:797    \
+            RRA:MAX:0.5:1:600          \
+            RRA:MAX:0.5:6:700          \
+            RRA:MAX:0.5:24:775         \
+            RRA:MAX:0.5:288:797
+
+Lo siguiente es recoger los datos y guardarlos, como en el ejemplo
+siguiente. Esta parcialmente en pseudo-código, por lo que tendrás que
+buscar exactamente como hacerlo funcionar en tu sistema operativo.
+
+   mientras no sea el fin del universo
+   hacer
+      tomar el resultado de 
+          snmpget router community 2.2.1.10.4
+      en la variable $in
+      tomar el resultado de
+          snmpget router community 2.2.1.16.4
+      en la variable $out
+      rrdtool update myrouter.rrd N:$in:$out
+      esperar 5 minutos
+   hecho
+
+Luego, tras recoger datos por un día, crea una imagen, usando:
+
+   rrdtool graph myrouter-day.gif --start -86400 \
+            DEF:inoctets=myrouter.rrd:input:AVERAGE \
+            DEF:outoctets=myrouter.rrd:output:AVERAGE \
+            AREA:inoctets#00FF00:"In traffic" \
+            LINE1:outoctets#0000FF:"Out traffic"
+
+Este comando debe producir un gráfico del tráfico del día. Un día
+son 24 horas, de 60 minutos, de 60 segundos: 24*60*60=86400, o sea que
+empezamos a "ahora" menos 86400 segundos. Definimos (con los DEFs)
+"inoctets" y "outoctets" como los valores promedio de la base da datos
+myrouter.rrd, dibujando un área para el tráfico de entrada y una línea
+para el tráfico de salida.
+
+Mira la imagen y sigue recogiendo datos por unos cuantos días. Si
+lo deseas, puedes probar con los ejemplos de la base de datos de
+pruebas y ver si puedes hacer trabajar las diversas opciones y
+operaciones.
+
+Sugerencia:
+
+Haz un gráfico que muestre el tráfico en bytes por segundo y en
+bits por segundo. Colorea el tráfico Ethernet rojo si sobrepasa los
+cuatro megabits por segundo.
+
+=head2 Funciones de consolidación
+
+Unos cuantos párrafos atrás hablábamos sobre la posibilidad de
+guardar el valor máximo en vez del promedio. Profundicemos un poco en
+este tema.
+
+Recordemos lo que hablábamos sobre la velocidad de un coche.
+Supongamos que manejamos a 144 KM/H durante 5
+minutos y luego nos detiene la policía durante unos 25 minutos. Al
+finalizar el regaño, tomamos nuestro portátil y creamos una imagen
+desde nuestra base de datos. Si visualizamos la segunda RRA que
+creamos, tendremos el promedio de 6 muestreos. Las velocidades
+registradas serian 144+0+0+0+0+0=144, lo que en promedio nos da una
+velocidad de 24 KM/H., con lo que nos igual nos
+pondrían una multa, sólo que no por exceso de velocidad.
+
+Obviamente, en este caso, no deberíamos tomar en cuenta los
+promedios. Estos son útiles en varios casos. Por ejemplo, si queremos
+ver cuantos KM hemos viajado, este sería el
+gráfico más indicado. Pero por otro lado, para ver la velocidad ha la
+que hemos viajado, los valores máximos son más adecuados.
+
+Es lo mismo con los datos que recogemos. Si quieres saber la
+cantidad total, mira los promedios. Si quieres ver la velocidad, mira
+los máximos. Con el tiempo, ambas cantidades se separan cada vez más.
+En la última base de datos que creamos, había dos archivos que
+guardaban los datos de cada día. El archivo que guarda los promedios
+mostrará valores bajos, mientras que el de máximos mostrará valores más
+altos. Para mi coche, mostraría valores promedio de 96/24=4 KM/H
+(viajo unos 96 kilómetros por día), y máximos de 1220 KM/H (la
+velocidad máxima que alcanzo cada día)
+
+Como ves, una gran diferencia. No mires el segundo gráfico para
+estimar la distancia que recorro, ni al primero para estimar la
+velocidad a la que voy. Esto sólo funciona con muestras muy cercanas,
+pero no si sacas promedios.
+
+Algunas veces, hago un viaje largo. Si hago un recorrido por
+Europa, conduciendo por unas 12 horas, el primer gráfico subirá
+a unos 60 KM/H. El segundo mostrará unos 180 KM/H. Esto significa que
+recorrí unos 60 KM/H por 24 horas = 1440 KM. Muestra además que fui a
+una velocidad promedio mayor a la normal y a un máximo de 180 KM/H,
+¡no que fui 8 horas a una velocidad fija de 180 KM/H! Este es un
+ejemplo real: tengo que seguir la corriente en las autopistas de
+Alemania, detenerme por gasolina y café de vez en cuando, manejar más
+lentamente por Austria y Holanda, e ir con cuidado en las montañas y
+las villas. Si viéramos los gráficos de los promedios de cada 5
+minutos, la imagen sería completamente distinta; veríamos los mismos
+valores de promedio y de máxima. (suponiendo que las mediciones fueran
+cada 300 segundos). Se podría ver cuando paré, cuando iba en
+primera, cuando iba por las autopistas, etc. La granularidad de los
+datos es más alta, por lo que se tiene más información. Sin embargo,
+esto nos lleva unas 12 muestras por hora, o 288 al día, lo cual es
+mucho para guardar por un periodo de tiempo largo. Por lo tanto,
+sacamos el promedio, guardando eventualmente un solo valor por día.
+Con este único valor, no podemos ver mucho.
+
+Es importante comprender lo que expuesto en estos últimos párrafos.
+Unos ejes y unas líneas no tienen ningún valor por si mismos; hay que
+saber que representan e interpretar correctamente los valores
+obtenidos. Sean cuales sean los datos, esto siempre será cierto.
+
+El mayor error que puedes cometer es usar los datos recogidos para
+algo para lo cual no sirven. En ese caso, seria hasta mejor no tener
+gráfico alguno.
+
+=head2 Repasemos lo que sabemos
+
+Ahora ya sabes como crear una base de datos. Puedes guardar valores
+en ella, extraerlos creando un gráfico, hacer operaciones matemáticas
+con ellos desde la base de datos y visualizar los resultados de estas
+en vez de los datos originales. Vimos la diferencia entre los
+promedios y los máximos y cuando debemos usar cada uno (o al menos una
+idea de ello)
+
+RRDtool puede hacer más de lo que hemos visto hasta ahora. Pero
+antes de continuar, te recomiendo que releas el texto desde el
+principio y pruebes a hacerle algunas modificaciones a los ejemplos.
+Asegúrate de entenderlo todo. El esfuerzo valdrá la pena, y te ayudará,
+no sólo con el resto del documento, sino en tu trabajo diario de
+monitorización, mucho después de terminar con esta introducción.
+
+=head2 Tipos de fuentes de datos
+
+De acuerdo, quieres continuar. Bienvenido de vuelta otra vez y
+prepárate; voy a ir más rápido con los ejemplos y explicaciones.
+
+Ya vimos que, para ver el cambio de un contador a lo largo del
+tiempo, tenemos que tomar dos números y dividir la diferencia entre el
+tiempo transcurrido entre las mediciones. Para los ejemplos que hemos
+visto es lo lógico, pero hay otras posibilidades. Por ejemplo, mi
+enrutador me puede dar la temperatura actual en tres puntos distintos,
+la entrada de aire, el llamado "punto caliente" y la salida de
+ventilación. Estos valores no son contadores; si tomo los valores de
+dos muestreos y lo divido entre 300 segundos, obtendré el cambio de
+temperatura por segundo. ¡Esperemos que sea cero, o tendríamos un
+incendio en el cuarto de ordenadores! :)
+
+Entonces, ¿que hacemos? Podemos decirle a RRDtool que guarde los
+valores tal como los medimos (esto no es exactamente así, pero se
+aproxima bastante a la verdad). Así, los gráficos se verán mucho
+mejor. Puedo ver cuando el enrutador está trabajando más (en serio,
+funciona; como usa más electricidad, genera más calor y sube la
+temperatura), puedo saber cuando me he dejado las puertas abiertas (el
+cuarto de ordenadores tiene aire acondicionado; con las puertas
+abiertas el aire caliente del resto del edificion entra y sube la
+temperatura en la entrada de aire del enrutador), etc. Antes usamos un
+tipo de datos de "contador", ahora usaremos un tipo de datos
+diferente, con un nombre diferente, GAUGE.
+Tenemos otros tipos:
+
+ - COUNTER este ya lo conocemos
+ - GAUGE   este acabamos de verlo
+ - DERIVE
+ - ABSOLUTE
+
+Los otros dos tipos son DERIVE y ABSOLUTE. ABSOLUTE puede usarse
+igual que COUNTER, con una diferencia; RRDtool asume que el contador
+se reinicia cada vez que se lee. O en otras palabras; el delta entre
+los valores no hay que calcularlo, mientras que con COUNTER RRDtool
+tiene que sacar él la cuenta. Por ejemplo, nuestro primer ejemplo,
+(12345, 12357, 12363, 12363), sería (unknown, 12, 6, 0) en ABSOLUTE.
+El otro tipo, DERIVE, es como COUNTER, pero al contrario de COUNTER,
+este valor también puede decrecer, por lo que puede tenerse un delta
+negativo.
+
+Vamos a probarlos todos:
+
+   rrdtool create all.rrd --start 978300900 \
+            DS:a:COUNTER:600:U:U \
+            DS:b:GAUGE:600:U:U \
+            DS:c:DERIVE:600:U:U \
+            DS:d:ABSOLUTE:600:U:U \
+            RRA:AVERAGE:0.5:1:10
+   rrdtool update all.rrd \
+            978301200:300:1:600:300    \
+            978301500:600:3:1200:600   \
+            978301800:900:5:1800:900   \
+            978302100:1200:3:2400:1200 \
+            978302400:1500:1:2400:1500 \
+            978302700:1800:2:1800:1800 \
+            978303000:2100:4:0:2100    \
+            978303300:2400:6:600:2400  \
+            978303600:2700:4:600:2700  \
+            978303900:3000:2:1200:3000
+   rrdtool graph all1.gif -s 978300600 -e 978304200 -h 400 \
+            DEF:linea=all.rrd:a:AVERAGE LINE3:linea#FF0000:"Line A" \
+            DEF:lineb=all.rrd:b:AVERAGE LINE3:lineb#00FF00:"Line B" \
+            DEF:linec=all.rrd:c:AVERAGE LINE3:linec#0000FF:"Line C" \
+            DEF:lined=all.rrd:d:AVERAGE LINE3:lined#000000:"Line D"
+
+=head2 RRDtool bajo el microscopio
+
+=over 4
+
+=item *
+
+La línea A es un contador, por lo que
+debe incrementarse continuamente y RRDtool tiene que calcular las
+diferencias. Además RRDtool tiene que dividir la diferencia entre
+el tiempo transcurrido. Esto debería terminar con una línea recta
+en 1 (los deltas son 300, y los intervalos son de 300)
+
+=item *
+
+La línea B es de tipo GAUGE. Estos son
+los valores "reales", así que el gráfico debe mostrar lo mismo que
+los valores que introducimos: una especie de onda
+Z<>
+
+=item *
+
+La línea C es de tipo DERIVE. Es un
+contador, y puede decrecer. Va entre 2400 y 0, con 1800 en el medio.
+
+=item *
+
+La línea D es de tipo ABSOLUTE. Esto es,
+es un contador pero no hay que calcular las diferencias. Los
+números son iguales a la línea A, y espero
+que puedas ver la diferencia en los gráficos.
+
+=back
+
+Esto equivale a los valores siguientes, empezando a las 23:10 y
+terminando a las 00:10 (las U significan desconocido).
+
+
+ - Línea  A:  u  u  1  1  1  1  1  1  1  1  1  u
+ - Línea  B:  u  1  3  5  3  1  2  4  6  4  2  u
+ - Línea  C:  u  u  2  2  2  0 -2 -6  2  0  2  u
+ - Línea  D:  u  1  2  3  4  5  6  7  8  9 10  u
+
+Si tu archivo GIF muestra todo esto, has
+entrado los datos correctamente, tu programa RRDtool está funcionando
+bien, el visor de gráficos no te engaña y hemos entrado en el 2000 sin
+problemas :) Puedes probar el mismo ejemplo cuatro veces, una por cada línea.
+
+Revisemos los datos otra vez:
+
+=over 4
+
+=item *
+
+Línea A: 300, 600, 900 , etc.
+La diferencia del contador es siempre 300, igual que el intervalo de
+tiempo transcurrido entre mediciones. Por lo tanto, el promedio
+siempre es 1. Pero, ¿por qué el primer punto tiene un valor de
+"desconocido"? ¿Acaso no era conocido el valor que pusimos en la
+base de datos? ¡Si! Pero no teníamos un valor inicial para
+calcular la diferencia. Sería un error asumir que el contador
+empezaba en 0, así que no conocemos el valor de la diferencia
+
+=item *
+
+Línea B: 
+No hay nada que calcular, los valores son los mismos que se
+introdujeron en la base de datos.
+
+=item *
+
+Línea C: 
+De nuevo, no conocemos el valor
+inicial antes de la primera medición, así que se aplica el mismo
+razonamiento que para la línea A. En este
+caso las diferencias no son constantes, así que la línea no es
+recta. Si hubiésemos puesto los mismos valores que en la línea
+A, el gráfico sería el mismo. Al contrario
+que COUNTER, el valor puede decrecer, y espero mostrarte más
+adelante el por que de la diferencia entre ambos tipos.
+
+=item *
+
+Línea D: En este caso, el dispositivo nos
+da las diferencias por sí mismo. Por lo tanto, conocemos la
+diferencia inicial, y podemos graficarla. Tenemos los mismos
+valores que en la línea A, pero su
+significado es distinto, por lo que el gráfico también lo es. En
+este caso, las diferencias se incrementan en 300 cada vez,
+mientras que el intervalo de tiempo permanece constante en 300
+segundos, por lo que la división nos da resultados cada vez mayores.
+
+=back
+
+=head2 Reinicialización de los contadores
+
+Todavía nos quedan algunas cosas por ver. Nos quedan algunas
+opciones importantes por cubrir, y aun no hemos hablado de la
+reinicialización de contadores. Empecemos por ahí: Estamos en nuestro
+coche, vemos el contador y muestra 999987. Andamos unos 20 KM, así que
+el contador debe subir a 1000007. Desafortunadamente, el contador
+sólo tiene 6 dígitos, así que en realidad nos muestra 000007. Si
+estuviéramos guardando los valores en un tipo DERIVE, esto
+significaría que el contador retrocedió unos 999980 KM. Por supuesto
+esto no es cierto, por lo que necesitamos alguna protección contra estos
+casos. Esta protección sólo la tenemos para el tipo COUNTER, el cual
+de todas formas era el que teníamos que haber usado para este tipo de
+contador. ¿Cómo funciona? Los valores tipo COUNTER no deben decrecer
+nunca, ¡por lo que RRDtool asume en ese caso que el contador se ha
+reinicializado! Si la diferencia es negativa, esto se compensa sumando
+el valor máximo del contador + 1. Para nuestro coche, tendríamos:
+
+ Delta = 7 - 999987 = -999980    (en vez de 1000007-999987=20)
+ 
+ Delta real= -999980 + 999999 + 1 = 20
+
+Al momento de escribir este documento, RRDtool maneja contadores de
+32 o 64 bits de tamaño. Estos contadores pueden manejar los siguientes
+valores:
+
+ - 32 bits: 0 ..           4294967295
+ - 64 bits: 0 .. 18446744073709551615
+
+Si estos valores te parecen raros, podemos verlos en formato hexadecimal:
+
+ - 32 bits: 0 ..         FFFFFFFF
+ - 64 bits: 0 .. FFFFFFFFFFFFFFFF
+
+RRDtool maneja ambos contadores de la misma manera. Si ocurre un
+desbordamiento y la diferencia es negativa, RRDtool le suma primero
+el máximo del contador "menor" (32 bits) + 1 a la diferencia. Si aún
+así la diferencia es negativa, entonces el contador reinicializado era
+mayor (64 bits), por lo que se le suma el valor máximo del contador
+"largo" + 1 y se le resta el máximo del contador "pequeño" que sumamos
+erróneamente. Hay un problema con esto: supongamos que un contador
+largo se ha reinicializado al sumársele una diferencia muy grande;
+entonces es posible que al añadir el valor máximo del contador pequeño
+la diferencia nos dé positivo. En este caso poco probable, los valores
+resultantes no serian correctos. Para que ocurra esto, el incremento
+tiene que ser casi tan grande como el valor máximo del contador, por
+lo que de ocurrir es muy probable que halla varios problemas más en
+la configuración y no merezca la pena preocuparse sólo por este. Aún
+así, he incluido un ejemplo de este caso para que lo puedas juzgar por
+ti mismo.
+
+A continuación, unos ejemplos de reinicialización de los
+contadores. Prueba de hacer los cálculos por ti mismo, o acepta mis
+resultados si tu calculadora no puede con los números :)
+
+Números de corrección:
+
+ - 32 bits: (4294967295+1) =                                 4294967296
+ - 64 bits: (18446744073709551615+1)-correction1 = 18446744069414584320
+ 
+ Antes:          4294967200
+ Incremento:            100
+ Debería ser:    4294967300
+ Pero es:                 4
+ Diferencia:    -4294967196
+ Corrección #1: -4294967196 + 4294967296 = 100
+ 
+ Antes:          18446744073709551000
+ Incremento:                      800
+ Debería ser:    18446744073709551800
+ Pero es:                         184
+ Diferencia:    -18446744073709550816
+ Corrección #1: -18446744073709550816 +4294967296 = -18446744069414583520
+ Corrección #2: -18446744069414583520 +18446744069414584320 = 800
+ 
+ Antes:          18446744073709551615 ( valor máximo )
+ Incremento:     18446744069414584320 ( incremento absurdo, 
+ Debería ser:    36893488143124135935   mínimo para que 
+ Pero es:        18446744069414584319   funcione el ejemplo)       
+ Diferencia:              -4294967296
+ Corrección #1:  -4294967296 + 4294967296 = 0 (positivo,
+                                               por tanto no se hace 
+                                               la segunda corrección)
+ 
+ Antes:          18446744073709551615 ( valor máximo )
+ Incremento:     18446744069414584319 
+ Debería ser:    36893488143124135934
+ Pero es:        18446744069414584318
+ Diferencia:              -4294967297
+ Corrección #1:  -4294967297 +4294967296 = -1
+ Corrección #2:  -1 +18446744069414584320 = 18446744069414584319
+
+Como puede verse en los últimos ejemplos, necesitas unos valores
+bastante extraños para hacer que RRDtool falle (asumiendo que no tenga
+ningún error el programa, por supuesto), así que esto no debería
+ocurrir. Sin embargo, SNMP o cualquier otro
+método que uses de recogida de datos puede también reportar algún
+valor erróneo ocasionalmente. No podemos prevenir todos los errores,
+pero podemos tomar algunas medidas. El comando "create" de RRDtool
+tiene dos parámetros especialmente para esto, que definen los valores
+mínimo y máximo permitidos. Hasta ahora hemos usado "U",
+"desconocido". Si le pasas valores para uno o ambos parámetros y
+RRDtool recibe un valor fuera de esos límites, los ignorará. Para un
+termómetro en grados Celsius, el mínimo absoluto es -273. Para mi
+enrutador, puedo asumir que ese mínimo es mucho mayor, digamos que 10.
+La temperatura máxima la pondría en unos 80 grados; más alto y
+el aparato no funcionaría. Para mi coche, nunca esperaría obtener
+valores negativos, y tampoco esperaría valores mayores a 230.
+Cualquier otra cosa sería un error. Pero recuerda, lo contrario no es
+cierto: si los valores pasan este examen no quiere decir que sean los
+correctos. Siempre examina bien el gráfico si los valores parecen
+extraños.
+
+
+=head2 Remuestreo de los datos
+
+Hay una funcionalidad importante de RRDtool que no hemos explicado
+todavía: es virtualmente imposible recoger los datos y pasarselos a
+RRDtool a intervalos exactos de tiempo. Por tanto, RRDtool interpola
+los datos a los intervalos exactos. Si no sabes que significa esto o
+como se hace, he aquí la ayuda que necesitas:
+
+Supongamos un contador se incremente exactamente en 1 cada segundo.
+Queremos medirlo cada 300 segundos, por lo que deberíamos tener
+valores separados exactamente en 300. Sin embargo, por varias
+circunstancias llegamos unos segundos tarde y el intervalo es 303. La
+diferencia será por tanto 303. Obviamente, RRDtool no debe colocar 303
+en la base de datos y dar así la impresión de que el contador se
+incrementó 303 en 300 segundos. Aquí es donde RRDtool interpola:
+alterá el valor 303 al valor que tendría 3 segundos antes y guarda 300
+en 300 segundos. Digamos que la próxima vez llegamos justo a tiempo;
+por tanto, el intervalo actual es 297 segundos, por lo que el contador
+debería ser 297. De nuevo, RRDtool altera el valor y guarda 300, como
+debe ser.
+
+         en RRD                     en realidad
+ tiempo+000:   0 delta="U"    tiempo+000:   0 delta="U" 
+ tiempo+300: 300 delta=300    tiempo+300: 300 delta=300
+ tiempo+600: 600 delta=300    tiempo+603: 603 delta=303
+ tiempo+900: 900 delta=300    tiempo+900: 900 delta=297
+
+Creemos dos bases de datos idénticas. He escogido el rango de
+tiempo entre 920805000 y 920805900.
+
+   rrdtool create seconds1.rrd   \
+      --start 920804700          \
+      DS:seconds:COUNTER:600:U:U \
+      RRA:AVERAGE:0.5:1:24
+
+   para Unix: cp seconds1.rrd seconds2.rrd
+   para DOS: copy seconds1.rrd seconds2.rrd
+   para VMS:  y yo que sé :)
+
+   rrdtool update seconds1.rrd \
+      920805000:000 920805300:300 920805600:600 920805900:900
+   rrdtool update seconds2.rrd \
+      920805000:000 920805300:300 920805603:603 920805900:900
+
+   rrdtool graph seconds1.gif                       \
+      --start 920804700 --end 920806200             \
+      --height 200                                  \
+      --upper-limit 1.05 --lower-limit 0.95 --rigid \
+      DEF:seconds=seconds1.rrd:seconds:AVERAGE      \
+      CDEF:unknown=seconds,UN                       \
+      LINE2:seconds#0000FF                          \
+      AREA:unknown#FF0000
+   rrdtool graph seconds2.gif                       \
+      --start 920804700 --end 920806200             \
+      --height 200                                  \
+      --upper-limit 1.05 --lower-limit 0.95 --rigid \
+      DEF:seconds=seconds2.rrd:seconds:AVERAGE      \
+      CDEF:unknown=seconds,UN                       \
+      LINE2:seconds#0000FF                          \
+      AREA:unknown#FF0000
+
+Los dos gráficos debe ser iguales.
+
+=head1 RESUMEN
+
+Es hora de concluir este documento. Ahora debes conocer lo básico
+como para trabajar con RRDtool y leer la documentación. Aún hay mucho
+más por descubrir acerca de RRDtool, y le encontrarás; más y más usos
+para la herramienta. Con los ejemplos y la herramienta puedes crear
+fácilmente muchos gráficos; también puedes usar las interfaces
+disponibles.
+
+=head1 LISTA DE CORREO
+
+Recuerda subscribirte a la lista de correo. Aunque no contestes los
+correos que aparecen en ella, te servirá de ayuda a ti y a los demás.
+Mucho de lo que se sobre MRTG (y por tanto sobre RRDtool), lo aprendí
+tan sólo con leer la lista, sin escribir. No hay por que preguntar las
+preguntas básicas, que ya tienen su respuesta en la FAQ (¡léela!). Con
+miles de usuarios a lo largo del mundo, siempre hay preguntas que tu
+puedes responder con lo aprendido en este y otros documentos.
+
+=head1 VER TAMBIÉN
+
+Las páginas del manual de RRDtool
+
+=head1 AUTOR
+
+Espero que hayas disfrutado con los ejemplos y las descripciones.
+Si es así, ayuda a otros refiriéndolos a este documento cuando te
+hagan preguntas básicas. No sólo obtendrán la respuesta, sino que
+aprenderán muchas otras cosas.
+
+Alex van den Bogaerdt <alex at ergens.op.het.net>

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdtune.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdtune.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdtune.pod	Sat Jul 13 21:26:19 2002
@@ -2,6 +2,8 @@
 
 rrdtool tune - Modify some basic properties of a Round Robin Database
 
+=for html <div align="right"><a href="rrdtune.pdf">PDF</a> version.</div>
+
 =head1 SYNOPSIS
 
 B<rrdtool> B<tune> I<filename> 
@@ -57,7 +59,7 @@
 
 =head1 EXAMPLE
 
-C<rrdtool tune data.rrd -h in:100000 -h in:100000 -h in:100000>
+C<rrdtool tune data.rrd -h in:100000 -h out:100000 -h through:100000>
 
 Set the minimum required heartbeat for data sources 'in', 'out' 
 and 'through' to 10000 seconds which is a little over one day in data.rrd.

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdfetch.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdfetch.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdfetch.html	Sat Jul 13 21:26:19 2002
@@ -1,229 +1,199 @@
 <HTML>
 <HEAD>
 <TITLE>rrdfetch</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
 	<UL>
 
-		<LI><A HREF="#AT_STYLE_TIME_SPECIFICATION">AT-STYLE TIME SPECIFICATION</A>
-		<LI><A HREF="#TIME_REFERENCE_SPECIFICATION">TIME REFERENCE SPECIFICATION</A>
-		<LI><A HREF="#TIME_OFFSET_SPECIFICATION">TIME OFFSET SPECIFICATION</A>
-		<LI><A HREF="#TIME_SPECIFICATION_EXAMPLES">TIME SPECIFICATION EXAMPLES</A>
+		<LI><A HREF="#atstyle time specification">AT-STYLE TIME SPECIFICATION</A></LI>
+		<LI><A HREF="#time reference specification">TIME REFERENCE SPECIFICATION</A></LI>
+		<LI><A HREF="#time offset specification">TIME OFFSET SPECIFICATION</A></LI>
+		<LI><A HREF="#time specification examples">TIME SPECIFICATION EXAMPLES</A></LI>
 	</UL>
 
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-rrdtool fetch - fetch data from an rrd.
-
-<P>
+<H1><A NAME="name">NAME</A></H1>
+<P>rrdtool fetch - fetch data from an rrd.</P>
+<div align="right"><a href="rrdfetch.pdf">PDF</a> version.</div><P>
 <HR>
-<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
-<P>
-<STRONG>rrdtool</STRONG>  <STRONG>fetch</STRONG>  <EM>filename</EM>  <EM>CF</EM> 
- 
+<H1><A NAME="synopsis">SYNOPSIS</A></H1>
+<P><STRONG>rrdtool</STRONG> <STRONG>fetch</STRONG> <EM>filename</EM> <EM>CF</EM> 
 [<STRONG>--resolution</STRONG>|<STRONG>-r</STRONG>&nbsp;<EM>resolution</EM>] 
- 
 [<STRONG>--start</STRONG>|<STRONG>-s</STRONG>&nbsp;<EM>start</EM>] 
- 
-[<STRONG>--end</STRONG>|<STRONG>-e</STRONG>&nbsp;<EM>end</EM>] 
-
- 
-
+[<STRONG>--end</STRONG>|<STRONG>-e</STRONG>&nbsp;<EM>end</EM>]</P>
 <P>
 <HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-The <STRONG>fetch</STRONG> function is normally used internally by the graph function, to get data
-from <STRONG>RRD</STRONG>s. <STRONG>fetch</STRONG> will analyze the <STRONG>RRD</STRONG> and will try to retrieve the data in the resolution requested. The data
-fetched is printed to stdout. <EM>*UNKNOWN*</EM> data is often represented by the string ``NaN'' depending on your OSs
-printf function.
-
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>The <STRONG>fetch</STRONG> function is normally used internally by the graph function,
+to get data from <STRONG>RRD</STRONG>s. <STRONG>fetch</STRONG> will analyze the <STRONG>RRD</STRONG> and
+will try to retrieve the data in the resolution requested.
+The data fetched is printed to stdout. <EM>*UNKNOWN*</EM> data is often
+represented by the string ``NaN'' depending on your OSs printf
+function.</P>
 <DL>
-<DT><STRONG><A NAME="item_filename">filename</A></STRONG><DD>
-<P>
+<DT><STRONG><A NAME="item_filename"><EM>filename</EM></A></STRONG><BR>
+<DD>
 the name of the <STRONG>RRD</STRONG> you want to fetch the data from.
-
-<DT><STRONG><A NAME="item_CF">CF</A></STRONG><DD>
-<P>
-which consolidation function should have been applied to the data you want
-to fetch? (AVERAGE,MIN,MAX,LAST)
-
-<DT><STRONG><A NAME="item__resolution_r">--resolution|-r resolution (default is the highest resolution)</A></STRONG><DD>
-<P>
-what interval should the values have (seconds per value). <STRONG>rrdfetch</STRONG> will try to match your request, but it will return data even if no absolute
+<P></P>
+<DT><STRONG><A NAME="item_CF"><EM>CF</EM></A></STRONG><BR>
+<DD>
+which consolidation function should have been applied to the data you
+want to fetch? (AVERAGE,MIN,MAX,LAST)
+<P></P>
+<DT><STRONG><A NAME="item_resolution"><STRONG>--resolution</STRONG>|<STRONG>-r</STRONG> <EM>resolution</EM> (default is the highest resolution)</A></STRONG><BR>
+<DD>
+what interval should the values have (seconds per value). <STRONG>rrdfetch</STRONG> will try
+to match your request, but it will return data even if no absolute
 match is possible.
-
-<DT><STRONG><A NAME="item__start_s">--start|-s start (default end-1day)</A></STRONG><DD>
-<P>
-when should the data begin. A time in seconds since epoch (1970-01-01) is
-required. Negative numbers are relative to the current time. By default one
-day worth of data will be fetched. See also AT-STYLE TIME SPECIFICATION
-section for a detailed explanation on ways to specify start time.
-
-<DT><STRONG><A NAME="item__end_e">--end|-e end (default now)</A></STRONG><DD>
-<P>
-when should the data end. Time in seconds since epoch. See also AT-STYLE
-TIME SPECIFICATION section for a detailed explanation of how to specify end
-time.
-
-</DL>
-<P>
-<HR>
-<H2><A NAME="AT_STYLE_TIME_SPECIFICATION">AT-STYLE TIME SPECIFICATION</A></H2>
-<P>
-Apart from the traditional <EM>Seconds since epoch</EM>, rrdtool does also understand at-style time specification. The
-specification is called ``at-style'' after Unix command <CODE>at(1)</CODE>
-that has moderately complex ways to specify time to run your job at. The
-at-style specification consists of two parts: <STRONG>TIME REFERENCE</STRONG> specification and <STRONG>TIME
-OFFSET</STRONG> specification.
-
-<P>
-<HR>
-<H2><A NAME="TIME_REFERENCE_SPECIFICATION">TIME REFERENCE SPECIFICATION</A></H2>
-<P>
-Time reference specification is used, well,... to establish a reference
-moment in time (for time offset to be applied to). When present, it should
-come first, when omitted, it defaults to <STRONG>now</STRONG>. On its own part, time reference consists of <EM>time-of-day</EM> reference (which should come first, if present) and <EM>day</EM> reference.
-
-<P>
-<EM>Time-of-day</EM> can be specified as <STRONG>HH:MM</STRONG>, <STRONG>HH.MM</STRONG>, or just <STRONG>HH</STRONG>, you can suffix it with <STRONG>am</STRONG> or <STRONG>pm</STRONG> or use 24-hours clock. The few special times of day are understood as well,
+<P></P>
+<DT><STRONG><A NAME="item_start"><STRONG>--start</STRONG>|<STRONG>-s</STRONG> <EM>start</EM> (default end-1day)</A></STRONG><BR>
+<DD>
+when should the data begin. A time in seconds since epoch (1970-01-01)
+is required. Negative numbers are relative to the current time. By default
+one day worth of data will be fetched. See also AT-STYLE TIME SPECIFICATION
+section for a detailed explanation on  ways to specify start time.
+<P></P>
+<DT><STRONG><A NAME="item_end"><STRONG>--end</STRONG>|<STRONG>-e</STRONG> <EM>end</EM> (default now)</A></STRONG><BR>
+<DD>
+when should the data end. Time in seconds since epoch. See also
+AT-STYLE TIME SPECIFICATION section for a detailed explanation of how to specify
+end time.
+<P></P></DL>
+<P>
+<H2><A NAME="atstyle time specification">AT-STYLE TIME SPECIFICATION</A></H2>
+<P>Apart from the traditional <EM>Seconds since epoch</EM>, rrdtool does also
+understand at-style time specification.  The specification is called
+``at-style'' after Unix command <CODE>at(1)</CODE> that has moderately complex ways
+to specify time to run your job at.  The at-style specification
+consists of two parts: <STRONG>TIME REFERENCE</STRONG> specification and <STRONG>TIME
+OFFSET</STRONG> specification.</P>
+<P>
+<H2><A NAME="time reference specification">TIME REFERENCE SPECIFICATION</A></H2>
+<P>Time reference specification is used, well,... to establish a reference
+moment in time (for time offset to be applied to). When present,
+it should come first, when omitted, it defaults to <STRONG>now</STRONG>. On its own part,
+time reference consists of <EM>time-of-day</EM> reference (which should come
+first, if present) and <EM>day</EM> reference.</P>
+<P><EM>Time-of-day</EM> can be specified as <STRONG>HH:MM</STRONG>, <STRONG>HH.MM</STRONG>,
+or just <STRONG>HH</STRONG>, you can suffix it with <STRONG>am</STRONG> or <STRONG>pm</STRONG> or use
+24-hours clock. The few special times of day are understood as well,
 these include <STRONG>midnight</STRONG> (00:00), <STRONG>noon</STRONG> (12:00) and British
-<STRONG>teatime</STRONG> (16:00).
-
-<P>
-The <EM>day</EM> can be specified as <EM>month-name</EM>  <EM>day-of-the-month</EM>
-and optional 2- or 4-digit <EM>year</EM> number (e.g. March 8 1999). Alternatively, you can use <EM>day-of-week-name</EM> (e.g. Monday), or one of the words: <STRONG>yesterday</STRONG>, <STRONG>today</STRONG>, <STRONG>tomorrow</STRONG>. You can also specify <EM>day</EM> as a full date in several numerical formats; these include: <STRONG>MM/DD/[YY]YY</STRONG>, <STRONG>DD.MM.[YY]YY</STRONG>, <STRONG>YYYYMMDD</STRONG>
-(<EM>NOTE1</EM>: this is different from the original <CODE>at(1)</CODE> behavior, which
-interprets a single-number date as MMDD[YY]YY)
-<EM>NOTE2</EM>: if you specify <EM>day</EM> this way, the <EM>time-of-day</EM> is REQUIRED to be present.
-
-<P>
-Finally, you can use words <STRONG>now</STRONG>, <STRONG>start</STRONG>, or <STRONG>end</STRONG> as your time reference. <STRONG>Now</STRONG> refers to the current moment (and is also a default time reference). <STRONG>Start</STRONG> (<STRONG>end</STRONG>) can be used to specify time relative to the start (end) time for those
-tools that use these categories (rrdfetch, rrdgraph).
-
-<P>
-Month and weekday names can be used in their naturally abbreviated form
+<STRONG>teatime</STRONG> (16:00).</P>
+<P>The <EM>day</EM> can be specified as <EM>month-name</EM> <EM>day-of-the-month</EM>
+and optional 2- or 4-digit <EM>year</EM> number (e.g. March 8 1999).
+Alternatively, you can use <EM>day-of-week-name</EM> (e.g. Monday),
+or one of the words: <STRONG>yesterday</STRONG>, <STRONG>today</STRONG>, <STRONG>tomorrow</STRONG>.
+You can also specify <EM>day</EM> as a full date in several numerical formats;
+these include: <STRONG>MM/DD/[YY]YY</STRONG>, <STRONG>DD.MM.[YY]YY</STRONG>, <STRONG>YYYYMMDD</STRONG>.</P>
+<P><EM>NOTE1</EM>: this is different from the original <CODE>at(1)</CODE> behavior,
+which interprets a single-number date as MMDD[YY]YY.</P>
+<P><EM>NOTE2</EM>: if you specify <EM>day</EM> this way, the <EM>time-of-day</EM> is REQUIRED
+to be present.</P>
+<P>Finally, you can use words <STRONG>now</STRONG>, <STRONG>start</STRONG>, or <STRONG>end</STRONG> as your time
+reference. <STRONG>Now</STRONG> refers to the current moment (and is also a default
+time reference). <STRONG>Start</STRONG> (<STRONG>end</STRONG>) can be used to specify time
+relative to the start (end) time for those tools that use these
+categories (rrdfetch, rrdgraph).</P>
+<P>Month and weekday names can be used in their naturally abbreviated form
 (e.g., Dec for December, Sun for Sunday, etc.). The words <STRONG>now</STRONG>,
-<STRONG>start</STRONG>, <STRONG>end</STRONG> can be abbreviated to <STRONG>n</STRONG>, <STRONG>s</STRONG>, <STRONG>e</STRONG>.
-
-<P>
-<HR>
-<H2><A NAME="TIME_OFFSET_SPECIFICATION">TIME OFFSET SPECIFICATION</A></H2>
+<STRONG>start</STRONG>, <STRONG>end</STRONG> can be abbreviated to <STRONG>n</STRONG>, <STRONG>s</STRONG>, <STRONG>e</STRONG>.</P>
 <P>
-Time offset specification is used to add (or subtract) certain time
+<H2><A NAME="time offset specification">TIME OFFSET SPECIFICATION</A></H2>
+<P>Time offset specification is used to add (or subtract) certain time
 interval to (from) the time reference moment. It consists of <EM>sign</EM>
-(<STRONG>+</STRONG>&nbsp;or&nbsp;<STRONG>-</STRONG>) and <EM>amount</EM>. The following time units can be used to specify the <EM>amount</EM>: <STRONG>years</STRONG>, <STRONG>months</STRONG>, <STRONG>weeks</STRONG>, <STRONG>days</STRONG>,
-<STRONG>hours</STRONG>, <STRONG>minutes</STRONG>, <STRONG>seconds</STRONG>, these can be used in singular or plural form, and abbreviated naturally
-or to a single letter (e.g. +3days, -1wk, -3y). Several time units can be
-combined together (e.g., -5mon1w2d), as well as several time offsets can be
-concatenated (e.g., -5h45min = -5h-45min = -6h+15min = -7h+1h30m-15min,
-etc.)
-
-<P>
-<EM>NOTE3</EM>: If you specify time offset in days, weeks, months, or years, you will end
-with the time offset that may vary depending on you time reference, because
-all those time units have no single well defined time interval value (1&nbsp;year contains either 365 or 366 days, 1&nbsp;month
-is 28 to 31 days long, and even 1&nbsp;day may be not equal to 24 hours twice a year, when DST-related clock
-adjustments take place). To cope with this, when you use days, weeks,
-months, or years as your time offset units your time reference date is
-adjusted accordingly without taking too much further effort to ensure
-anything about it (in the hope that <CODE>mktime(3)</CODE> will take care
-of this later). This may lead to some surprising (or even invalid!)
-results, e.g. 'May&nbsp;31&nbsp;-1month' = 'Apr&nbsp;31' (meaningless) = 'May&nbsp;1'
-(after <CODE>mktime(3)</CODE> normalization); in the EET timezone '3:30am
-Mar 29 1999 -1 day' yields '3:30am Mar 28 1999' (Sunday) which is invalid
-time/date combination (because of 3am -&gt; 4am DST forward clock
-adjustment, see the below example). On the other hand, hours, minutes, and
-seconds are well defined time intervals, and these are guaranteed to always
-produce time offsets exactly as specified (e.g. for EET timezone, '8:00&nbsp;Mar&nbsp;27&nbsp;1999&nbsp;+2&nbsp;days' =
-'8:00&nbsp;Mar&nbsp;29&nbsp;1999', but since there is 1-hour DST forward clock adjustment takes place around 3:00&nbsp;Mar&nbsp;28&nbsp;1999, the actual time interval between
+(<STRONG>+</STRONG>&nbsp;or&nbsp;<STRONG>-</STRONG>) and <EM>amount</EM>. The following time units can be used
+to specify the <EM>amount</EM>: <STRONG>years</STRONG>, <STRONG>months</STRONG>, <STRONG>weeks</STRONG>, <STRONG>days</STRONG>,
+<STRONG>hours</STRONG>, <STRONG>minutes</STRONG>, <STRONG>seconds</STRONG>, these can be used in singular
+or plural form, and abbreviated naturally or to a single letter
+(e.g. +3days, -1wk, -3y). Several time units can be combined
+together (e.g., -5mon1w2d), as well as several time offsets can be
+concatenated (e.g., -5h45min = -5h-45min = -6h+15min = -7h+1h30m-15min, etc.)</P>
+<P><EM>NOTE3</EM>: If you specify time offset in days, weeks, months, or years,
+you will end with the time offset that may vary depending on you time
+reference, because all those time units have no single well defined
+time interval value (1&nbsp;year contains either 365 or 366 days, 1&nbsp;month
+is 28 to 31 days long, and even 1&nbsp;day may be not equal to 24 hours
+twice a year, when DST-related clock adjustments take place).
+To cope with this, when you use days, weeks, months, or years
+as your time offset units your time reference date is adjusted
+accordingly without taking too much further effort to ensure anything
+about it (in the hope that <CODE>mktime(3)</CODE> will take care of this later).
+This may lead to some surprising (or even invalid!) results,
+e.g. 'May&nbsp;31&nbsp;-1month' = 'Apr&nbsp;31' (meaningless) = 'May&nbsp;1'
+(after <CODE>mktime(3)</CODE> normalization); in the EET timezone
+'3:30am Mar 29 1999 -1 day' yields '3:30am Mar 28 1999' (Sunday)
+which is invalid time/date combination (because of 3am -&gt; 4am DST
+forward clock adjustment, see the below example).
+On the other hand, hours, minutes, and seconds are well defined time
+intervals, and these are guaranteed to always produce time offsets
+exactly as specified (e.g. for EET timezone, '8:00&nbsp;Mar&nbsp;27&nbsp;1999&nbsp;+2&nbsp;days' =
+'8:00&nbsp;Mar&nbsp;29&nbsp;1999', but since there is 1-hour DST forward clock adjustment
+takes place around 3:00&nbsp;Mar&nbsp;28&nbsp;1999, the actual time interval between
 8:00&nbsp;Mar&nbsp;27&nbsp;1999 and 8:00&nbsp;Mar&nbsp;29&nbsp;1999 equals 47 hours; on the other hand,
-'8:00&nbsp;Mar&nbsp;27&nbsp;1999&nbsp;+48&nbsp;hours' = '9:00&nbsp;Mar&nbsp;29&nbsp;1999', as expected)
-
-<P>
-<EM>NOTE4</EM>: The single-letter abbreviation for both <STRONG>months</STRONG> and <STRONG>minutes</STRONG>
+'8:00&nbsp;Mar&nbsp;27&nbsp;1999&nbsp;+48&nbsp;hours' = '9:00&nbsp;Mar&nbsp;29&nbsp;1999', as expected)</P>
+<P><EM>NOTE4</EM>: The single-letter abbreviation for both <STRONG>months</STRONG> and <STRONG>minutes</STRONG>
 is <STRONG>m</STRONG>. To disambiguate, the parser tries to read your mind&nbsp;:)
-by applying the following two heuristics:
-
+by applying the following two heuristics:</P>
 <OL>
 <LI>
-<P>
-If <STRONG>m</STRONG> is used in context of (i.e. right after the) years, months, weeks, or days
-it is assumed to mean <STRONG>months</STRONG>, while in the context of hours, minutes, and seconds it means minutes.
-(e.g., in -1y6m or +3w1m <STRONG>m</STRONG> means <STRONG>months</STRONG>, while in -3h20m or +5s2m <STRONG>m</STRONG> means <STRONG>minutes</STRONG>)
-
+If <STRONG>m</STRONG> is used in context of (i.e. right after the) years,
+months, weeks, or days it is assumed to mean <STRONG>months</STRONG>, while
+in the context of hours, minutes, and seconds it means minutes.
+(e.g., in -1y6m or +3w1m <STRONG>m</STRONG> means <STRONG>months</STRONG>, while in
+-3h20m or +5s2m <STRONG>m</STRONG> means <STRONG>minutes</STRONG>)
+<P></P>
 <LI>
-<P>
-Out of context (i.e. right after the <STRONG>+</STRONG> or <STRONG>-</STRONG> sign) the meaning of <STRONG>m</STRONG> is guessed from the number it directly follows. Currently, if the number
-absolute value is below 25 it is assumed that <STRONG>m</STRONG> means <STRONG>months</STRONG>, otherwise it is treated as <STRONG>minutes</STRONG>. (e.g., -25m == -25 minutes, while +24m == +24 months)
-
-</OL>
-<P>
-<EM>Final NOTES</EM>: Time specification is case-insensitive. Whitespace can be inserted freely
-or omitted altogether, there are, however, cases when whitespace is
-required (e.g., 'midnight&nbsp;Thu'). In this case you should either quote the whole phrase to prevent it from
-being taken apart by your shell or use '_' (underscore) or ',' (comma)
-which also count as whitespace (e.g., midnight_Thu or midnight,Thu)
-
+Out of context (i.e. right after the <STRONG>+</STRONG> or <STRONG>-</STRONG> sign) the
+meaning of <STRONG>m</STRONG> is guessed from the number it directly follows.
+Currently, if the number absolute value is below 25 it is assumed
+that <STRONG>m</STRONG> means <STRONG>months</STRONG>, otherwise it is treated as <STRONG>minutes</STRONG>.
+(e.g., -25m == -25 minutes, while +24m == +24 months)
+<P></P></OL>
+<P><EM>Final NOTES</EM>: Time specification is case-insensitive.
+Whitespace can be inserted freely or omitted altogether,
+there are, however, cases when whitespace is required
+(e.g., 'midnight&nbsp;Thu'). In this case you should either quote the
+whole phrase to prevent it from being taken apart by your shell or use
+'_' (underscore) or ',' (comma) which also count as whitespace
+(e.g., midnight_Thu or midnight,Thu)</P>
+<P>
+<H2><A NAME="time specification examples">TIME SPECIFICATION EXAMPLES</A></H2>
+<P><EM>Oct 12</EM> -- October 12 this year</P>
+<P><EM>-1month</EM> or <EM>-1m</EM> -- current time of day, only a month before
+(may yield surprises, see the NOTE3 above)</P>
+<P><EM>noon yesterday -3hours</EM> -- yesterday morning; can be put also as <EM>9am-1day</EM></P>
+<P><EM>23:59 31.12.1999</EM> -- 1 minute to the year 2000</P>
+<P><EM>12/31/99 11:59pm</EM> -- 1 minute to the year 2000 for imperialists</P>
+<P><EM>12am 01/01/01</EM> -- start of the new millennium</P>
+<P><EM>end-3weeks</EM> or <EM>e-3w</EM> -- 3 weeks before end time
+(may be used as start time specification)</P>
+<P><EM>start+6hours</EM> or <EM>s+6h</EM> -- 6 hours after start time
+(may be used as end time specification)</P>
+<P><EM>931225537</EM> -- 18:45  July 5th, 1999
+(yes, seconds since 1970 are valid as well)</P>
+<P><EM>19970703 12:45</EM> -- 12:45  July 3th, 1997
+(not quote standard, but I love this ...)</P>
 <P>
 <HR>
-<H2><A NAME="TIME_SPECIFICATION_EXAMPLES">TIME SPECIFICATION EXAMPLES</A></H2>
-<P>
-<EM>Oct 12</EM> -- October 12 this year
-
-<P>
-<EM>-1month</EM> or <EM>-1m</EM> -- current time of day, only a month before (may yield surprises, see the
-NOTE3 above)
-
-<P>
-<EM>noon yesterday -3hours</EM> -- yesterday morning; can be put also as <EM>9am-1day</EM>
-
-
-
-<P>
-<EM>23:59 31.12.1999</EM> -- 1 minute to the year 2000
-
-<P>
-<EM>12/31/99 11:59pm</EM> -- 1 minute to the year 2000 for imperialists
-
-<P>
-<EM>12am 01/01/01</EM> -- start of the new millennium
-
-<P>
-<EM>end-3weeks</EM> or <EM>e-3w</EM> -- 3 weeks before end time (may be used as start time specification)
-
-<P>
-<EM>start+6hours</EM> or <EM>s+6h</EM> -- 6 hours after start time (may be used as end time specification)
-
-<P>
-<EM>931225537</EM> -- 18:45 July 5th, 1999 (yes, seconds since 1970 are valid as well)
-
-<P>
-<EM>19970703 12:45</EM> -- 12:45 July 3th, 1997 (not quote standard, but I love this ...)
-
-<P>
-<HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-Tobias Oetiker &lt;<A
-HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;</P>
 
 </BODY>
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/bin_dec_hex.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/bin_dec_hex.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/bin_dec_hex.txt	Sat Jul 13 21:26:20 2002
@@ -60,7 +60,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      1
+2001-02-20             Last change: 1.0.33                      1
 
 
 
@@ -126,7 +126,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      2
+2001-02-20             Last change: 1.0.33                      2
 
 
 
@@ -187,12 +187,12 @@
       11111111 377  255   FF
 
      You can see why binary and hexadecimal can be converted
-     quickly:  For each hexadecimal digit there are exactly four
+     quickly: For each hexadecimal digit there are exactly four
      binary digits.  Take a binary number. Each time take four
 
 
 
-24/Oct/1999            Last change: 1.0.13                      3
+2001-02-20             Last change: 1.0.33                      3
 
 
 
@@ -209,7 +209,7 @@
      write down its binary equivalent.
 
      Computers (or rather the parsers running on them) would have
-     a hard time converting a number like _1_2_3_4(16). Therefore
+     a hard time converting a number like 1234(16). Therefore
      hexadecimal numbers get a prefix. This prefix depends on the
      language you're writing in. Some of the prefixes are "0x"
      for C, "$" for Pascal, "#" for HTML.  It is common to assume
@@ -258,7 +258,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      4
+2001-02-20             Last change: 1.0.33                      4
 
 
 
@@ -324,7 +324,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      5
+2001-02-20             Last change: 1.0.33                      5
 
 
 
@@ -390,7 +390,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      6
+2001-02-20             Last change: 1.0.33                      6
 
 
 
@@ -456,7 +456,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      7
+2001-02-20             Last change: 1.0.33                      7
 
 
 
@@ -480,10 +480,10 @@
      decimal, but in all bases you'll ever use (among them
      Binary).
 
-     For people on Windows:  Start the calculator (start-
-     >programs->accessories->calculator) and if necessary click
-     view->scientific. You now have a scientific calculator and
-     can compute in binary or hexadecimal.
+     For people on Windows: Start the calculator
+     (start->programs->accessories->calculator) and if necessary
+     click view->scientific. You now have a scientific calculator
+     and can compute in binary or hexadecimal.
 
 AAAAUUUUTTTTHHHHOOOORRRR
      I hope you enjoyed the examples and their descriptions. If
@@ -522,7 +522,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      8
+2001-02-20             Last change: 1.0.33                      8
 
 
 

Added: trunk/orca/packages/rrdtool-1.0.33/doc/rrdinfo.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdinfo.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdinfo.html	Sat Jul 13 21:26:20 2002
@@ -0,0 +1,84 @@
+<HTML>
+<HEAD>
+<TITLE>rrdinfo</TITLE>
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
+</HEAD>
+
+<BODY>
+
+<A NAME="__index__"></A>
+<!-- INDEX BEGIN -->
+<!--
+
+<UL>
+
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
+	<LI><A HREF="#example">EXAMPLE</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
+</UL>
+-->
+<!-- INDEX END -->
+
+<P>
+<H1><A NAME="name">NAME</A></H1>
+<P>rrdtool info - extract header information from an rrd</P>
+<div align="right"><a href="rrdinfo.pdf">PDF</a> version.</div><P>
+<HR>
+<H1><A NAME="synopsis">SYNOPSIS</A></H1>
+<P><STRONG>rrdtool</STRONG> <STRONG>info</STRONG> <EM>filename.rrd</EM></P>
+<P>
+<HR>
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>The <STRONG>info</STRONG> function prints the header information from an rrd in
+a parsing friendly format.</P>
+<P>Check <A HREF="././rrdcreate.html">the rrdcreate manpage</A> if you are uncertain about the meaning of the
+individual keys.</P>
+<P>
+<HR>
+<H1><A NAME="example">EXAMPLE</A></H1>
+<P>This is the output generated by running <STRONG>info</STRONG> on a simple rrd which
+contains two datasources and one rra. Note that the number after the
+<EM>last_update</EM> keyword is in seconds since 1970. The string <STRONG>NaN</STRONG>
+stands for <EM>*UNKNOWN*</EM> data. In the example it means that this rrd
+has neither minimum not maximum values defined for either of its
+datasources.</P>
+<PRE>
+ filename = &quot;randome.rrd&quot;
+ rrd_version = &quot;0001&quot;
+ step = 300
+ last_update = 955892996
+ ds[a].type = &quot;GAUGE&quot;
+ ds[a].minimal_heartbeat = 600
+ ds[a].min = NaN
+ ds[a].max = NaN
+ ds[a].last_ds = &quot;UNKN&quot;
+ ds[a].value = 2.1824421548e+04
+ ds[a].unknown_sec = 0
+ ds[b].type = &quot;GAUGE&quot;
+ ds[b].minimal_heartbeat = 600
+ ds[b].min = NaN
+ ds[b].max = NaN
+ ds[b].last_ds = &quot;UNKN&quot;
+ ds[b].value = 3.9620838224e+03
+ ds[b].unknown_sec = 0
+ rra[0].cf = &quot;AVERAGE&quot;
+ rra[0].pdp_per_row = 1
+ rra[0].cdp_prep[0].value = nan
+ rra[0].cdp_prep[0].unknown_datapoints = 0
+ rra[0].cdp_prep[1].value = nan
+ rra[0].cdp_prep[1].unknown_datapoints = 0</PRE>
+<DL>
+<DT><STRONG><A NAME="item_filename%2Errd"><EM>filename.rrd</EM></A></STRONG><BR>
+<DD>
+The name of the <STRONG>RRD</STRONG> you want to dump.
+<P></P></DL>
+<P>
+<HR>
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;</P>
+
+</BODY>
+
+</HTML>

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/bin_dec_hex.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/bin_dec_hex.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/bin_dec_hex.pod	Sat Jul 13 21:26:20 2002
@@ -2,6 +2,8 @@
 
 Binary Decimal Hexadecimal - How does it work
 
+=for html <div align="right"><a href="bin_dec_hex.pdf">PDF</a> version.</div>
+
 =head1 DESCRIPTION
 
 Most people use the decimal numbering system. This system uses ten

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/RRDp.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/RRDp.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/RRDp.html	Sat Jul 13 21:26:21 2002
@@ -1,143 +1,106 @@
 <HTML>
 <HEAD>
 <TITLE>RRDp</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
-	<LI><A HREF="#EXAMPLE">EXAMPLE</A>
-	<LI><A HREF="#SEE_ALSO">SEE ALSO</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
+	<LI><A HREF="#example">EXAMPLE</A></LI>
+	<LI><A HREF="#see also">SEE ALSO</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-RRDp - Attach rrdtool from within a perl script via a set of pipes;
-
+<H1><A NAME="name">NAME</A></H1>
+<P>RRDp - Attach rrdtool from within a perl script via a set of pipes;</P>
 <P>
 <HR>
-<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
-<P>
-use <STRONG>RRDp</STRONG>
-
-
-
-<P>
-<STRONG>RRDp::start</STRONG>  <EM>path to rrdtool executable</EM>
-
-
-
-<P>
-<STRONG>RRDp::cmd</STRONG>    <EM>rrdtool commandline</EM>
-
-
-
-<P>
-<CODE>$answer</CODE> = <STRONG>RRD::read</STRONG>
-
-
-
-<P>
-<CODE>$status</CODE> = <STRONG>RRD::end</STRONG>
-
-
-
-<P>
-<STRONG>$RRDp::user</STRONG>,  <STRONG>$RRDp::sys</STRONG>, <STRONG>$RRDp::real</STRONG>
-
-
-
+<H1><A NAME="synopsis">SYNOPSIS</A></H1>
+<P>use <STRONG>RRDp</STRONG></P>
+<P><STRONG>RRDp::start</STRONG> <EM>path to rrdtool executable</EM></P>
+<P><STRONG>RRDp::cmd</STRONG>  <EM>rrdtool commandline</EM></P>
+<P>$answer = <STRONG>RRD::read</STRONG></P>
+<P>$status = <STRONG>RRD::end</STRONG></P>
+<P><STRONG>$RRDp::user</STRONG>,  <STRONG>$RRDp::sys</STRONG>, <STRONG>$RRDp::real</STRONG></P>
 <P>
 <HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-With this module you can safely communicate with the rrdtool. 
-
-<P>
-After every <STRONG>RRDp::cmd</STRONG> you have to issue an <STRONG>RRDp::read</STRONG> command to get
-<STRONG>rrdtool</STRONG>s answer to your command. The answer is returned as a pointer, in order to
-speed things up. If the last command did not return any data, <STRONG>RRDp::read</STRONG> will return an undefined variable. 
-
-<P>
-If you import the PERFORMANCE variables into your namespace, you can access
-rrdtools internal performance measurements.
-
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>With this module you can safely communicate with the rrdtool.</P>
+<P>After every <STRONG>RRDp::cmd</STRONG> you have to issue an <STRONG>RRDp::read</STRONG> command to get
+<STRONG>rrdtool</STRONG>s answer to your command. The answer is returned as a pointer,
+in order to speed things up. If the last command did not return any
+data, <STRONG>RRDp::read</STRONG> will return an undefined variable.</P>
+<P>If you import the PERFORMANCE variables into your namespace, 
+you can access rrdtools internal performance measurements.</P>
 <DL>
-<DT><STRONG><A NAME="item_use">use RRDp</A></STRONG><DD>
-<P>
+<DT><STRONG><A NAME="item_use_RRDp">use <STRONG>RRDp</STRONG></A></STRONG><BR>
+<DD>
 Load the RRDp::pipe module.
-
-<DT><STRONG><A NAME="item_RRDp">RRDp::start path to rrdtool executable</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_RRDp%3A%3Astart_path_to_rrdtool_executable"><STRONG>RRDp::start</STRONG> <EM>path to rrdtool executable</EM></A></STRONG><BR>
+<DD>
 start rrdtool. The argument must be the path to the rrdtool executable
-
-<DT><STRONG><A NAME="item_RRDp">RRDp::cmd rrdtool commandline</A></STRONG><DD>
-<P>
-pass commands on to rrdtool. check the rrdtool documentation for more info
-on the rrdtool commands.
-
-<DT><STRONG><A NAME="item__answer">$answer = RRDp::read</A></STRONG><DD>
-<P>
-read rrdtools response to your command. Note that the <CODE>$answer</CODE>
-variable will only contain a pointer to the returned data. The reason for
-this is, that rrdtool can potentially return quite excessive amounts of
-data and we don't want to copy this around in memory. So when you want to
-access the contents of <CODE>$answer</CODE> you have to use
-<CODE>$$answer</CODE> which dereferences the variable.
-
-<DT><STRONG><A NAME="item__status">$status = RRDp::end</A></STRONG><DD>
-<P>
-terminates rrdtool and returns rrdtools status ... 
-
-<DT><STRONG><A NAME="item__RRDp_user_">$RRDp::user,  $RRDp::sys, $RRDp::real</A></STRONG><DD>
-<P>
-these variables will contain totals of the user time, system time and real
-time as seen by rrdtool. User time is the time rrdtool is running, System
-time is the time spend in system calls and real time is the total time
-rrdtool has been running.
-
-<P>
-The difference between user + system and real is the time spent waiting for
-things like the hard disk and new input from the perl script.
-
-</DL>
+<P></P>
+<DT><STRONG><A NAME="item_RRDp%3A%3Acmd_rrdtool_commandline"><STRONG>RRDp::cmd</STRONG> <EM>rrdtool commandline</EM></A></STRONG><BR>
+<DD>
+pass commands on to rrdtool. check the rrdtool documentation for
+more info on the rrdtool commands.
+<P></P>
+<DT><STRONG><A NAME="item_%24answer_%3D_RRDp%3A%3Aread">$answer = <STRONG>RRDp::read</STRONG></A></STRONG><BR>
+<DD>
+read rrdtools response to your command. Note that the $answer variable will
+only contain a pointer to the returned data. The reason for this is, that
+rrdtool can potentially return quite excessive amounts of data
+and we don't want to copy this around in memory. So when you want to 
+access the contents of $answer you have to use $$answer which dereferences
+the variable.
+<P></P>
+<DT><STRONG><A NAME="item_%24status_%3D_RRDp%3A%3Aend">$status = <STRONG>RRDp::end</STRONG></A></STRONG><BR>
+<DD>
+terminates rrdtool and returns rrdtools status ...
+<P></P>
+<DT><STRONG><A NAME="item_%24RRDp%3A%3Auser%2C_%24RRDp%3A%3Asys%2C_%24RRDp%3"><STRONG>$RRDp::user</STRONG>,  <STRONG>$RRDp::sys</STRONG>, <STRONG>$RRDp::real</STRONG></A></STRONG><BR>
+<DD>
+these variables will contain totals of the user time, system time and
+real time as seen by rrdtool.  User time is the time rrdtool is
+running, System time is the time spend in system calls and real time
+is the total time rrdtool has been running.
+<P>The difference between user + system and real is the time spent
+waiting for things like the hard disk and new input from the perl
+script.</P>
+<P></P></DL>
 <P>
 <HR>
-<H1><A NAME="EXAMPLE">EXAMPLE</A></H1>
-<P>
-<PRE> use RRDp;
+<H1><A NAME="example">EXAMPLE</A></H1>
+<PRE>
+ use RRDp;
  RRDp::start &quot;/usr/local/bin/rrdtool&quot;;
  RRDp::cmd   qw(create demo.rrd --step 100 
                DS:in:GAUGE:100:U:U
                RRA:AVERAGE:0.5:1:10);
  $answer = RRDp::read;
  print $$answer;
- ($usertime,$systemtime,$realtime) =  ($RRDp::user,$RRDp::sys,$RRDp::real);
-</PRE>
+ ($usertime,$systemtime,$realtime) =  ($RRDp::user,$RRDp::sys,$RRDp::real);</PRE>
 <P>
 <HR>
-<H1><A NAME="SEE_ALSO">SEE ALSO</A></H1>
-<P>
-For more information on how to use rrdtool, check the manpages.
-
+<H1><A NAME="see also">SEE ALSO</A></H1>
+<P>For more information on how to use rrdtool, check the manpages.</P>
 <P>
 <HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-Tobias Oetiker &lt;<A
-HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;</P>
 
 </BODY>
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdgraph.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdgraph.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdgraph.html	Sat Jul 13 21:26:21 2002
@@ -1,517 +1,529 @@
 <HTML>
 <HEAD>
 <TITLE>rrdgraph</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
-	<LI><A HREF="#NOTES_on_legend_arguments">NOTES on legend arguments</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
+	<LI><A HREF="#notes on legend arguments">NOTES on legend arguments</A></LI>
 	<UL>
 
-		<LI><A HREF="#Escaping_the_colon">Escaping the colon</A>
-		<LI><A HREF="#String_Formatting">String Formatting</A>
+		<LI><A HREF="#escaping the colon">Escaping the colon</A></LI>
+		<LI><A HREF="#string formatting">String Formatting</A></LI>
 	</UL>
 
-	<LI><A HREF="#NOTE_on_Return_Values">NOTE on Return Values</A>
-	<LI><A HREF="#EXAMPLE_1">EXAMPLE 1</A>
-	<LI><A HREF="#EXAMPLE_2">EXAMPLE 2</A>
-	<LI><A HREF="#EXAMPLE_3">EXAMPLE 3</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
-	<LI><A HREF="#REFERENCES">REFERENCES</A>
+	<LI><A HREF="#note on return values">NOTE on Return Values</A></LI>
+	<LI><A HREF="#example 1">EXAMPLE 1</A></LI>
+	<LI><A HREF="#example 2">EXAMPLE 2</A></LI>
+	<LI><A HREF="#example 3">EXAMPLE 3</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
+	<LI><A HREF="#references">REFERENCES</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-rrdtool graph - Create a graph based on data from one or several RRD
-
-<P>
+<H1><A NAME="name">NAME</A></H1>
+<P>rrdtool graph - Create a graph based on data from one or several RRD</P>
+<div align="right"><a href="rrdgraph.pdf">PDF</a> version.</div><P>
 <HR>
-<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
-<P>
-<STRONG>rrdtool</STRONG>  <STRONG>graph</STRONG>  <EM>filename</EM> 
- 
+<H1><A NAME="synopsis">SYNOPSIS</A></H1>
+<P><STRONG>rrdtool</STRONG> <STRONG>graph</STRONG> <EM>filename</EM> 
 [<STRONG>-s</STRONG>|<STRONG>--start</STRONG>&nbsp;<EM>seconds</EM>] 
- 
 [<STRONG>-e</STRONG>|<STRONG>--end</STRONG>&nbsp;<EM>seconds</EM>]
-
 [<STRONG>-x</STRONG>|<STRONG>--x-grid</STRONG>&nbsp;<EM>x-axis&nbsp;grid&nbsp;and&nbsp;label</EM>]
-
 [<STRONG>-y</STRONG>|<STRONG>--y-grid</STRONG>&nbsp;<EM>y-axis&nbsp;grid&nbsp;and&nbsp;label</EM>]
-
 [<STRONG>--alt-y-grid</STRONG>]
-
 [<STRONG>--alt-autoscale</STRONG>]
-
+[<STRONG>--alt-autoscale-max</STRONG>]
+[<STRONG>--units-exponent</STRONG>] <EM>value</EM>]&gt;
 [<STRONG>-v</STRONG>|<STRONG>--vertical-label</STRONG>&nbsp;<EM>text</EM>]
-
 [<STRONG>-w</STRONG>|<STRONG>--width</STRONG>&nbsp;<EM>pixels</EM>]
-
 [<STRONG>-h</STRONG>|<STRONG>--height</STRONG>&nbsp;<EM>pixels</EM>] 
- 
 [<STRONG>-i</STRONG>|<STRONG>--interlaced</STRONG>] 
- 
 [<STRONG>-f</STRONG>|<STRONG>--imginfo</STRONG>&nbsp;<EM>formatstring</EM>] 
- 
 [<STRONG>-a</STRONG>|<STRONG>--imgformat</STRONG>&nbsp;<STRONG>GIF</STRONG>|<STRONG>PNG</STRONG>] 
- 
 [<STRONG>-z</STRONG>|<STRONG>--lazy</STRONG>] 
- 
 [<STRONG>-o</STRONG>|<STRONG>--logarithmic</STRONG>]
-
 [<STRONG>-u</STRONG>|<STRONG>--upper-limit</STRONG>&nbsp;<EM>value</EM>] 
- 
 [<STRONG>-l</STRONG>|<STRONG>--lower-limit</STRONG>&nbsp;<EM>value</EM>]
-
 [<STRONG>-r</STRONG>|<STRONG>--rigid</STRONG>]
-
+[<STRONG>--step</STRONG>&nbsp;<EM>value</EM>]
 [<STRONG>-b</STRONG>|<STRONG>--base</STRONG>&nbsp;<EM>value</EM>]
-
 [<STRONG>-c</STRONG>|<STRONG>--color</STRONG>&nbsp;<EM>COLORTAG</EM><STRONG>#</STRONG><EM>rrggbb</EM>]
-
-
-
-<P>
 [<STRONG>-t</STRONG>|<STRONG>--title</STRONG>&nbsp;<EM>title</EM>]
-
 [<STRONG>DEF:</STRONG><EM>vname</EM><STRONG>=</STRONG><EM>rrd</EM><STRONG>:</STRONG><EM>ds-name</EM><STRONG>:</STRONG><EM>CF</EM>]
-
 [<STRONG>CDEF:</STRONG><EM>vname</EM><STRONG>=</STRONG><EM>rpn-expression</EM>]
-
 [<STRONG>PRINT:</STRONG><EM>vname</EM><STRONG>:</STRONG><EM>CF</EM><STRONG>:</STRONG><EM>format</EM>]
-
 [<STRONG>GPRINT:</STRONG><EM>vname</EM><STRONG>:</STRONG><EM>CF</EM><STRONG>:</STRONG><EM>format</EM>]
-
 [<STRONG>COMMENT:</STRONG><EM>text</EM>]
-
 [<STRONG>HRULE:</STRONG><EM>value</EM><STRONG>#</STRONG><EM>rrggbb</EM>[<STRONG>:</STRONG><EM>legend</EM>]]
-
 [<STRONG>VRULE:</STRONG><EM>time</EM><STRONG>#</STRONG><EM>rrggbb</EM>[<STRONG>:</STRONG><EM>legend</EM>]]
-
 [<STRONG>LINE</STRONG>{<STRONG>1</STRONG>|<STRONG>2</STRONG>|<STRONG>3</STRONG>}<STRONG>:</STRONG><EM>vname</EM>[<STRONG>#</STRONG><EM>rrggbb</EM>[<STRONG>:</STRONG><EM>legend</EM>]]]
-
 [<STRONG>AREA:</STRONG><EM>vname</EM>[<STRONG>#</STRONG><EM>rrggbb</EM>[<STRONG>:</STRONG><EM>legend</EM>]]]
-
-[<STRONG>STACK:</STRONG><EM>vname</EM>[<STRONG>#</STRONG><EM>rrggbb</EM>[<STRONG>:</STRONG><EM>legend</EM>]]]
-
-
-
+[<STRONG>STACK:</STRONG><EM>vname</EM>[<STRONG>#</STRONG><EM>rrggbb</EM>[<STRONG>:</STRONG><EM>legend</EM>]]]</P>
 <P>
 <HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-The <STRONG>graph</STRONG> functions main purpose is to create graphical representations of the data
-stored in one or several <STRONG>RRD</STRONG>s. Apart from generating graphs, it can also extract numerical reports.
-
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>The <STRONG>graph</STRONG> functions main purpose is to create graphical
+representations of the data stored in one or several <STRONG>RRD</STRONG>s. Apart
+from generating graphs, it can also extract numerical reports.</P>
 <DL>
-<DT><STRONG><A NAME="item_filename">filename</A></STRONG><DD>
-<P>
-The name of the graph to generate. Since <STRONG>rrdtool</STRONG> outputs GIFs and PNGs, it's recommended that the filename end in either
-<EM>.gif</EM> or <EM>.png</EM>.  <STRONG>rrdtool</STRONG> does not enforce this, however. If the  <EM>filename</EM> is set to '-' the image file will be written to standard out. All other
-output will get suppressed.
-
-<P>
-PNG output is recommended, since it takes up to 40% less disk space and
-20-30% less time to generate than a GIF file.
-
-<P>
-If no graph functions are called, the graph will not be created.
-
-<DT><STRONG><A NAME="item__s_start">-s|--start seconds (default end-1day)</A></STRONG><DD>
-<P>
-The time when the graph should begin. Time in seconds since epoch
-(1970-01-01) is required. Negative numbers are relative to the current
-time. By default one day worth of data will be graphed. See also AT-STYLE
-TIME SPECIFICATION section in the <EM>rrdfetch</EM>
+<DT><STRONG><A NAME="item_filename"><EM>filename</EM></A></STRONG><BR>
+<DD>
+The name of the graph to generate. Since <STRONG>rrdtool</STRONG> outputs
+GIFs and PNGs, it's recommended that the filename end in either
+<EM>.gif</EM> or <EM>.png</EM>.  <STRONG>rrdtool</STRONG> does not enforce this, however.
+If the  <EM>filename</EM> is set to '-' the image file will be written
+to standard out.  All other output will get suppressed.
+<P>PNG output is recommended, since it takes up to 40% less disk space
+and 20-30% less time to generate than a GIF file.</P>
+<P>If no graph functions are called, the graph will not be created.</P>
+<P></P>
+<DT><STRONG><A NAME="item_seconds"><STRONG>-s</STRONG>|<STRONG>--start</STRONG> <EM>seconds</EM> (default end-1day)</A></STRONG><BR>
+<DD>
+The time when the graph should begin. Time in seconds since
+epoch (1970-01-01) is required. Negative numbers are relative to the
+current time. By default one day worth of data will be graphed.
+See also AT-STYLE TIME SPECIFICATION section in the <EM>rrdfetch</EM>
 documentation for a detailed explanation on how to specify time.
-
-<DT><STRONG><A NAME="item__e_end">-e|--end seconds (default now)</A></STRONG><DD>
-<P>
-The time when the graph should end. Time in seconds since epoch. See also
-AT-STYLE TIME SPECIFICATION section in the <EM>rrdfetch</EM>
+<P></P>
+<DT><STRONG><STRONG>-e</STRONG>|<STRONG>--end</STRONG> <EM>seconds</EM> (default now)</STRONG><BR>
+<DD>
+The time when the graph should end. Time in seconds since epoch.
+See also AT-STYLE TIME SPECIFICATION section in the <EM>rrdfetch</EM>
 documentation for a detailed explanation of ways to specify time.
-
-<DT><STRONG><A NAME="item__x_x_grid">-x|--x-grid x-axis grid and label (default autoconfigure)</A></STRONG><DD>
-<P>
-The x-axis label is quite complex to configure. So if you don't have very
-special needs, you can rely on the autoconfiguration to get this right.
-
-<P>
-The x-axis label is configured, using the following format:
-
-<P>
-<EM>GTM</EM><STRONG>:</STRONG><EM>GST</EM><STRONG>:</STRONG><EM>MTM</EM><STRONG>:</STRONG><EM>MST</EM><STRONG>:</STRONG><EM>LTM</EM>:<EM>LST</EM><STRONG>:</STRONG><EM>LPR</EM><STRONG>:</STRONG><EM>LFM</EM>
-
-
-
-<P>
-You have to configure three elements making up the x-axis labels and grid.
-The base grid (<EM>G??</EM>), the major grid (<EM>M??</EM>) and the labels (<EM>L??</EM>). The configuration is based on the idea that you first specify a well
-known amount of time (<EM>?TM</EM>) and then say how many times it has to pass between each grid line or
-label (<EM>?ST</EM>). For the label you have to define two additional items: The precision of
-the label in seconds (<EM>LPR</EM>) and the strftime format used to generate the text of the label (<EM>LFM</EM>).
-
-<P>
-The <EM>?TM</EM> elements must be one of the following keywords: <STRONG>SECOND</STRONG>,
-<STRONG>MINUTE</STRONG>, <STRONG>HOUR</STRONG>, <STRONG>DAY</STRONG>, <STRONG>WEEK</STRONG>, <STRONG>MONTH</STRONG> or <STRONG>YEAR</STRONG>.
-
-<P>
-If you wanted a graph with a base grid every 10 minutes and a major one
-every hour, with labels every hour you would use the following x-axis
-definition.
-
-<P>
-<CODE>MINUTE:10:HOUR:1:HOUR:1:0:%X</CODE>
-
-
-
-<P>
-The precision in this example is 0 because the <CODE>%X</CODE> format is
-exact. If the label was the name of the day, we would have had a precision
-of 24 hours, because when you say something like 'Monday' you mean the
-whole day and not Monday morning 00:00. Thus the label should be positioned
-at noon. By defining a precision of 24 hours or rather 86400 seconds, you
-make sure that this happens.
-
-<DT><STRONG><A NAME="item__y_y_grid">-y|--y-grid grid step:label factor (default autoconfigure)</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_label"><STRONG>-x</STRONG>|<STRONG>--x-grid</STRONG> <EM>x-axis grid and label</EM> (default autoconfigure)</A></STRONG><BR>
+<DD>
+The x-axis label is quite complex to configure. So if you don't have
+very special needs, you can rely on the autoconfiguration to get this
+right.
+<P>If you want no x-grid at all, use the magic setting <STRONG>none</STRONG>.</P>
+<P>The x-axis label and grid can be configured, using the following format:</P>
+<P><EM>GTM</EM><STRONG>:</STRONG><EM>GST</EM><STRONG>:</STRONG><EM>MTM</EM><STRONG>:</STRONG><EM>MST</EM><STRONG>:</STRONG><EM>LTM</EM>:<EM>LST</EM><STRONG>:</STRONG><EM>LPR</EM><STRONG>:</STRONG><EM>LFM</EM></P>
+<P>You have to configure three elements making up the x-axis labels and
+grid. The base grid (<EM>G??</EM>), the major grid (<EM>M??</EM>) and the labels
+(<EM>L??</EM>). The configuration is based on the idea that you first
+specify a well known amount of time (<EM>?TM</EM>) and then say how many
+times it has to pass between each grid line or label (<EM>?ST</EM>). For the
+label you have to define two additional items: The precision of the
+label in seconds (<EM>LPR</EM>) and the strftime format used to generate the
+text of the label (<EM>LFM</EM>).</P>
+<P>The <EM>?TM</EM> elements must be one of the following keywords: <STRONG>SECOND</STRONG>,
+<STRONG>MINUTE</STRONG>, <STRONG>HOUR</STRONG>, <STRONG>DAY</STRONG>, <STRONG>WEEK</STRONG>, <STRONG>MONTH</STRONG> or <STRONG>YEAR</STRONG>.</P>
+<P>If you wanted a graph with a base grid every 10 minutes and a major
+one every hour, with labels every hour you would use the following
+x-axis definition.</P>
+<P><CODE>MINUTE:10:HOUR:1:HOUR:1:0:%X</CODE></P>
+<P>The precision in this example is 0 because the %X format is exact. If
+the label was the name of the day, we would have had a precision of 24
+hours, because when you say something like 'Monday' you mean the whole
+day and not Monday morning 00:00. Thus the label should be positioned
+at noon. By defining a precision of 24 hours or rather 86400 seconds,
+you make sure that this happens.</P>
+<P></P>
+<DT><STRONG><A NAME="item_factor"><STRONG>-y</STRONG>|<STRONG>--y-grid</STRONG> <EM>grid step</EM>:<EM>label factor</EM> (default autoconfigure)</A></STRONG><BR>
+<DD>
 Makes vertical grid lines appear at <EM>grid step</EM> interval. Every
-<EM>label factor</EM> gridstep, a major grid line is printed, along with label showing the value
-of the grid line.
-
-<DT><STRONG><A NAME="item__alt_y_grid">--alt-y-grid</A></STRONG><DD>
-<P>
-Place Y grid dynamically based on graph Y range. Algorithm ensures that you
-always have grid, that there are enough but not too many grid lines and the
-grid is metric. That is grid lines are placed every 1, 2, 5 or 10 units.
-(contributed by Sasha Mikheev)
-
-<DT><STRONG><A NAME="item__alt_autoscale">--alt-autoscale</A></STRONG><DD>
-<P>
-Compute Y range based on function absolute minimum and maximum values.
-Default algorithm uses predefined set of ranges. This is good in many cases
-but it fails miserably when you need to graph something like 260 + 0.001 *
-<CODE>sin(x).</CODE> Default algorithm will use Y range from 250 to 300 and
-on the graph you will see almost straight line. With --alt-autoscale Y
-range will be from slightly less the 260 - 0.001 to slightly more then 260
-+ 0.001 and periodic behavior will be seen. (contributed by Sasha Mikheev)
-
-<DT><STRONG><A NAME="item__v_vertical_label">-v|--vertical-label text</A></STRONG><DD>
-<P>
+<EM>label factor</EM> gridstep, a major grid line is printed, along with
+label showing the value of the grid line.
+<P>If you want no y-grid at all set specify the magic word <STRONG>none</STRONG>.</P>
+<P></P>
+<DT><STRONG><A NAME="item_%2D%2Dalt%2Dy%2Dgrid"><STRONG>--alt-y-grid</STRONG></A></STRONG><BR>
+<DD>
+Place Y grid dynamically based on graph Y range. Algorithm ensures
+that you always have grid, that there are enough but not too many
+grid lines and the grid is metric. That is grid lines are placed 
+every 1, 2, 5 or 10 units.  (contributed by Sasha Mikheev)
+<P></P>
+<DT><STRONG><A NAME="item_%2D%2Dalt%2Dautoscale"><STRONG>--alt-autoscale</STRONG></A></STRONG><BR>
+<DD>
+Compute Y range  based on function absolute minimum and 
+maximum values. Default algorithm uses predefined set of ranges.  
+This is good in many cases but it fails miserably when you need
+to graph something like 260 + 0.001 * sin(x). Default algorithm 
+will use Y range from 250 to 300 and on the graph you will see
+almost straight line. With --alt-autoscale Y range will be
+from slightly less the 260 - 0.001 to slightly more then 260 + 0.001
+and periodic behavior will be seen.   (contributed by Sasha Mikheev)
+<P></P>
+<DT><STRONG><A NAME="item_%2D%2Dalt%2Dautoscale%2Dmax"><STRONG>--alt-autoscale-max</STRONG></A></STRONG><BR>
+<DD>
+Where --alt-autoscale will modify both the absolute maximum AND minimum
+values, this option will only affect the maximum value. The minimum 
+value, if not defined on the command line, will be 0. This option can
+be useful when graphing router traffic when the WAN line uses compression,
+and thus the throughput may be higher than the WAN line speed.
+<P></P>
+<DT><STRONG><A NAME="item_value"><STRONG>--units-exponent</STRONG> <EM>value</EM> (default autoconfigure)</A></STRONG><BR>
+<DD>
+This sets the 10**exponent scaling of the y-axis values.  Normally
+values will be scaled to the appropriate units (k, M, etc.).  However
+you may wish to display units always in k (Kilo, 10e3) even if the data
+is in the M (Mega, 10e6) range for instance.  Value should be an
+integer which is a multiple of 3 between -18 and 18 inclusive.  It is
+the exponent on the units you which to use.  For example, use 3 to
+display the y-axis values in k (Kilo, 10e3, thousands), use -6 to
+display the y-axis values in u (Micro, 10e-6, millionths).  Use a value
+of 0 to prevent any scaling of the y-axis values.
+<P></P>
+<DT><STRONG><A NAME="item_%2Dv%7C%2D%2Dvertical%2Dlabel_text"><STRONG>-v</STRONG>|<STRONG>--vertical-label</STRONG> <EM>text</EM></A></STRONG><BR>
+<DD>
 vertical label on the left side of the graph. This is normally used to
 specify the units used.
-
-<DT><STRONG><A NAME="item__w_width">-w|--width pixels (default 400 pixel)</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_pixels"><STRONG>-w</STRONG>|<STRONG>--width</STRONG> <EM>pixels</EM> (default 400 pixel)</A></STRONG><BR>
+<DD>
 Width of the drawing area within the graph. This affects the size of the
 gif.
-
-<DT><STRONG><A NAME="item__h_height">-h|--height pixels (default 100 pixel)</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><STRONG>-h</STRONG>|<STRONG>--height</STRONG> <EM>pixels</EM> (default 100 pixel)</STRONG><BR>
+<DD>
 Width of the drawing area within the graph. This affects the size of the
 gif.
-
-<DT><STRONG><A NAME="item__i_interlaced">-i|--interlaced (default: false)</A></STRONG><DD>
-<P>
-If you set this option, then the resulting GIF will be interlaced. Most web
-browsers display these incrementally as they load. If you do not use this
-option, the GIFs default to being progressive scanned. The only effect of
-this option is to control the format of the GIF on disk. It makes no
-changes to the layout or contents of the graph.
-
-<DT><STRONG><A NAME="item__f_imginfo">-f|--imginfo formatstring</A></STRONG><DD>
-<P>
-After the image has been created, the graph function uses printf together
-with this format string to create output similar to the PRINT function,
-only that the printf is supplied with the parameters
-<EM>filename</EM>, <EM>xsize</EM> and <EM>ysize</EM>. In order to generate an <STRONG>IMG</STRONG> tag suitable for including the graph into a web page, the command line
+<P></P>
+<DT><STRONG><A NAME="item_interlaced"><STRONG>-i</STRONG>|<STRONG>--interlaced</STRONG> (default: false)</A></STRONG><BR>
+<DD>
+If you set this option, then the resulting GIF will be interlaced.
+Most web browsers display these incrementally as they load. If
+you do not use this option, the GIFs default to being progressive
+scanned. The only effect of this option is to control the format
+of the GIF on disk. It makes no changes to the layout or contents
+of the graph.
+<P></P>
+<DT><STRONG><A NAME="item_%2Df%7C%2D%2Dimginfo_formatstring"><STRONG>-f</STRONG>|<STRONG>--imginfo</STRONG> <EM>formatstring</EM></A></STRONG><BR>
+<DD>
+After the image has been created, the graph function uses printf
+together with this format string to create output similar to the PRINT
+function, only that the printf is supplied with the parameters
+<EM>filename</EM>, <EM>xsize</EM> and <EM>ysize</EM>. In order to generate an <STRONG>IMG</STRONG> tag
+suitable for including the graph into a web page, the command line
 would look like this:
-
-<P>
-<PRE> --imginfo '&lt;IMG SRC=&quot;/img/%s&quot; WIDTH=&quot;%lu&quot; HEIGHT=&quot;%lu&quot; ALT=&quot;Demo&quot;&gt;'
-</PRE>
-<DT><STRONG><A NAME="item__a_imgformat">-a|--imgformat GIF|PNG (default: GIF)</A></STRONG><DD>
-<P>
-Allows you to produce PNG output from rrdtool. 
-
-<DT><STRONG><A NAME="item__z_lazy">-z|--lazy (default: false)</A></STRONG><DD>
-<P>
-Only generate the graph, if the current gif is out of date or not existent.
-
-<DT><STRONG><A NAME="item__u_upper_limit">-u|--upper-limit value (default autoconfigure)</A></STRONG><DD>
-<P>
-This is not the upper limit of a graph! But rather, this is the minimum
-upper bound of a graph. Use this to expand graphs up. For example, the
-value 100 will result in graphs that have a upper bound of 100 or more.
-Setting the upper limit to the maximum value for some DS will result in
-disabling RRDtool's autoscaling down (ie it will ``expand'' graphs up.) To
-disable RRDtool's autoscaling up (to the max value for the DSs graphed),
-use a nifty CDEF like so: CDEF:mcpu=cpu,100,GT,100,cpu,IF. If this CDEF is
-applied to all DSs in a graph, then the graph will have an upper limit of
-100.
-
-<DT><STRONG><A NAME="item__l_lower_limit">-l|--lower-limit value (default autoconfigure)</A></STRONG><DD>
-<P>
-This is not the lower limit of a graph. But rather, this is the maximum
-lower bound of a graph. For example, the value -100 will result in a graph
-that has a lower limit of -100 or less. Use this keyword to expand graphs
-down.
-
-<DT><STRONG><A NAME="item__r_rigid">-r|--rigid</A></STRONG><DD>
-<P>
-rigid boundaries mode. Normally rrdgraph will automatically expand the
+<PRE>
+ --imginfo '&lt;IMG SRC=&quot;/img/%s&quot; WIDTH=&quot;%lu&quot; HEIGHT=&quot;%lu&quot; ALT=&quot;Demo&quot;&gt;'</PRE>
+<P></P>
+<DT><STRONG><A NAME="item_PNG"><STRONG>-a</STRONG>|<STRONG>--imgformat</STRONG> <STRONG>GIF</STRONG>|<STRONG>PNG</STRONG> (default: GIF)</A></STRONG><BR>
+<DD>
+Allows you to produce PNG output from rrdtool.
+<P></P>
+<DT><STRONG><A NAME="item_lazy"><STRONG>-z</STRONG>|<STRONG>--lazy</STRONG> (default: false)</A></STRONG><BR>
+<DD>
+Only generate the graph, if the current gif is out of date or not
+existent.
+<P></P>
+<DT><STRONG><STRONG>-u</STRONG>|<STRONG>--upper-limit</STRONG> <EM>value</EM> (default autoconfigure)</STRONG><BR>
+<DD>
+Defines the value normally located at the upper border of the
+graph. If the graph contains higher values, the upper border will
+move upwards to accomodate these values as well.
+<P>If you want to define an upper-limit which will not move in any
+event you have to set the <STRONG>--rigid</STRONG> option as well.</P>
+<P></P>
+<DT><STRONG><STRONG>-l</STRONG>|<STRONG>--lower-limit</STRONG> <EM>value</EM> (default autoconfigure)</STRONG><BR>
+<DD>
+This is not the lower limit of a graph.  But rather, this is the
+maximum lower bound of a graph.  For example, the value -100 will
+result in a graph that has a lower limit of -100 or less.  Use this
+keyword to expand graphs down.
+<P></P>
+<DT><STRONG><A NAME="item_%2Dr%7C%2D%2Drigid"><STRONG>-r</STRONG>|<STRONG>--rigid</STRONG></A></STRONG><BR>
+<DD>
+rigid boundaries mode.  Normally rrdgraph will automatically expand the
 lower and upper limit if the graph contains a value outside the valid
 range. With the r option you can disable this behavior
-
-<DT><STRONG><A NAME="item__b_base">-b|--base value</A></STRONG><DD>
-<P>
-if you are graphing memory (and NOT network traffic) this switch should be
-set to 1024 so that one Kb is 1024 byte. For traffic measurement, 1 kb/s is
-1000 b/s.
-
-<DT><STRONG><A NAME="item__o_logarithmic">-o|--logarithmic</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_%2Db%7C%2D%2Dbase_value"><STRONG>-b</STRONG>|<STRONG>--base</STRONG> <EM>value</EM></A></STRONG><BR>
+<DD>
+if you are graphing memory (and NOT network traffic) this switch
+should be set to 1024 so that one Kb is 1024 byte. For traffic
+measurement, 1 kb/s is 1000 b/s.
+<P></P>
+<DT><STRONG><A NAME="item_%2Do%7C%2D%2Dlogarithmic"><STRONG>-o</STRONG>|<STRONG>--logarithmic</STRONG></A></STRONG><BR>
+<DD>
 logarithmic y-axis scaling
-
-<DT><STRONG><A NAME="item__c_color">-c|--color COLORTAG#rrggbb (default colors)</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_rrggbb"><STRONG>-c</STRONG>|<STRONG>--color</STRONG> <EM>COLORTAG</EM><STRONG>#</STRONG><EM>rrggbb</EM> (default colors)</A></STRONG><BR>
+<DD>
 override the colors for the standard elements of the graph. The <EM>COLORTAG</EM>
 must be one of the following symbolic names: <STRONG>BACK</STRONG> ground, <STRONG>CANVAS</STRONG>,
 <STRONG>SHADEA</STRONG> left/top border, <STRONG>SHADEB</STRONG> right/bottom border, <STRONG>GRID</STRONG>, <STRONG>MGRID</STRONG>
-major grid, <STRONG>FONT</STRONG>, <STRONG>FRAME</STRONG> and axis of the graph or <STRONG>ARROW</STRONG>. This option can be called multiple times to set several colors.
-
-<DT><STRONG><A NAME="item__t_title">-t|--title text (default no title)</A></STRONG><DD>
-<P>
+major grid, <STRONG>FONT</STRONG>, <STRONG>FRAME</STRONG> and axis of the graph or <STRONG>ARROW</STRONG>. This option
+can be called multiple times to set several colors.
+<P></P>
+<DT><STRONG><A NAME="item_%2Dg%7C%2D%2Dno%2Dlegend"><STRONG>-g</STRONG>|<STRONG>--no-legend</STRONG></A></STRONG><BR>
+<DD>
+Suppress generation of legend; only render the graph.
+<P></P>
+<DT><STRONG><A NAME="item_text"><STRONG>-t</STRONG>|<STRONG>--title</STRONG> <EM>text</EM> (default no title)</A></STRONG><BR>
+<DD>
 Define a title to be written into the graph
-
-<DT><STRONG><A NAME="item_DEF">DEF:vname=rrd:ds-name:CF</A></STRONG><DD>
-<P>
-Define virtual name for a data source. This name can then be used in the
-functions explained below. The DEF call automatically chooses an <STRONG>RRA</STRONG> which contains <EM>CF</EM> consolidated data in a resolution appropriate for the size of the graph to
-be drawn. Ideally this means that one data point from the <STRONG>RRA</STRONG> should be represented by one pixel in the graph. If the resolution of the <STRONG>RRA</STRONG> is higher than the resolution of the graph, the data in the RRA will be
-further consolidated according to the consolidation function (<EM>CF</EM>) chosen.
-
-<DT><STRONG><A NAME="item_CDEF">CDEF:vname=rpn-expression</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><STRONG>--step</STRONG> <EM>value</EM> (default automatic)</STRONG><BR>
+<DD>
+By default rrdgraph calculates the width of one pixle in the time domain and
+tries to get data at that resolution from the RRD. With this switch you can
+override this behaviour. If you want rrdgraph to get data at 1 hour
+resolution from the RRD, then you can set the step to 3600 seconds. Note,
+that a step smaller than 1 pixle will be silently ignored.
+<P></P>
+<DT><STRONG><A NAME="item_DEF%3Avname%3Drrd%3Ads%2Dname%3ACF"><STRONG>DEF:</STRONG><EM>vname</EM><STRONG>=</STRONG><EM>rrd</EM><STRONG>:</STRONG><EM>ds-name</EM><STRONG>:</STRONG><EM>CF</EM></A></STRONG><BR>
+<DD>
+Define virtual name for a data source. This name can then be used
+in the functions explained below. The
+DEF call automatically chooses an <STRONG>RRA</STRONG> which contains <EM>CF</EM> consolidated data in a
+resolution appropriate for the size of the graph to be drawn.  Ideally
+this means that one data point from the <STRONG>RRA</STRONG> should be represented
+by one pixel in the graph.  If the resolution of the <STRONG>RRA</STRONG> is higher
+than the resolution of the graph, the data in the RRA will be further
+consolidated according to the consolidation function (<EM>CF</EM>) chosen.
+<P></P>
+<DT><STRONG><A NAME="item_CDEF%3Avname%3Drpn%2Dexpression"><STRONG>CDEF:</STRONG><EM>vname</EM><STRONG>=</STRONG><EM>rpn-expression</EM></A></STRONG><BR>
+<DD>
 Create a new virtual data source by evaluating a mathematical expression,
-specified in Reverse Polish Notation (RPN). If you have ever used a
-traditional HP calculator you already know RPN. The idea behind RPN
-notation is, that you have a stack and push your data onto this stack. When
-ever you execute an operation, it takes as many data values from the stack
-as needed. The pushing of data is implicit, so when ever you specify a
-number or a variable, it gets pushed automatically. 
-
-<P>
-If this is all a big load of incomprehensible words for you, maybe an
-example helps (a more complete explanation is given in [1]): The expression <EM>vname+3/2</EM> becomes <CODE>vname,3,2,/,+</CODE> in RPN. First the three values get pushed onto the stack (which now
-contains (the current value of) vname, a 3 and a 2). Then the / operator
-pops two values from the stack (3 and 2), divides the first argument by the
-second (3/2) and pushes the result (1.5) back onto the stack. Then the +
-operator pops two values (vname and 1.5) from the stack; both values are
-added up and the result gets pushes back onto the stack. In the end there
-is only one value left on the stack: The result of the expression.
-
-<P>
-The <EM>rpn-expression</EM> in the <STRONG>CDEF</STRONG> function takes both, constant values as well as <EM>vname</EM> variables. The following operators can be used on these values: 
-
+specified in Reverse Polish Notation (RPN). If you have ever used a traditional
+HP calculator you already know RPN. The idea behind RPN notation is, 
+that you have a stack and push your data onto this stack. When ever
+you execute an operation, it takes as many data values from the stack
+as needed. The pushing of data is implicit, so when ever you specify a number
+or a variable, it gets pushed automatically.
+<P>If this is all a big load of incomprehensible words for you, maybe an
+example helps (a more complete explanation is given in [1]): The
+expression <EM>vname+3/2</EM> becomes <CODE>vname,3,2,/,+</CODE> in RPN. First the three
+values get pushed onto the stack (which now contains (the current
+value of) vname, a 3 and a 2).  Then the / operator pops two values
+from the stack (3 and 2), divides the first argument by the second
+(3/2) and pushes the result (1.5) back onto the stack. Then the +
+operator pops two values (vname and 1.5) from the stack; both values
+are added up and the result gets pushes back onto the stack. In the
+end there is only one value left on the stack: The result of the
+expression.</P>
+<P>The <EM>rpn-expression</EM> in the <STRONG>CDEF</STRONG> function takes both, constant values
+as well as <EM>vname</EM> variables. The following operators can be used on these
+values:</P>
 <DL>
-<DT><STRONG><A NAME="item__">+, -, *, /, %</A></STRONG><DD>
-<P>
-pops two values from the stack applies the selected operator and pushes the
-result back onto the stack. The % operator stands for the modulo operation.
-
-<DT><STRONG><A NAME="item_SIN">SIN, COS, LOG, EXP</A></STRONG><DD>
-<P>
-pops one value from the stack, applies the selected function and pushes the
-result back onto the stack.
-
-<DT><STRONG><A NAME="item_LT">LT, LE, GT, GE, EQ</A></STRONG><DD>
-<P>
+<DT><STRONG><A NAME="item_%2B%2C_%2D%2C_%2A%2C_%2F%2C_%25">+, -, *, /, %</A></STRONG><BR>
+<DD>
+pops two values from the stack applies the selected operator and pushes 
+the result back onto the stack. The % operator stands for the modulo
+operation.
+<P></P>
+<DT><STRONG><A NAME="item_SIN%2C_COS%2C_LOG%2C_EXP%2C_FLOOR%2C_CEIL">SIN, COS, LOG, EXP, FLOOR, CEIL</A></STRONG><BR>
+<DD>
+pops one value from the stack, applies the selected function and pushes
+the result back onto the stack.
+<P></P>
+<DT><STRONG><A NAME="item_LT%2C_LE%2C_GT%2C_GE%2C_EQ">LT, LE, GT, GE, EQ</A></STRONG><BR>
+<DD>
 pops two values from the stack, compares them according to the selected
 condition and pushes either 1 back onto the stack if the condition is true
 and 0 if the condition was not true.
-
-<DT><STRONG><A NAME="item_IF">IF</A></STRONG><DD>
-<P>
-pops three values from the stack. If the last value is not 0, the second
-value will be pushed back onto the stack, otherwise the first value is
-pushed back.
-
-<P>
-If the stack contains the values A, B, C, D, E are presently on the stack,
-the IF operator will pop the values E D and C of the stack. It will look at
-C and if it is not 0 it will push D back onto the stack, otherwise E will
-be sent back to the stack.
-
-<DT><STRONG><A NAME="item_DUP">DUP, EXC, POP</A></STRONG><DD>
-<P>
-These manipulate the stack directly. DUP will duplicate the top of the
-stack, pushing the result back onto the stack. EXC will exchange the top
+<P></P>
+<DT><STRONG><A NAME="item_IF">IF</A></STRONG><BR>
+<DD>
+pops three values from the stack. If the last value is not 0, the
+second value will be pushed back onto the stack, otherwise the
+first value is pushed back.
+<P>If the stack contains the values A, B, C, D, E are presently on the
+stack, the IF operator will pop the values E D and C of the stack. It will
+look at C and if it is not 0 it will push D back onto the stack, otherwise
+E will be sent back to the stack.</P>
+<P></P>
+<DT><STRONG><A NAME="item_MIN%2C_MAX">MIN, MAX</A></STRONG><BR>
+<DD>
+selects the lesser or larger of the two top stack values respectively
+<P></P>
+<DT><STRONG><A NAME="item_LIMIT">LIMIT</A></STRONG><BR>
+<DD>
+replaces the value with <EM>*UNKNOWN*</EM> if it is outside the limits specified
+by the two values above it on the stack.
+<PRE>
+ CDEF:a=alpha,0,100,LIMIT</PRE>
+<P></P>
+<DT><STRONG><A NAME="item_DUP%2C_EXC%2C_POP">DUP, EXC, POP</A></STRONG><BR>
+<DD>
+These manipulate the stack directly.  DUP will duplicate the top of the
+stack, pushing the result back onto the stack.  EXC will exchange the top
 two elements of the stack, and POP will pop off the top element of the
-stack. Having insufficient elements on the stack for these operations is an
-error.
-
-<DT><STRONG><A NAME="item_UN">UN</A></STRONG><DD>
-<P>
-Pops one value off the stack, if it is <EM>*UNKNOWN*</EM>, 1 will be pushed back otherwise 0.
-
-<DT><STRONG><A NAME="item_UNKN">UNKN</A></STRONG><DD>
-<P>
+stack.  Having insufficient elements on the stack for these operations is
+an error.
+<P></P>
+<DT><STRONG><A NAME="item_UN">UN</A></STRONG><BR>
+<DD>
+Pops one value off the stack, if it is <EM>*UNKNOWN*</EM>, 1 will be pushed
+back otherwise 0.
+<P></P>
+<DT><STRONG><A NAME="item_UNKN">UNKN</A></STRONG><BR>
+<DD>
 Push an <EM>*UNKNOWN*</EM> value onto the stack.
-
-<DT><STRONG><A NAME="item_PREV">PREV</A></STRONG><DD>
-<P>
-Push <EM>*UNKNOWN*</EM> if its at the first value of a data set or otherwise the value of this CDEF
-at the previous time step. This allows you to perform calculations across
-the data.
-
-<DT><STRONG><A NAME="item_INF">INF, NEGINF</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_PREV">PREV</A></STRONG><BR>
+<DD>
+Push <EM>*UNKNOWN*</EM> if its at the first value of a data set or otherwise
+the value of this CDEF at the previous time step. This allows you to
+perform calculations across the data.
+<P></P>
+<DT><STRONG><A NAME="item_INF%2C_NEGINF">INF, NEGINF</A></STRONG><BR>
+<DD>
 Push a positive or negative infinite (oo) value onto the stack. When
-drawing an infinite number it appears right at the top or bottom edge of
-the graph, depending whether you have a positive or negative infinite
-number.
-
-<DT><STRONG><A NAME="item_NOW">NOW</A></STRONG><DD>
-<P>
+drawing an infinite number it appears right at the top or bottom edge of the
+graph, depending whether you have a positive or negative infinite number.
+<P></P>
+<DT><STRONG><A NAME="item_NOW">NOW</A></STRONG><BR>
+<DD>
 Push the current (real world) time onto the stack.
-
-<DT><STRONG><A NAME="item_TIME">TIME</A></STRONG><DD>
-<P>
-Push the time the current sample was taken onto the stack.
-
-</DL>
-<P>
-Please note that you may only use <EM>vname</EM> variables that you previously defined by either <STRONG>DEF</STRONG> or <STRONG>CDEF</STRONG>. Furthermore, as of this writing (version 0.99.25), you must use at least
-one <EM>vname</EM>
+<P></P>
+<DT><STRONG><A NAME="item_TIME">TIME</A></STRONG><BR>
+<DD>
+Push the time the current sample was taken onto the stack. This is the
+number of non-skip seconds since 0:00:00 January 1, 1970.
+<P></P>
+<DT><STRONG><A NAME="item_LTIME">LTIME</A></STRONG><BR>
+<DD>
+This is like TIME <STRONG>+ current timezone offset in seconds</STRONG>. The current
+offset takes daylight saving time into account, given your OS supports
+this. If you were looking at a sample, in Zurich, in summer, the
+offset would be 2*3600 seconds, as Zurich at that time of year is 2
+hours ahead of UTC.
+<P>Note that the timezone offset is always calculated for the time the
+current sample was taken at. It has nuthing todo with the time you are
+doing the calculation.</P>
+<P></P></DL>
+<P>Please note that you may only use <EM>vname</EM> variables that you
+previously defined by either <STRONG>DEF</STRONG> or <STRONG>CDEF</STRONG>. Furthermore, as of
+this writing (version 0.99.25), you must use at least one <EM>vname</EM>
 per expression, that is ``CDEF:fourtytwo=2,40,+'' will yield an error
-message but not a <EM>vname</EM> fourtytwo that's always equal to 42.
-
-<DT><STRONG><A NAME="item_PRINT">PRINT:vname:CF:format</A></STRONG><DD>
-<P>
-Calculate the chosen consolidation function <EM>CF</EM> over the data-source variable <EM>vname</EM> and <CODE>printf</CODE> the result to stdout using <EM>format</EM>. In the <EM>format</EM> string there should be a '%lf' or '%le' marker in the place where the
-number should be printed.
-
-<P>
-If an additional '%s' is found AFTER the marker, the value will be scaled
+message but not a <EM>vname</EM> fourtytwo that's always equal to 42.</P>
+<DT><STRONG><A NAME="item_PRINT%3Avname%3ACF%3Aformat"><STRONG>PRINT:</STRONG><EM>vname</EM><STRONG>:</STRONG><EM>CF</EM><STRONG>:</STRONG><EM>format</EM></A></STRONG><BR>
+<DD>
+Calculate the chosen consolidation function <EM>CF</EM> over the data-source
+variable <EM>vname</EM> and <CODE>printf</CODE> the result to stdout using <EM>format</EM>.
+In the <EM>format</EM> string there should be a '%lf' or '%le' marker in the
+place where the number should be printed.
+<P>If an additional '%s' is found AFTER the marker, the value will be scaled
 and an appropriate SI magnitude unit will be printed in place of the '%s'
-marker. The scaling will take the '--base' argument into consideration!
-
-<P>
-If a '%S' is used instead of a '%s', then instead of calculating the
-appropriate SI magnitude unit for this value, the previously calculated SI
-magnitude unit will be used. This is useful if you want all the values in a
-PRINT statement to have the same SI magnitude unit. If there was no
-previous SI magnitude calculation made, then '%S' behaves like a '%s',
+marker. The scaling will take the '--base' argument into consideration!</P>
+<P>If a '%S' is used instead of a '%s', then instead of calculating the
+appropriate SI magnitude unit for this value, the previously calculated
+SI magnitude unit will be used.  This is useful if you want all the values
+in a PRINT statement to have the same SI magnitude unit.  If there was
+no previous SI magnitude calculation made, then '%S' behaves like a '%s',
 unless the value is 0, in which case it does not remember a SI magnitude
 unit and a SI magnitude unit will only be calculated when the next '%s' is
-seen or the next '%S' for a non-zero value.
-
-<DT><STRONG><A NAME="item_GPRINT">GPRINT:vname:CF:format</A></STRONG><DD>
-<P>
+seen or the next '%S' for a non-zero value.</P>
+<P>If you want to put a '%' into your PRINT string, use '%%' instead.</P>
+<P></P>
+<DT><STRONG><A NAME="item_GPRINT%3Avname%3ACF%3Aformat"><STRONG>GPRINT:</STRONG><EM>vname</EM><STRONG>:</STRONG><EM>CF</EM><STRONG>:</STRONG><EM>format</EM></A></STRONG><BR>
+<DD>
 Same as <STRONG>PRINT</STRONG> but the result is printed into the graph below the legend.
-
-<DT><STRONG><A NAME="item_COMMENT">COMMENT:text</A></STRONG><DD>
-<P>
+<P></P></DL>
+<P><STRONG>Caveat:</STRONG> When using the <STRONG>PRINT</STRONG> and <STRONG>GRPRINT</STRONG> functions to
+calculate data summaries over time periods bounded by the current
+time, it is important to note that the last sample will almost always
+yield a value of UNKNOWN as it lies after the last update time.  This
+can result in slight data skewing, particularly with the <STRONG>AVERAGE</STRONG>
+function.  In order to avoid this, make sure that your end time is at
+least one heartbeat prior to the current time.</P>
+<DL>
+<DT><STRONG><A NAME="item_COMMENT%3Atext"><STRONG>COMMENT:</STRONG><EM>text</EM></A></STRONG><BR>
+<DD>
 Like <STRONG>GPRINT</STRONG> but the <EM>text</EM> is simply printed into the graph.
-
-<DT><STRONG><A NAME="item_HRULE">HRULE:value#rrggbb[:legend]</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_HRULE%3Avalue%23rrggbb%5B%3Alegend%5D"><STRONG>HRULE:</STRONG><EM>value</EM><STRONG>#</STRONG><EM>rrggbb</EM>[<STRONG>:</STRONG><EM>legend</EM>]</A></STRONG><BR>
+<DD>
 Draw a horizontal rule into the graph and optionally add a legend
-
-<DT><STRONG><A NAME="item_VRULE">VRULE:time#rrggbb[:legend]</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_VRULE%3Atime%23rrggbb%5B%3Alegend%5D"><STRONG>VRULE:</STRONG><EM>time</EM><STRONG>#</STRONG><EM>rrggbb</EM>[<STRONG>:</STRONG><EM>legend</EM>]</A></STRONG><BR>
+<DD>
 Draw a vertical rule into the graph and optionally add a legend
-
-<DT><STRONG><A NAME="item_LINE">LINE{1|2|3}:vname[#rrggbb[:legend]]</A></STRONG><DD>
-<P>
-Plot for the requested data, using the color specified. Write a legend into
-the graph. The 3 possible keywords <STRONG>LINE1</STRONG>, <STRONG>LINE2</STRONG>, and <STRONG>LINE3</STRONG> 
-generate increasingly wide lines. If no color is defined, the drawing is
-done 'blind' this is useful in connection with the 
-<STRONG>STACK</STRONG> function when you want to ADD the values of two data-sources without
-showing it in the graph.
-
-<DT><STRONG><A NAME="item_AREA">AREA:vname[#rrggbb[:legend]]</A></STRONG><DD>
-<P>
-Does the same as <STRONG>LINE?</STRONG>, but the area between 0 and the graph will be filled with the color
-specified.
-
-<DT><STRONG><A NAME="item_STACK">STACK:vname[#rrggbb[:legend]]</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_LINE%7B1%7C2%7C3%7D%3Avname%5B%23rrggbb%5B%3Alegen"><STRONG>LINE</STRONG>{<STRONG>1</STRONG>|<STRONG>2</STRONG>|<STRONG>3</STRONG>}<STRONG>:</STRONG><EM>vname</EM>[<STRONG>#</STRONG><EM>rrggbb</EM>[<STRONG>:</STRONG><EM>legend</EM>]]</A></STRONG><BR>
+<DD>
+Plot for the requested data, using the color specified. Write a legend
+into the graph. The 3 possible keywords <STRONG>LINE1</STRONG>, <STRONG>LINE2</STRONG>, and <STRONG>LINE3</STRONG> 
+generate increasingly wide lines. If no color is defined, 
+the drawing is done 'blind' this is useful in connection with the 
+<STRONG>STACK</STRONG> function when you want to ADD the values of two 
+data-sources without showing it in the graph.
+<P></P>
+<DT><STRONG><A NAME="item_AREA%3Avname%5B%23rrggbb%5B%3Alegend%5D%5D"><STRONG>AREA</STRONG>:<EM>vname</EM>[<STRONG>#</STRONG><EM>rrggbb</EM>[<STRONG>:</STRONG><EM>legend</EM>]]</A></STRONG><BR>
+<DD>
+Does the same as <STRONG>LINE?</STRONG>, but the area between 0 and 
+the graph will be filled with the color specified.
+<P></P>
+<DT><STRONG><A NAME="item_STACK%3Avname%5B%23rrggbb%5B%3Alegend%5D%5D"><STRONG>STACK</STRONG>:<EM>vname</EM>[<STRONG>#</STRONG><EM>rrggbb</EM>[<STRONG>:</STRONG><EM>legend</EM>]]</A></STRONG><BR>
+<DD>
 Does the same as <STRONG>LINE?</STRONG>, but the graph gets stacked on top of the previous
-<STRONG>LINE?</STRONG>, <STRONG>AREA</STRONG> or <STRONG>STACK</STRONG> graph. Depending on the type of the previous graph, the <STRONG>STACK</STRONG> will be either a <STRONG>LINE?</STRONG> or an <STRONG>AREA</STRONG>. This obviously implies that the first <STRONG>STACK</STRONG> must be preceded by an
-<STRONG>AREA</STRONG> or <STRONG>LINE?</STRONG> -- you need something to stack something onto in the first place ;) 
-
-<P>
-Note, that when you STACK onto *UNKNOWN* data, rrdtool will not draw any
-graphics ... *UNKNOWN* is not zero ... if you want it to zero then you
-might want to use a CDEF argument with IF and UN functions to turn
-*UNKNOWN* into zero ... =back
-
-<H1><A NAME="NOTES_on_legend_arguments">NOTES on legend arguments</A></H1>
-<H2><A NAME="Escaping_the_colon">Escaping the colon</A></H2>
-<P>
-In a ':' in a <EM>legend</EM> argument will mark the end of the legend. To enter a ':' into a legend, the
-colon must be escaped with a backslash '\:'. Beware, that many environments
-look for backslashes themselves, so it may be necessary to write two
-backslashes so that one is passed onto rrd_graph.
-
-<H2><A NAME="String_Formatting">String Formatting</A></H2>
-<P>
-The text printed below the actual graph can be formated by appending
-special escaped characters at the end of a text. When ever such a character
-occurs, all pending text is pushed onto the graph according to the
-character specified.
-
+<STRONG>LINE?</STRONG>, <STRONG>AREA</STRONG> or <STRONG>STACK</STRONG> graph. Depending on the type of the
+previous graph, the <STRONG>STACK</STRONG> will be either a <STRONG>LINE?</STRONG> or an <STRONG>AREA</STRONG>.
+This obviously implies that the first <STRONG>STACK</STRONG> must be preceded by an
+<STRONG>AREA</STRONG> or <STRONG>LINE?</STRONG> -- you need something to stack something onto in
+the first place ;)
+<P>Note, that when you STACK onto *UNKNOWN* data, rrdtool will not draw
+any graphics ... *UNKNOWN* is not zero ... if you want it to zero
+then you might want to use a CDEF argument with IF and UN functions to
+turn *UNKNOWN* into zero ...</P>
+<P></P></DL>
 <P>
-Valid markers are: <STRONG>\j</STRONG> for justified, <STRONG>\l</STRONG> for left aligned, <STRONG>\r</STRONG> for right aligned and <STRONG>\c</STRONG> for centered. In the next section there is an example showing how to use
-centered formating.
-
+<HR>
+<H1><A NAME="notes on legend arguments">NOTES on legend arguments</A></H1>
 <P>
-Normally there are two space characters inserted between every two items
+<H2><A NAME="escaping the colon">Escaping the colon</A></H2>
+<P>In a ':' in a <EM>legend</EM> argument will mark the end of the legend. To
+enter a ':' into a legend, the colon must be escaped with a backslash '\:'.
+Beware, that many environments look for backslashes themselves, so it may
+be necessary to write two backslashes so that one is passed onto rrd_graph.</P>
+<P>
+<H2><A NAME="string formatting">String Formatting</A></H2>
+<P>The text printed below the actual graph can be formated by appending special
+escaped characters at the end of a text. When ever such a character occurs,
+all pending text is pushed onto the graph according to the character
+specified.</P>
+<P>Valid markers are: <STRONG>\j</STRONG> for justified, <STRONG>\l</STRONG> for left aligned, <STRONG>\r</STRONG> for
+right aligned and <STRONG>\c</STRONG> for centered. In the next section there is an
+example showing how to use centered formating.</P>
+<P>Normally there are two space characters inserted between every two items
 printed into the graph. The space following a string can be suppressed by
-putting a <STRONG>\g</STRONG> at the end of the string. The <STRONG>\g</STRONG> also squshes any space inside the string if it is at the very end of the
-string. This can be used in connection with <STRONG>%s</STRONG> to supress empty unit strings.
-
+putting a <STRONG>\g</STRONG> at the end of the string. The <STRONG>\g</STRONG> also squshes any space
+inside the string if it is at the very end of the string. This can be used
+in connection with <STRONG>%s</STRONG> to supress empty unit strings.</P>
+<PRE>
+ GPRINT:a:MAX:%lf%s\g</PRE>
+<P>A special case is COMMENT:<STRONG>\s</STRONG> this inserts some additional vertical space
+before placing the next row of legends.</P>
 <P>
-<PRE> GPRINT:a:MAX:%lf%s\g
- 
-A special case is COMMENT:B&lt;\s&gt; this inserts some additional vertical space
-before placing the next row of legends.
-</PRE>
-<H1><A NAME="NOTE_on_Return_Values">NOTE on Return Values</A></H1>
-<P>
-Whenever rrd_graph gets called, it prints a line telling the size of the
-gif it has just created to STDOUT. This line looks like this: XSIZExYSIZE.
-
-<H1><A NAME="EXAMPLE_1">EXAMPLE 1</A></H1>
+<HR>
+<H1><A NAME="note on return values">NOTE on Return Values</A></H1>
+<P>Whenever rrd_graph gets called, it prints a line telling the size of
+the gif it has just created to STDOUT. This line looks like this: XSIZExYSIZE.</P>
 <P>
-<PRE>  rrdtool graph demo.gif --title=&quot;Demo Graph&quot; \
+<HR>
+<H1><A NAME="example 1">EXAMPLE 1</A></H1>
+<PRE>
+  rrdtool graph demo.gif --title=&quot;Demo Graph&quot; \
           DEF:cel=demo.rrd:exhaust:AVERAGE \
-          &quot;CDEF:far=cel,32,-,0.55555,*&quot; \
+          &quot;CDEF:far=cel,1.8,*,32,+&quot;&quot; \
           LINE2:cel#00a000:&quot;D. Celsius&quot; \
-          LINE2:far#ff0000:&quot;D. Fahrenheit\c&quot;
-</PRE>
-<H1><A NAME="EXAMPLE_2">EXAMPLE 2</A></H1>
+          LINE2:far#ff0000:&quot;D. Fahrenheit\c&quot;</PRE>
 <P>
-This example demonstrates the syntax for using IF and UN to set
-<EM>*UNKNOWN*</EM> values to 0. This technique is useful if you are aggregating interface data
-where the start dates of the data sets doesn't match.
-
-<P>
-<PRE>  rrdtool graph demo.gif --title=&quot;Demo Graph&quot; \
+<HR>
+<H1><A NAME="example 2">EXAMPLE 2</A></H1>
+<P>This example demonstrates the syntax for using IF and UN to set
+<EM>*UNKNOWN*</EM> values to 0.  This technique is useful if you are
+aggregating interface data where the start dates of the data sets
+doesn't match.</P>
+<PRE>
+  rrdtool graph demo.gif --title=&quot;Demo Graph&quot; \
          DEF:idat1=interface1.rrd:ds0:AVERAGE \
          DEF:idat2=interface2.rrd:ds0:AVERAGE \
          DEF:odat1=interface1.rrd:ds1:AVERAGE \
@@ -520,27 +532,25 @@
          CDEF:aggoutput=odat1,UN,0,odat1,IF,odat2,UN,0,odat2,IF,+,8,* \
          AREA:agginput#00cc00:Input Aggregate \
          LINE1:agginput#0000FF:Output Aggregate
-         
-Assuming that idat1 has a data value of I&lt;*UNKNOWN*&gt;, the CDEF expression 
 </PRE>
-<P>
-<PRE> idat1,UN,0,idat1,IF 
-</PRE>
-<P>
-leaves us with a stack with contents of 1,0,NaN and the IF function will
-pop off the 3 values and replace them with 0. If idat1 had a real value
-like 7942099, then the stack would have 0,0,7942099 and the real value
-would be the replacement.  
+<PRE>
 
-<H1><A NAME="EXAMPLE_3">EXAMPLE 3</A></H1>
+Assuming that idat1 has a data value of I&lt;*UNKNOWN*&gt;, the CDEF expression</PRE>
+<PRE>
+ idat1,UN,0,idat1,IF</PRE>
+<P>leaves us with a stack with contents of 1,0,NaN and the IF function
+will pop off the 3 values and replace them with 0.  If idat1 had a
+real value like 7942099, then the stack would have 0,0,7942099 and the
+real value would be the replacement.</P>
 <P>
-This example shows two ways to use the INF function. First it makes the
-background change color during half of the hours. Then, it uses AREA and
-STACK to draw a picture. If one of the inputs was UNKNOWN, all inputs are
-overlaid with another AREA.
-
-<P>
-<PRE>  rrdtool graph example.png --title=&quot;INF demo&quot; \
+<HR>
+<H1><A NAME="example 3">EXAMPLE 3</A></H1>
+<P>This example shows two ways to use the INF function. First it makes
+the background change color during half of the hours. Then, it uses
+AREA and STACK to draw a picture. If one of the inputs was UNKNOWN,
+all inputs are overlaid with another AREA.</P>
+<PRE>
+  rrdtool graph example.png --title=&quot;INF demo&quot; \
          DEF:val1=some.rrd:ds0:AVERAGE \
          DEF:val2=some.rrd:ds1:AVERAGE \
          DEF:val3=some.rrd:ds2:AVERAGE \
@@ -552,44 +562,30 @@
          STACK:val2#00C000:Value2 \
          STACK:val3#FFFF00:Value3 \
          STACK:val4#FFC000:Value4 \
-         AREA:whipeout#FF0000:Unknown
-</PRE>
-<P>
-The first CDEF uses val4 as a dummy value. It's value is removed
-immediately from the stack. Then a decision is made based on the time that
-a sample was taken. If it is an even hour (UTC time !) then the area will
-be filled. If it is not, the value is set to UNKN and is not plotted.
-
+         AREA:wipeout#FF0000:Unknown</PRE>
+<P>The first CDEF uses val4 as a dummy value. It's value is removed immediately
+from the stack. Then a decision is made based on the time that a sample was
+taken. If it is an even hour (UTC time !) then the area will be filled. If
+it is not, the value is set to UNKN and is not plotted.</P>
+<P>The second CDEF looks if any of val1,val2,val3,val4 is unknown. It does so by
+checking the outcome of sum(val1,val2,val3,val4). Again, INF is returned when
+the condition is true, UNKN is used to not plot the data.</P>
+<P>The different items are plotted in a particular order. First do the background, then use a
+normal area to overlay it with data. Stack the other data until they are all plotted. Last but
+not least, overlay everything with eye-hurting red
+to signal any unknown data.</P>
+<P>Note that this example assumes that your data is in the positive half of the y-axis
+otherwhise you would would have to add NEGINF in order to extend the coverage
+of the rea to whole graph.</P>
 <P>
-The second CDEF looks if any of val1,val2,val3,val4 is unknown. It does so
-by checking the outcome of <CODE>sum(val1,val2,val3,val4).</CODE> Again,
-INF is returned when the condition is true, UNKN is used to not plot the
-data.
-
-<P>
-The different items are plotted in a particular order. First do the
-background, then use a normal area to overlay it with data. Stack the other
-data until they are all plotted. Last but not least, overlay everything
-with eye-hurting red to signal any unknown data.
-
-<P>
-Note that this example assumesthat your data is in the positive half of the
-y-axis otherwhise you would would have to add NEGINF in order to extend the
-coverage of the rea to whole graph.
-
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;
-
-
-
-<H1><A NAME="REFERENCES">REFERENCES</A></H1>
+<HR>
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;</P>
 <P>
-[1] <A
-HREF="http://www.dotpoint.com/xnumber/rpn_or_adl.htm">http://www.dotpoint.com/xnumber/rpn_or_adl.htm</A>
-
+<HR>
+<H1><A NAME="references">REFERENCES</A></H1>
+<P>[1] <A HREF="http://www.dotpoint.com/xnumber/rpn_or_adl.htm">http://www.dotpoint.com/xnumber/rpn_or_adl.htm</A></P>
 
-</DL>
 </BODY>
 
 </HTML>

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdlast.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdlast.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdlast.html	Sat Jul 13 21:26:21 2002
@@ -1,57 +1,46 @@
 <HTML>
 <HEAD>
 <TITLE>rrdlast</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-rrdtool last - Return the date of the last data sample in an <STRONG>RRD</STRONG>
-
-
-
-<P>
+<H1><A NAME="name">NAME</A></H1>
+<P>rrdtool last - Return the date of the last data sample in an <STRONG>RRD</STRONG></P>
+<div align="right"><a href="rrdlast.pdf">PDF</a> version.</div><P>
 <HR>
-<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
-<P>
-<STRONG>rrdtool</STRONG>  <STRONG>last</STRONG>  <EM>filename</EM>
-
-
-
+<H1><A NAME="synopsis">SYNOPSIS</A></H1>
+<P><STRONG>rrdtool</STRONG> <STRONG>last</STRONG> <EM>filename</EM></P>
 <P>
 <HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-The <STRONG>last</STRONG> function returns the UNIX timestamp when the RRD was last updated.
-
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>The <STRONG>last</STRONG> function returns the UNIX timestamp when the RRD was last
+updated.</P>
 <DL>
-<DT><STRONG><A NAME="item_filename">filename</A></STRONG><DD>
-<P>
+<DT><STRONG><A NAME="item_filename"><EM>filename</EM></A></STRONG><BR>
+<DD>
 The name of the <STRONG>RRD</STRONG> that contains the data.
-
-</DL>
+<P></P></DL>
 <P>
 <HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-Russ Wright &lt;<A
-HREF="mailto:rwwright at home.com">rwwright at home.com</A>&gt;
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Russ Wright &lt;<A HREF="mailto:rwwright at home.com">rwwright at home.com</A>&gt;</P>
 
 </BODY>
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.html	Sat Jul 13 21:26:22 2002
@@ -1,329 +1,258 @@
 <HTML>
 <HEAD>
 <TITLE>rrdtutorial</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
-	<LI><A HREF="#TUTORIAL">TUTORIAL</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
+	<LI><A HREF="#tutorial">TUTORIAL</A></LI>
 	<UL>
 
-		<LI><A HREF="#Important">Important</A>
-		<LI><A HREF="#What_is_RRDtool_">What is RRDtool ?</A>
-		<LI><A HREF="#What_data_can_be_put_into_an_RDD">What data can be put into an RDD ?</A>
-		<LI><A HREF="#What_can_I_do_with_this_tool_">What can I do with this tool ?</A>
-		<LI><A HREF="#What_if_I_still_have_problems_af">What if I still have problems after reading this document ?</A>
-		<LI><A HREF="#How_will_you_help_me_">How will you help me ?</A>
-		<LI><A HREF="#Your_first_Round_Robin_Database">Your first Round Robin Database</A>
-		<LI><A HREF="#What_has_been_created_">What has been created ?</A>
-		<LI><A HREF="#It_is_time_to_create_some_graphi">It is time to create some graphics</A>
-		<LI><A HREF="#Graphics_with_some_math">Graphics with some math</A>
-		<LI><A HREF="#Graphics_Magic">Graphics Magic</A>
-		<LI><A HREF="#Updates_in_Reality">Updates in Reality</A>
-		<LI><A HREF="#Some_words_on_SNMP">Some words on SNMP</A>
-		<LI><A HREF="#A_Real_World_Example">A Real World Example</A>
-		<LI><A HREF="#Consolidation_Functions">Consolidation Functions</A>
-		<LI><A HREF="#Let_s_review_what_you_now_should">Let's review what you now should know.</A>
-		<LI><A HREF="#Data_Source_Types">Data Source Types</A>
-		<LI><A HREF="#RRDtool_under_the_Microscope">RRDtool under the Microscope</A>
-		<LI><A HREF="#Counter_Wraps">Counter Wraps</A>
-		<LI><A HREF="#Data_Resampling">Data Resampling</A>
+		<LI><A HREF="#important">Important</A></LI>
+		<LI><A HREF="#what is rrdtool ">What is RRDtool ?</A></LI>
+		<LI><A HREF="#what data can be put into an rdd ">What data can be put into an RDD ?</A></LI>
+		<LI><A HREF="#what can i do with this tool ">What can I do with this tool ?</A></LI>
+		<LI><A HREF="#what if i still have problems after reading this document ">What if I still have problems after reading this document ?</A></LI>
+		<LI><A HREF="#how will you help me ">How will you help me ?</A></LI>
+		<LI><A HREF="#your first round robin database">Your first Round Robin Database</A></LI>
+		<LI><A HREF="#what has been created ">What has been created ?</A></LI>
+		<LI><A HREF="#it is time to create some graphics">It is time to create some graphics</A></LI>
+		<LI><A HREF="#graphics with some math">Graphics with some math</A></LI>
+		<LI><A HREF="#graphics magic">Graphics Magic</A></LI>
+		<LI><A HREF="#updates in reality">Updates in Reality</A></LI>
+		<LI><A HREF="#some words on snmp">Some words on SNMP</A></LI>
+		<LI><A HREF="#a real world example">A Real World Example</A></LI>
+		<LI><A HREF="#consolidation functions">Consolidation Functions</A></LI>
+		<LI><A HREF="#let's review what you now should know.">Let's review what you now should know.</A></LI>
+		<LI><A HREF="#data source types">Data Source Types</A></LI>
+		<LI><A HREF="#rrdtool under the microscope">RRDtool under the Microscope</A></LI>
+		<LI><A HREF="#counter wraps">Counter Wraps</A></LI>
+		<LI><A HREF="#data resampling">Data Resampling</A></LI>
 	</UL>
 
-	<LI><A HREF="#WRAPUP">WRAPUP</A>
-	<LI><A HREF="#MAILINGLIST">MAILINGLIST</A>
-	<LI><A HREF="#SEE_ALSO">SEE ALSO</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#wrapup">WRAPUP</A></LI>
+	<LI><A HREF="#mailinglist">MAILINGLIST</A></LI>
+	<LI><A HREF="#see also">SEE ALSO</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-rrdtutorial - Alex van den Bogaerdt's RRDtool tutorial
-
-<P>
+<H1><A NAME="name">NAME</A></H1>
+<P>rrdtutorial - Alex van den Bogaerdt's RRDtool tutorial</P>
+<div align="right">Go <a href="rrdtutorial.es.html">Spanish</a></div><div align="right"><a href="rrdtutorial.pdf">PDF</a> version.</div><P>
 <HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-RRDtool is written by Tobias Oetiker &lt;<A
-HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt; with
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>RRDtool is written by Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt; with
 contributions from many people all around the world. This document is
-written by Alex van den Bogaerdt &lt;<A
-HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt; to help
-you understand what RRDtool is and what it can do for you.
-
-<P>
-The documentation provided with RRDtool can be too technical for some
-people. This tutorial is here to help you understand the basics of RRDtool.
-It should prepare you to read the documentation yourself. It also explains
-the general things about statistics with a focus on networking.
-
-<P>
-<HR>
-<H1><A NAME="TUTORIAL">TUTORIAL</A></H1>
-<P>
-<HR>
-<H2><A NAME="Important">Important</A></H2>
-<P>
-Please don't skip ahead in this document! The first part of this document
-explains the basics and may be boring. But if you don't understand the
-basics, the examples will not be as meaningful to you.
-
-<P>
-<HR>
-<H2><A NAME="What_is_RRDtool_">What is RRDtool ?</A></H2>
-<P>
-RRDtool refers to Round Robin Database tool. Round robin is a technique
-that works with a fixed amount of data, and a pointer to the current
-element. Think of a circle with some dots plotted on the edge, these dots
-are the places where data can be stored. Draw an arrow from the center of
-the circle to one of the dots, this is the pointer. When the current data
-is read or written, the pointer moves to the next element. As we are on a
-circle there is no beginning nor an end, you can go on and on. After a
-while, all the available places will be used and the process automatically
-reuses old locations. This way, the database will not grow in size and
-therefore requires no mainenance. RRDtool works with with Round Robin
-Databases (RRDs). It stores and retrieves data from them.
-
-<P>
-<HR>
-<H2><A NAME="What_data_can_be_put_into_an_RDD">What data can be put into an RDD ?</A></H2>
+written by Alex van den Bogaerdt &lt;<A HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt; to help you
+understand what RRDtool is and what it can do for you.</P>
+<P>The documentation provided with RRDtool can be too technical for some
+people. This tutorial is here to help you understand the basics of
+RRDtool. It should prepare you to read the documentation yourself.
+It also explains the general things about statistics with a focus on
+networking.</P>
+<P>
+<HR>
+<H1><A NAME="tutorial">TUTORIAL</A></H1>
+<P>
+<H2><A NAME="important">Important</A></H2>
+<P>Please don't skip ahead in this document!  The first part of this
+document explains the basics and may be boring.  But if you don't
+understand the basics, the examples will not be as meaningful to you.</P>
+<P>
+<H2><A NAME="what is rrdtool ">What is RRDtool ?</A></H2>
+<P>RRDtool refers to Round Robin Database tool.
+Round robin is a technique that works with a fixed amount of data, and a
+pointer to the current element. Think of a circle with some dots plotted
+on the edge, these dots are the places where data can be stored. Draw an
+arrow from the center of the circle to one of the dots, this is the pointer.
+When the current data is read or written, the pointer moves to the next
+element. As we are on a circle there is no beginning nor an end, you can
+go on and on. After a while, all the available places will be used and
+the process automatically reuses old locations. This way, the database
+will not grow in size and therefore requires no mainenance.
+RRDtool works with with Round Robin Databases (RRDs). It stores and retrieves
+data from them.</P>
 <P>
-You name it, it will probably fit. You should be able to measure some value
+<H2><A NAME="what data can be put into an rdd ">What data can be put into an RDD ?</A></H2>
+<P>You name it, it will probably fit. You should be able to measure some value
 at several points in time and provide this information to RRDtool. If you
 can do this, RRDtool will be able to store it. The values need to be
-numerical but don't have to be, as opposed to MRTG, integers.
-
-<P>
-Many examples talk about SNMP which is an acronym for Simple Network
-Management Protocol. ``Simple'' refers to the protocol -- it does not mean
-it is simple to manage or monitor a network. After working your way through
-this document, you should know enough to be able to understand what people
-are talking about. For now, just realize that SNMP is a way to ask devices
-for the values of counters they keep. It is the value from those counters
-that are kept in the RRD.
-
-<P>
-<HR>
-<H2><A NAME="What_can_I_do_with_this_tool_">What can I do with this tool ?</A></H2>
-<P>
-RRDtool originated from MRTG (Multi Router Traffic Grapher). MRTG started
-as a tiny little script for graphing the use of a connection to the
-Internet. MRTG evolved into a tool for graphing other data sources
-including temperature, speed, voltage, number of printouts and the like.
-Most likely you will start to use the RRDtool to store and process data
-collected via SNMP. The data will most likely be bytes (or bits) transfered
-from and to a network or a computer. RRDtool lets you create a database,
-store data in it, retrieve that data and create graphs in GIF format for
-display on a web browser. Those GIF images are dependent on the data you
-collected and could be, for instance, an overview of the average network
-usage, or the peaks that occurred. It can also be used to display tidal
-waves, solar radiation, power consumption, number of visitors at an
-exhibition, noise levels near an airport, temperature on your favorite
-holiday location, temperature in the fridge and whatever you imagination
-can come up with. You need a sensor to measure the data and be able to feed
-the numbers to RRDtool.
-
-<P>
-<HR>
-<H2><A NAME="What_if_I_still_have_problems_af">What if I still have problems after reading this document ?</A></H2>
-<P>
-First of all: read it again! You may have missed something. If you are
-unable to compile the sources and you have a fairly common OS, it will
-probably not be the fault of RRDtool. There may be precompiled versions
-around on the Internet. If they come from trusted sources, get one of
-those. If on the other hand the program works but does not give you the
-expected results, it will be a problem with configuring it. Review your
-configuration and compare it with the examples that follow.
-
-<P>
-There is a mailing list and an archive of it. Read the list for a few weeks
-and search the archive. It is considered rude to just ask a question
-without searching the archives: your problem may already have been solved
-for somebody else! This is true for most, if not all, mailing lists and not
-only for this particular list! Look in the documentation that came with
-RRDtool for the location and usage of the list.
-
-<P>
-I suggest you take a moment to subscribe to the mailing list right now by
-sending an email to &lt;<A
-HREF="mailto:rrd-users-request at list.ee.ethz.ch">rrd-users-request at list.ee.ethz.ch</A>
-&gt; with a subject of ``subscribe''. If you ever want to leave this list, you
-write an email to the same address but now with a subject of
-``unsubscribe''.
-
-<P>
-<HR>
-<H2><A NAME="How_will_you_help_me_">How will you help me ?</A></H2>
-<P>
-By giving you some detailed descriptions with detailed examples. It is
-assumed that following the instructions in the order presented will give
-you enough knowledge of RRDtool to experiment for yourself. If it doesn't
-work the first time, don't give up. Reread the stuff that you did
-understand, you may have missed something. By following the examples you
-get some hands-on experience and, even more important, some background
-information of how it works.
-
-<P>
-You will need to know something about hexadecimal numbers. If you don't
-then start with reading ``bin_dec_hex'' before you continue here.
-
-<P>
-<HR>
-<H2><A NAME="Your_first_Round_Robin_Database">Your first Round Robin Database</A></H2>
-<P>
-In my opinion the best way to learn something is to actually do it. Why not
-start right now? We will create a database, put some values in it and
-extract this data again. Your output should be the same as the output that
-is included in this document.
-
-<P>
-We will start with some easy stuff and compare a car with a router, or
-compare kilometers (miles if you wish) with bits and bytes. It's all the
-same: some number over some time.
-
-<P>
-Assume we have a device that transfers bytes to and from the Internet. This
-device keeps a counter that starts at zero when it is turned on, increasing
-with every byte that is transfered. This counter will have a maximum value,
-if that value is reached and an extra byte is counted, the counter starts
-all over at zero. This is the same as many counters in the world such as
-the mileage counter in a car. Most discussions about networking talk about
-bits per second so lets get used to that right away. Assume a byte is eight
-bits and start to think in bits not bytes. The counter, however, still
-counts bytes ! In the SNMP world most of the counters are 32 bits. That
-means they are counting from 0 to 4294967295. We will use these values in
-the examples. The device, when asked, returns the current value of the
-counter. We know the time that has passes since we last asked so we now
-know how many bytes have been transfered <CODE>***on</CODE> average*** per
-second. This is not very hard to calculate. First in words, then in
-calculations:
-
+numerical but don't have to be, as opposed to MRTG, integers.</P>
+<P>Many examples talk about SNMP which is an acronym for
+Simple Network Management Protocol. ``Simple'' refers to the protocol --
+it does not mean it is simple to manage or monitor a network. After working your
+way through this document, you should know enough to be able to understand
+what people are talking about. For now, just realize that SNMP is a way to
+ask devices for the values of counters they keep.
+It is the value from those counters that are kept in the RRD.</P>
+<P>
+<H2><A NAME="what can i do with this tool ">What can I do with this tool ?</A></H2>
+<P>RRDtool originated from MRTG (Multi Router Traffic Grapher).  MRTG started
+as a tiny little script for graphing the use of a connection
+to the Internet. MRTG evolved into a tool for graphing other data sources
+including temperature, speed, voltage, number of printouts and
+the like. Most likely you will start to use the RRDtool to store
+and process data collected via SNMP. The data will most likely be bytes
+(or bits) transfered from and to a network or a computer.
+RRDtool lets you create a database, store data in it, retrieve that data
+and create graphs in GIF format for display on a web browser. Those GIF
+images are dependent on the data you collected and could be, for instance,
+an overview of the average network usage, or the peaks that occurred.
+It can also be used to display tidal waves, solar radiation, power
+consumption, number of visitors at an exhibition, noise levels near an
+airport, temperature on your favorite holiday location, temperature in the
+fridge and whatever you imagination can come up with. You need a sensor to
+measure the data and be able to feed the numbers to RRDtool.</P>
+<P>
+<H2><A NAME="what if i still have problems after reading this document ">What if I still have problems after reading this document ?</A></H2>
+<P>First of all: read it again! You may have missed something.
+If you are unable to compile the sources and you have a fairly common
+OS, it will probably not be the fault of RRDtool. There may be precompiled
+versions around on the Internet. If they come from trusted sources, get
+one of those.
+If on the other hand the program works but does not give you the
+expected results, it will be a problem with configuring it. Review
+your configuration and compare it with the examples that follow.</P>
+<P>There is a mailing list and an archive of it. Read the list for a few
+weeks and search the archive. It is considered rude to just ask
+a question without searching the archives: your problem may already have been
+solved for somebody else!  This is true for most, if not all, mailing lists
+and not only for this particular list! Look in the documentation that
+came with RRDtool for the location and usage of the list.</P>
+<P>I suggest you take a moment to subscribe to the mailing list right now
+by sending an email to &lt;<A HREF="mailto:rrd-users-request at list.ee.ethz.ch">rrd-users-request at list.ee.ethz.ch</A>&gt; with a
+subject of ``subscribe''. If you ever want to leave this list, you write
+an email to the same address but now with a subject of ``unsubscribe''.</P>
+<P>
+<H2><A NAME="how will you help me ">How will you help me ?</A></H2>
+<P>By giving you some detailed descriptions with detailed examples.
+It is assumed that following the instructions in the order presented
+will give you enough knowledge of RRDtool to experiment for yourself.
+If it doesn't work the first time, don't give up. Reread the stuff that
+you did understand, you may have missed something.
+By following the examples you get some hands-on experience and, even
+more important, some background information of how it works.</P>
+<P>You will need to know something about hexadecimal numbers. If you don't
+then start with reading <A HREF="././bin_dec_hex.html">the bin_dec_hex manpage</A> before you continue here.</P>
+<P>
+<H2><A NAME="your first round robin database">Your first Round Robin Database</A></H2>
+<P>In my opinion the best way to learn something is to actually do it.
+Why not start right now?  We will create a database, put some values
+in it and extract this data again.  Your output should be the same
+as the output that is included in this document.</P>
+<P>We will start with some easy stuff and compare a car with a router,
+or compare kilometers (miles if you wish) with bits and bytes. It's
+all the same: some number over some time.</P>
+<P>Assume we have a device that transfers bytes to and from the Internet.
+This device keeps a counter that starts at zero when it is turned on,
+increasing with every byte that is transfered. This counter will have
+a maximum value, if that value is reached and an extra byte is counted,
+the counter starts all over at zero. This is the same as many counters
+in the world such as the mileage counter in a car.
+Most discussions about networking talk about bits per second so lets
+get used to that right away. Assume a byte is eight bits and start to
+think in bits not bytes. The counter, however, still counts bytes !
+In the SNMP world most of the counters are 32 bits. That means they are
+counting from 0 to 4294967295. We will use these values in the examples.
+The device, when asked, returns the current value of the counter. We
+know the time that has passes since we last asked so we now know how
+many bytes have been transfered ***on average*** per second. This is
+not very hard to calculate. First in words, then in calculations:</P>
 <OL>
-<LI><STRONG><A NAME="item__">.</A></STRONG>
-<P>
+<LI>
 Take the current counter, subtract the previous value from it.
-
-<LI><STRONG>.</STRONG>
-<P>
+<P></P>
+<LI>
 Do the same with the current time and the previous time.
-
-<LI><STRONG>.</STRONG>
-<P>
-Divide the outcome of (1) by the outcome of (2), the result is the amount
-of bytes per second. Multiply by eight to get the number of bits per second
-(bps).
-
-</OL>
-<P>
-<PRE>  bps = (counter_now - counter_before) / (time_now - time_before) * 8
-</PRE>
-<P>
-For some people it may help to translate this to a automobile example: Do
-not try this example, and if you do, don't blame me for the results.
-
-<P>
-People who are not used to think in kilometers per hour can translate most
-into miles per hour by dividing km by 1.6 (close enough). I will use the
-following abbreviations:
-
-<P>
-<PRE> M:    meter
+<P></P>
+<LI>
+Divide the outcome of (1) by the outcome of (2), the result is
+the amount of bytes per second. Multiply by eight to get the
+number of bits per second (bps).
+<P></P></OL>
+<PRE>
+  bps = (counter_now - counter_before) / (time_now - time_before) * 8</PRE>
+<P>For some people it may help to translate this to a automobile example:
+Do not try this example, and if you do, don't blame me for the results.</P>
+<P>People who are not used to think in kilometers per hour can translate
+most into miles per hour by dividing km by 1.6 (close enough).
+I will use the following abbreviations:</P>
+<PRE>
+ M:    meter
  KM:   kilometer (= 1000 meters).
  H:    hour
  S:    second
  KM/H: kilometers per hour
- M/S:  meters per second
-</PRE>
-<P>
-You're driving a car. At 12:05 you read the counter in the dashboard and it
-tells you that the car has moved 12345 KM until that moment. At 12:10 you
-look again, it reads 12357 KM. This means you have traveled 12 KM in five
-minutes. A scientist would translate that into meters per second and this
-makes a nice comparison towards the problem of (bytes per five minutes)
-versus (bits per second).
-
-<P>
-We traveled 12 kilometers which is 12000 meters. We did that in five
+ M/S:  meters per second</PRE>
+<P>You're driving a car. At 12:05 you read the counter in the dashboard
+and it tells you that the car has moved 12345 KM until that moment.
+At 12:10 you look again, it reads 12357 KM. This means you have
+traveled 12 KM in five minutes. A scientist would translate that
+into meters per second and this makes a nice comparison towards the
+problem of (bytes per five minutes) versus (bits per second).</P>
+<P>We traveled 12 kilometers which is 12000 meters. We did that in five
 minutes which translates into 300 seconds. Our speed is 12000M / 300S
-equals 40 M/S.
-
-<P>
-We could also calculate the speed in KM/H: 12 times five minutes is an hour
-so we have to multiply 12 KM by 12 to get 144 KM/H. For our native English
-speaking friends: that's 90 MPH so don't try this example at home or where
-I live :)
-
-<P>
-Remember: these numbers are averages only. There is no way to figure out
-from the numbers, if you drove at a constant speed. There is an example
-later on in this tutorial that explains this.
-
-<P>
-I hope you understand that there is no difference in calculating M/S or
-bps; only the way we collect the data is different. Even the K from kilo is
-the same as in networking terms k also means 1000.
-
-<P>
-We will now create a database where we can keep all these interesting
-numbers. The method used to start the program may differ slightly from OS
-to OS but I assume you can figure it out if it works different on your OS.
-Make sure you do not overwrite any file on your system when executing the
-following command and type the whole line as one long line (I had to split
-it for readability) and skip all of the '\' characters.
-
-<P>
-<PRE>   rrdtool create test.rrd             \
+equals 40 M/S.</P>
+<P>We could also calculate the speed in KM/H: 12 times five minutes
+is an hour so we have to multiply 12 KM by 12 to get 144 KM/H.
+For our native English speaking friends: that's 90 MPH so don't
+try this example at home or where I live :)</P>
+<P>Remember: these numbers are averages only.  There is no way to figure out
+from the numbers, if you drove at a constant speed.  There is an example
+later on in this tutorial that explains this.</P>
+<P>I hope you understand that there is no difference in calculating M/S or
+bps; only the way we collect the data is different. Even the K from kilo
+is the same as in networking terms k also means 1000.</P>
+<P>We will now create a database where we can keep all these interesting
+numbers. The method used to start the program may differ slightly from
+OS to OS but I assume you can figure it out if it works different on
+your OS. Make sure you do not overwrite any file on your system when
+executing the following command and type the whole line as one long
+line (I had to split it for readability)
+and skip all of the '\' characters.</P>
+<PRE>
+   rrdtool create test.rrd             \
             --start 920804400          \
             DS:speed:COUNTER:600:U:U   \
             RRA:AVERAGE:0.5:1:24       \
-            RRA:AVERAGE:0.5:6:10
-</PRE>
-<P>
-(So enter: <CODE>rrdtool create test.rrd --start 920804400 DS ...</CODE>)
-
-<P>
-<HR>
-<H2><A NAME="What_has_been_created_">What has been created ?</A></H2>
+            RRA:AVERAGE:0.5:6:10</PRE>
+<P>(So enter: <CODE>rrdtool create test.rrd --start 920804400 DS ...</CODE>)</P>
 <P>
-We created the round robin database called test (test.rrd) which starts at
-noon the day I started (7th of march, 1999) writing this document. It holds
-one data source (DS) named ``speed'' that gets built from a counter. This
-counter is read every five minutes (default) In the same database two round
-robin archives (RRAs) are kept, one averages the data every time it is read
-(eg there's nothing to average) and keeps 24 samples (24 times 5 minutes is
-2 hours). The other averages 6 values (half hour) and contains 10 of such
-averages (eg 5 hours) The remaining options will be discussed later on.
-
-<P>
-RRDtool works with special time stamps coming from the UNIX world. This
-time stamp is the number of seconds that passed since January 1st 1970 UTC.
-This time stamp is translated into local time and it will therefore look
-different for the different time zones.
-
-<P>
-Chances are that you are not in the same part of the world as I am. This
-means your time zone is different. In all examples where I talk about time,
-the hours may be wrong for you. This has little effect on the results of
-the examples, just correct the hours while reading. As an example: where I
-will see ``12:05'' the UK folks will see ``11:05''.
-
-<P>
-We now have to fill our database with some numbers. We'll pretend to have
-read the following numbers:
-
-<P>
-<PRE> 12:05  12345 KM
+<H2><A NAME="what has been created ">What has been created ?</A></H2>
+<P>We created the round robin database called test (test.rrd)
+which starts at noon the day I started (7th of march, 1999) writing
+this document. It holds one data source (DS) named ``speed'' that gets
+built from a counter. This counter is read every five minutes (default)
+In the same database two round robin archives (RRAs) are kept, one
+averages the data every time it is read (eg there's nothing to average)
+and keeps 24 samples (24 times 5 minutes is 2 hours). The other averages
+6 values (half hour) and contains 10 of such averages (eg 5 hours)
+The remaining options will be discussed later on.</P>
+<P>RRDtool works with special time stamps coming from the UNIX world.
+This time stamp is the number of seconds that passed since January
+1st 1970 UTC.  This time stamp is translated into local time and
+it will therefore look different for the different time zones.</P>
+<P>Chances are that you are not in the same part of the world as I am.
+This means your time zone is different. In all examples where I talk
+about time, the hours may be wrong for you. This has little effect on
+the results of the examples, just correct the hours while reading.
+As an example: where I will see ``12:05'' the UK folks will see ``11:05''.</P>
+<P>We now have to fill our database with some numbers. We'll pretend to
+have read the following numbers:</P>
+<PRE>
+ 12:05  12345 KM
  12:10  12357 KM
  12:15  12363 KM
  12:20  12363 KM
@@ -337,47 +266,30 @@
  13:00  12415 KM
  13:05  12420 KM
  13:10  12422 KM
- 13:15  12423 KM
-</PRE>
-<P>
-We fill the database as follows:
-
-<P>
-<PRE> rrdtool update test.rrd 920804700:12345 920805000:12357 920805300:12363
+ 13:15  12423 KM</PRE>
+<P>We fill the database as follows:</P>
+<PRE>
+ rrdtool update test.rrd 920804700:12345 920805000:12357 920805300:12363
  rrdtool update test.rrd 920805600:12363 920805900:12363 920806200:12373
  rrdtool update test.rrd 920806500:12383 920806800:12393 920807100:12399
  rrdtool update test.rrd 920807400:12405 920807700:12411 920808000:12415
- rrdtool update test.rrd 920808300:12420 920808600:12422 920808900:12423
-</PRE>
-<P>
-This reads: update our test database with the following numbers
-
-<P>
-<PRE> time 920804700, value 12345
- time 920805000, value 12357
-</PRE>
-<P>
-etcetera.
-
-<P>
-As you can see, it is possible to feed more than one value into the
-database in one command. I had to stop at three for readability but the
-real maximum is OS dependent.
-
-<P>
-We can now retrieve the data from our database using ``rrdtool fetch'':
-
-<P>
-<PRE> rrdtool fetch test.rrd AVERAGE --start 920804400 --end 920809200
-</PRE>
-<P>
-It should return the following output:
-
-<P>
-<PRE>                speed
-</PRE>
-<P>
-<PRE> 920804700:       NaN
+ rrdtool update test.rrd 920808300:12420 920808600:12422 920808900:12423</PRE>
+<P>This reads: update our test database with the following numbers</P>
+<PRE>
+ time 920804700, value 12345
+ time 920805000, value 12357</PRE>
+<P>etcetera.</P>
+<P>As you can see, it is possible to feed more than one value into the
+database in one command. I had to stop at three for readability but
+the real maximum is OS dependent.</P>
+<P>We can now retrieve the data from our database using ``rrdtool fetch'':</P>
+<PRE>
+ rrdtool fetch test.rrd AVERAGE --start 920804400 --end 920809200</PRE>
+<P>It should return the following output:</P>
+<PRE>
+                speed</PRE>
+<PRE>
+ 920804700:       NaN
  920805000:      0.04
  920805300:      0.02
  920805600:      0.00
@@ -392,123 +304,88 @@
  920808300:      0.02
  920808600:      0.01
  920808900:      0.00
- 920809200:       NaN
-</PRE>
-<P>
-If it doesn't, something may be wrong. Perhaps your OS will print ``NaN''
-in a different form. It represents ``Not A Number''. If your OS writes
-``U'' or ``UNKN'' or something similar that's okay. If something else is
-wrong, it will probably be due to an error you made (assuming that my
-tutorial is correct of course :-). In that case: delete the database and
-try again.
-
-<P>
-What this output represents will become clear in the rest of the tutorial.
-
-<P>
-<HR>
-<H2><A NAME="It_is_time_to_create_some_graphi">It is time to create some graphics</A></H2>
-<P>
-Try the following command:
-
-<P>
-<PRE> rrdtool graph speed.gif                                 \
+ 920809200:       NaN</PRE>
+<P>If it doesn't, something may be wrong.  Perhaps your OS will print
+``NaN'' in a different form.  It represents ``Not A Number''.  If your OS
+writes ``U'' or ``UNKN'' or something similar that's okay.  If something
+else is wrong, it will probably be due to an error you made (assuming
+that my tutorial is correct of course :-). In that case: delete the
+database and try again.</P>
+<P>What this output represents will become clear in the rest of the tutorial.</P>
+<P>
+<H2><A NAME="it is time to create some graphics">It is time to create some graphics</A></H2>
+<P>Try the following command:</P>
+<PRE>
+ rrdtool graph speed.gif                                 \
          --start 920804400 --end 920808000               \
          DEF:myspeed=test.rrd:speed:AVERAGE              \
-         LINE2:myspeed#FF0000
-</PRE>
-<P>
-This will create speed.gif which starts at 12:00 and ends at 13:00. There
-is a definition of variable myspeed, it is the data from RRA ``speed'' out
-of database ``test.rrd''. The line drawn is 2 pixels high, and comes from
-variable myspeed. The color is red. You'll notice that the start of the
-graph is not at 12:00 but at 12:05 and this is because we have insufficient
-data to tell the average before that time. This will only happen when you
-miss some samples, this will not happen a lot, hopefully.
-
-<P>
-If this has worked: congratulations! If not, check what went wrong.
-
-<P>
-The colors are built up from red, green and blue. For each of the
-components, you specify how much to use in hexadecimal where 00 means not
-included and FF means fully included. The ``color'' white is a mixture of
-red, green and blue: FFFFFF The ``color'' black is all colors off: 000000
-
-<P>
-<PRE>   red     #FF0000
+         LINE2:myspeed#FF0000</PRE>
+<P>This will create speed.gif which starts at 12:00 and ends at 13:00.
+There is a definition of variable myspeed, it is the data from RRA
+``speed'' out of database ``test.rrd''. The line drawn is 2 pixels high,
+and comes from variable myspeed. The color is red.
+You'll notice that the start of the graph is not at 12:00 but at 12:05
+and this is because we have insufficient data to tell the average before
+that time. This will only happen when you miss some samples, this will
+not happen a lot, hopefully.</P>
+<P>If this has worked: congratulations! If not, check what went wrong.</P>
+<P>The colors are built up from red, green and blue. For each of the
+components, you specify how much to use in hexadecimal where 00 means
+not included and FF means fully included.
+The ``color'' white is a mixture of red, green and blue: FFFFFF
+The ``color'' black is all colors off: 000000</P>
+<PRE>
+   red     #FF0000
    green   #00FF00
    blue    #0000FF
    magenta #FF00FF     (mixed red with blue)
-   gray    #555555     (one third of all components)
-</PRE>
-<P>
-The GIF you just created can be displayed using your favorite image viewer.
-Web browsers will display the GIF via the URL
-``file://the/path/to/speed.gif''
-
-<P>
-<HR>
-<H2><A NAME="Graphics_with_some_math">Graphics with some math</A></H2>
+   gray    #555555     (one third of all components)</PRE>
+<P>The GIF you just created can be displayed using your favorite image
+viewer.  Web browsers will display the GIF via the URL
+``file://the/path/to/speed.gif''</P>
 <P>
-When looking at the image, you notice that the horizontal axis is labeled
+<H2><A NAME="graphics with some math">Graphics with some math</A></H2>
+<P>When looking at the image, you notice that the horizontal axis is labeled
 12:10, 12:20, 12:30, 12:40 and 12:50. The two remaining times (12:00 and
-13:00) would not be displayed nicely so they are skipped. The vertical axis
-displays the range we entered. We provided kilometers and when divided by
-300 seconds, we get very small numbers. To be exact, the first value was 12
-(12357-12345) and divided by 300 this makes 0.04, which is displayed by
-RRDtool as ``40 m'' meaning ``40/1000''. The ``m'' has nothing to do with
-meters, kilometers or millimeters! RRDtool doesn't know about all this, it
-just works with numbers and not with meters...
-
-<P>
-What we did wrong was that we should have measured in meters, this would
-have been (12357000-12345000)/300 = 12000/300 = 40.
-
-<P>
-Let's correct that. We could recreate our database and store the correct
-data but there is a better way: do some calculations while creating the gif
-file !
-
-<P>
-<PRE>   rrdtool graph speed2.gif                           \
+13:00) would not be displayed nicely so they are skipped.
+The vertical axis displays the range we entered. We provided kilometers
+and when divided by 300 seconds, we get very small numbers. To be exact,
+the first value was 12 (12357-12345) and divided by 300 this makes 0.04,
+which is displayed by RRDtool as ``40 m'' meaning ``40/1000''. The ``m'' has
+nothing to do with meters, kilometers or millimeters! RRDtool doesn't
+know about all this, it just works with numbers and not with meters...</P>
+<P>What we did wrong was that we should have measured in meters, this would
+have been (12357000-12345000)/300 = 12000/300 = 40.</P>
+<P>Let's correct that. We could recreate our database and store the correct
+data but there is a better way: do some calculations while creating the
+gif file !</P>
+<PRE>
+   rrdtool graph speed2.gif                           \
       --start 920804400 --end 920808000               \
       --vertical-label m/s                            \
       DEF:myspeed=test.rrd:speed:AVERAGE              \
       CDEF:realspeed=myspeed,1000,*                   \
-      LINE2:realspeed#FF0000
-</PRE>
-<P>
-After viewing this GIF, you notice the ``m'' has disappeared. This it what
+      LINE2:realspeed#FF0000</PRE>
+<P>After viewing this GIF, you notice the ``m'' has disappeared. This it what
 the correct result would be. Also, a label has been added to the image.
-Apart from the things mentioned above, the GIF should be the same.
-
-<P>
-The calculations are in the CDEF part and are in Reverse Polish Notation
+Apart from the things mentioned above, the GIF should be the same.</P>
+<P>The calculations are in the CDEF part and are in Reverse Polish Notation
 (``RPN''). What it says is: ``take the data source myspeed and the number
 1000; multiply those''. Don't bother with RPN yet, it will be explained
 later on in more detail. Also, you may want to read my tutorial on CDEFs
-and Steve Rader's tutorial on RPN. But first finish this tutorial.
-
-<P>
-Hang on! If we can multiply values with 1000, it should also be possible to
-display kilometers per hour from the same data!
-
-<P>
-To change a value that is measured in meters per second: -*- Calculate
-meters per hour: value * 3600 -*- Calculate kilometers per hour: value /
-1000 -*- Together this makes: value * (3600/1000) == value * 3.6
-
-<P>
-In our example database we made a mistake and we need to compensate for
-this by multiplying with 1000. Applying that correction: -*- value * 3.6
-<CODE>*1000</CODE> == value * 3600
-
-<P>
-Now let's create this GIF, and add some more magic ...
-
-<P>
-<PRE>   rrdtool graph speed3.gif                           \
+and Steve Rader's tutorial on RPN. But first finish this tutorial.</P>
+<P>Hang on! If we can multiply values with 1000, it should also be possible
+to display kilometers per hour from the same data!</P>
+<P>To change a value that is measured in meters per second:
+ -*- Calculate meters per hour:     value * 3600
+ -*- Calculate kilometers per hour: value / 1000
+ -*- Together this makes:           value * (3600/1000) == value * 3.6</P>
+<P>In our example database we made a mistake and we need to compensate for
+this by multiplying with 1000. Applying that correction:
+ -*- value * 3.6  *1000 == value * 3600</P>
+<P>Now let's create this GIF, and add some more magic ...</P>
+<PRE>
+   rrdtool graph speed3.gif                           \
       --start 920804400 --end 920808000               \
       --vertical-label km/h                           \
       DEF:myspeed=test.rrd:speed:AVERAGE              \
@@ -517,37 +394,25 @@
       CDEF:good=kmh,100,GT,0,kmh,IF                   \
       HRULE:100#0000FF:&quot;Maximum allowed&quot;              \
       AREA:good#00FF00:&quot;Good speed&quot;                   \
-      AREA:fast#FF0000:&quot;Too fast&quot;
-</PRE>
-<P>
-This looks much better. Speed in KM/H and even an extra line with the
-maximum allowed speed (on the road I travel at). I also changed the colors
-used to display speed and changed it from a line into an area.
-
-<P>
-The calculations are more complex now. For the ``good'' speed they are:
-
-<P>
-<PRE>   Check if kmh is greater than 100    ( kmh,100 ) GT
-   If so, return 0, else kmh           ((( kmh,100 ) GT ), 0, kmh) IF
-</PRE>
-<P>
-For the other speed:
-
-<P>
-<PRE>   Check if kmh is greater than 100    ( kmh,100 ) GT
-   If so, return kmh, else return 0    ((( kmh,100) GT ), kmh, 0) IF
-</PRE>
-<P>
-<HR>
-<H2><A NAME="Graphics_Magic">Graphics Magic</A></H2>
-<P>
-I like to believe there are virtually no limits to how RRDtool graph can
-manipulate data. I will not explain how it works, but look at the following
-GIF:
-
-<P>
-<PRE>   rrdtool graph speed4.gif                           \
+      AREA:fast#FF0000:&quot;Too fast&quot;</PRE>
+<P>This looks much better. Speed in KM/H and even an extra line with the
+maximum allowed speed (on the road I travel at). I also changed the
+colors used to display speed and changed it from a line into an area.</P>
+<P>The calculations are more complex now. For the ``good'' speed they are:</P>
+<PRE>
+   Check if kmh is greater than 100    ( kmh,100 ) GT
+   If so, return 0, else kmh           ((( kmh,100 ) GT ), 0, kmh) IF</PRE>
+<P>For the other speed:</P>
+<PRE>
+   Check if kmh is greater than 100    ( kmh,100 ) GT
+   If so, return kmh, else return 0    ((( kmh,100) GT ), kmh, 0) IF</PRE>
+<P>
+<H2><A NAME="graphics magic">Graphics Magic</A></H2>
+<P>I like to believe there are virtually no limits to how RRDtool graph
+can manipulate data. I will not explain how it works, but look at the
+following GIF:</P>
+<PRE>
+   rrdtool graph speed4.gif                           \
       --start 920804400 --end 920808000               \
       --vertical-label km/h                           \
       DEF:myspeed=test.rrd:speed:AVERAGE              \
@@ -558,255 +423,178 @@
       HRULE:100#0000FF:&quot;Maximum allowed&quot;              \
       AREA:good#00FF00:&quot;Good speed&quot;                   \
       AREA:fast#550000:&quot;Too fast&quot;                     \
-      STACK:over#FF0000:&quot;Over speed&quot;
-</PRE>
-<P>
-Let's create a quick and dirty HTML page to view three GIFs:
-
-<P>
-<PRE>   &lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;Speed&lt;/TITLE&gt;&lt;/HEAD&gt;&lt;BODY&gt;
+      STACK:over#FF0000:&quot;Over speed&quot;</PRE>
+<P>Let's create a quick and dirty HTML page to view three GIFs:</P>
+<PRE>
+   &lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;Speed&lt;/TITLE&gt;&lt;/HEAD&gt;&lt;BODY&gt;
    &lt;IMG src=&quot;speed2.gif&quot; alt=&quot;Speed in meters per second&quot;&gt;
    &lt;BR&gt;
    &lt;IMG src=&quot;speed3.gif&quot; alt=&quot;Speed in kilometers per hour&quot;&gt;
    &lt;BR&gt;
    &lt;IMG src=&quot;speed4.gif&quot; alt=&quot;Traveled too fast?&quot;&gt;
-   &lt;/BODY&gt;&lt;/HTML&gt;
-</PRE>
-<P>
-Name the file ``speed.html'' or similar, and view it.
-
-<P>
-Now, all you have to do is measure the values regularly and update the
-database. When you want to view the data, recreate the GIFs and make sure
-to refresh them in your browser. (Note: just clicking reload may not be
-enough; Netscape in particular has a problem doing so and you'll need to
-click reload while pressing the shift key).
-
-<P>
-<HR>
-<H2><A NAME="Updates_in_Reality">Updates in Reality</A></H2>
-<P>
-We've already used the ``update'' command: it took one or more parameters
-in the form of ``&lt;time&gt;:&lt;value&gt;''. You'll be glad to know that
-you can get the current time by filling in a ``N'' as the time. If you
-wish, you can also use the ``time'' function in perl. The shortest example
-in this doc :)
-
-<P>
-<PRE>   perl -e 'print time, &quot;\n&quot; '
-</PRE>
-<P>
-How you can run a program on regular intervals is OS specific. But here's
-an example in pseudo code:
-
-<P>
-<PRE>   Get the value, put it in variable &quot;$speed&quot;
-   rrdtool update speed.rrd N:$speed
-</PRE>
-<P>
-(Do not try this with our test database, it is used in further examples)
-
-<P>
-This is all. Run this script every five minutes. When you need to know what
-the graphics look like, run the examples above. You could put them in a
-script. After running that script, view index.html
-
-<P>
-<HR>
-<H2><A NAME="Some_words_on_SNMP">Some words on SNMP</A></H2>
-<P>
-I can imagine very few people will be able to get real data from their car
-every five minutes, all other people will have to settle for some other
-kind of counter. You could measure the number of pages printed by a
-printer, the coffee made by the coffee machine, a device that counts the
-electricity used, whatever. Any incrementing counter can be monitored and
-graphed using the stuff you learned until now. Later on we will also be
-able to monitor other types of values like temperature. Most people will
-use the counter that keeps track of octets (bytes) transfered by a network
-device so we have to do just that. We will start with a description of how
-to collect data. Some people will make a remark that there are tools who
-can do this data collection for you. They are right! However, I feel it is
-important that you understand they are not necessary. When you have to
-determine why things went wrong you need to know how they work.
-
-<P>
-One tool used in the example has been talked about very briefly in the
+   &lt;/BODY&gt;&lt;/HTML&gt;</PRE>
+<P>Name the file ``speed.html'' or similar, and view it.</P>
+<P>Now, all you have to do is measure the values regularly and update the
+database.  When you want to view the data, recreate the GIFs and make
+sure to refresh them in your browser. (Note: just clicking reload may
+not be enough; Netscape in particular has a problem doing so and you'll
+need to click reload while pressing the shift key).</P>
+<P>
+<H2><A NAME="updates in reality">Updates in Reality</A></H2>
+<P>We've already used the ``update'' command: it took one or more parameters
+in the form of ``&lt;time&gt;:&lt;value&gt;''. You'll be glad to know that you can
+get the current time by filling in a ``N'' as the time.
+If you wish, you can also use the ``time'' function in perl.
+The shortest example in this doc :)</P>
+<PRE>
+   perl -e 'print time, &quot;\n&quot; '</PRE>
+<P>How you can run a program on regular intervals is OS specific. But here's
+an example in pseudo code:</P>
+<PRE>
+   Get the value, put it in variable &quot;$speed&quot;
+   rrdtool update speed.rrd N:$speed</PRE>
+<P>(Do not try this with our test database, it is used in further examples)</P>
+<P>This is all. Run this script every five minutes. When you need to know
+what the graphics look like, run the examples above. You could put them
+in a script. After running that script, view index.html</P>
+<P>
+<H2><A NAME="some words on snmp">Some words on SNMP</A></H2>
+<P>I can imagine very few people will be able to get real data from their
+car every five minutes, all other people will have to settle for some
+other kind of counter. You could measure the number of pages printed by
+a printer, the coffee made by the coffee machine, a device that counts
+the electricity used, whatever. Any incrementing counter can be monitored
+and graphed using the stuff you learned until now. Later on we will also
+be able to monitor other types of values like temperature.
+Most people will use the counter that keeps track
+of octets (bytes) transfered by a network device so we have to do just
+that. We will start with a description of how to collect data.
+Some people will make a remark that there are tools who can do this data
+collection for you. They are right!  However, I feel it is important that
+you understand they are not necessary.  When you have to determine why
+things went wrong you need to know how they work.</P>
+<P>One tool used in the example has been talked about very briefly in the
 beginning of this document, it is called SNMP. It is a way of talking to
 equipment. The tool I use below is called ``snmpget'' and this is how it
-works:
-
-<P>
-<PRE>   snmpget device password OID
-</PRE>
-<P>
-For device you substitute the name, or the IP address, of your device. For
-password you use the ``community read string'' as it is called in the SNMP
-world. For some devices the default of ``public'' might work, however this
-can be disabled, altered or protected for privacy and security reasons.
-Read the documentation that comes with your device or program.
-
-<P>
-Then there is this third parameter, called OID, which means ``object
-identifier''.
-
-<P>
-When you start to learn about SNMP it looks very confusing. It isn't all
-that difficult when you look at the Management Information Base (``MIB'').
-It is an upside-down tree that describes data, with a single node as the
-root and from there a number of branches. These branches end up in another
-node, they branch out, etc. All the branches have a name and they form the
-path that we follow all the way down. The branches that we follow are
-named: iso, org, dod, internet, mgmt and mib-2. These names can also be
-written down as numbers and are 1 3 6 1 2 1.
-
-<P>
-<PRE>   iso.org.dod.internet.mgmt.mib-2 (1.3.6.1.2.1)
-</PRE>
-<P>
-There is a lot of confusion about the leading dot that some programs use.
-There is *no* leading dot in an OID. However, some programs can use above
-part of OIDs as a default. To indicate the difference between abbreviated
-OIDs and full OIDs they need a leading dot when you specify the complete
-OID. Often those programs will leave out the default portion when returning
-the data to you. To make things worse, they have several default prefixes
-...
-
-<P>
-Right, lets continue to the start of our OID: we had 1.3.6.1.2.1 From
-there, we are especially interested in the branch ``interfaces'' which has
-number 2 (eg 1.3.6.1.2.1.2 or 1.3.6.1.2.1.interfaces).
-
-<P>
-First, we have to get some SNMP program. First look if there is a
-pre-compiled package available for your OS. This is the preferred way. If
-not, you will have to get yourself the sources and compile those. The
-Internet is full of sources, programs etc. Find information using a search
-engine or whatever you prefer. As a suggestion: look for CMU-SNMP. It is
-commonly used.
-
-<P>
-Assume you got the program. First try to collect some data that is
-available on most systems. Remember: there is a short name for the part of
-the tree that interests us most in the world we live in!
-
-<P>
-I will use the short version as I think this document is large enough as it
-is. If that doesn't work for you, prefix with .1.3.6.1.2.1 and try again.
-Also, Read The Fine Manual. Skip the parts you cannot understand yet, you
-should be able to find out how to start the program and use it.
-
-<P>
-<PRE>   snmpget myrouter public system.sysdescr.0
-</PRE>
-<P>
-The device should answer with a description of itself, perhaps empty. Until
-you got a valid answer from a device, perhaps using a different
-``password'', or a different device, there is no point in continuing.
-
-<P>
-<PRE>   snmpget myrouter public interfaces.ifnumber.0
-</PRE>
-<P>
-Hopefully you get a number as a result, the number of interfaces. If so,
-you can carry on and try a different program called ``snmpwalk''.
-
-<P>
-<PRE>   snmpwalk myrouter public interfaces.iftable.ifentry.ifdescr
-</PRE>
-<P>
-If it returns with a list of interfaces, you're almost there. Here's an
-example: [user at host /home/alex]$ snmpwalk cisco public 2.2.1.2
-
-<P>
-<PRE>   interfaces.ifTable.ifEntry.ifDescr.1 = &quot;BRI0: B-Channel 1&quot;
+works:</P>
+<PRE>
+   snmpget device password OID</PRE>
+<P>For device you substitute the name, or the IP address, of your device.
+For password you use the ``community read string'' as it is called in the
+SNMP world.  For some devices the default of ``public'' might work, however
+this can be disabled, altered or protected for privacy and security
+reasons.  Read the documentation that comes with your device or program.</P>
+<P>Then there is this third parameter, called OID, which means ``object
+identifier''.</P>
+<P>When you start to learn about SNMP it looks very confusing. It isn't
+all that difficult when you look at the Management Information Base
+(``MIB'').  It is an upside-down tree that describes data, with a single node
+as the root and from there a number of branches.  These branches end
+up in another node, they branch out, etc.  All the branches have a name
+and they form the path that we follow all the way down.  The branches
+that we follow are named: iso, org, dod, internet, mgmt and mib-2.
+These names can also be written down as numbers and are 1 3 6 1 2 1.</P>
+<PRE>
+   iso.org.dod.internet.mgmt.mib-2 (1.3.6.1.2.1)</PRE>
+<P>There is a lot of confusion about the leading dot that some programs
+use.  There is *no* leading dot in an OID.  However, some programs
+can use above part of OIDs as a default.  To indicate the difference
+between abbreviated OIDs and full OIDs they need a leading dot when
+you specify the complete OID.  Often those programs will leave out
+the default portion when returning the data to you.  To make things
+worse, they have several default prefixes ...</P>
+<P>Right, lets continue to the start of our OID: we had 1.3.6.1.2.1
+From there, we are especially interested in the branch ``interfaces''
+which has number 2 (eg 1.3.6.1.2.1.2 or 1.3.6.1.2.1.interfaces).</P>
+<P>First, we have to get some SNMP program. First look if there is a
+pre-compiled package available for your OS. This is the preferred way.
+If not, you will have to get yourself the sources and compile those.
+The Internet is full of sources, programs etc. Find information using
+a search engine or whatever you prefer. As a suggestion: look for
+CMU-SNMP.  It is commonly used.</P>
+<P>Assume you got the program. First try to collect some data that is
+available on most systems. Remember: there is a short name for the
+part of the tree that interests us most in the world we live in!</P>
+<P>I will use the short version as I think this document is large enough
+as it is. If that doesn't work for you, prefix with .1.3.6.1.2.1 and
+try again.  Also, Read The Fine Manual.  Skip the parts you cannot
+understand yet, you should be able to find out how to start the
+program and use it.</P>
+<PRE>
+   snmpget myrouter public system.sysdescr.0</PRE>
+<P>The device should answer with a description of itself, perhaps empty.
+Until you got a valid answer from a device, perhaps using a different
+``password'', or a different device, there is no point in continuing.</P>
+<PRE>
+   snmpget myrouter public interfaces.ifnumber.0</PRE>
+<P>Hopefully you get a number as a result, the number of interfaces.
+If so, you can carry on and try a different program called ``snmpwalk''.</P>
+<PRE>
+   snmpwalk myrouter public interfaces.iftable.ifentry.ifdescr</PRE>
+<P>If it returns with a list of interfaces, you're almost there.
+Here's an example:
+   [user at host /home/alex]$ snmpwalk cisco public 2.2.1.2</P>
+<PRE>
+   interfaces.ifTable.ifEntry.ifDescr.1 = &quot;BRI0: B-Channel 1&quot;
    interfaces.ifTable.ifEntry.ifDescr.2 = &quot;BRI0: B-Channel 2&quot;
    interfaces.ifTable.ifEntry.ifDescr.3 = &quot;BRI0&quot; Hex: 42 52 49 30
    interfaces.ifTable.ifEntry.ifDescr.4 = &quot;Ethernet0&quot;
-   interfaces.ifTable.ifEntry.ifDescr.5 = &quot;Loopback0&quot;
-</PRE>
-<P>
-On this cisco equipment, I would like to monitor the ``Ethernet0''
-interface and see that it is number four. I try:
-
-<P>
-<PRE>   [user at host /home/alex]$ snmpget cisco public 2.2.1.10.4 2.2.1.16.4
-</PRE>
-<P>
-<PRE>   interfaces.ifTable.ifEntry.ifInOctets.4 = 2290729126
-   interfaces.ifTable.ifEntry.ifOutOctets.4 = 1256486519
-</PRE>
-<P>
-So now I have two OIDs to monitor and they are (in full, this time):
-
-<P>
-<PRE>   1.3.6.1.2.1.2.2.1.10
-</PRE>
-<P>
-and
-
-<P>
-<PRE>   1.3.6.1.2.1.2.2.1.16
-</PRE>
-<P>
-both with an interface number of 4.
-
-<P>
-Don't get fooled, this wasn't my first try. It took some time for me too to
-understand what all these numbers mean, it does help a lot when they get
-translated into descriptive text... At least, when people are talking about
-MIBs and OIDs you know what it's all about. Do not forget the interface
-number (0 if it is not interface dependent) and try snmpwalk if you don't
-get an answer from snmpget.
-
-<P>
-If you understand above part, and get numbers from your device, continue on
-with this tutorial. If not, then go back and re-read this part.
-
-<P>
-<HR>
-<H2><A NAME="A_Real_World_Example">A Real World Example</A></H2>
-<P>
-Let the fun begin. First, create a new database. It contains data from two
-counters, called input and output. The data is put into archives that
-average it. They take 1, 6, 24 or 288 samples at a time. They also go into
-archives that keep the maximum numbers. This will be explained later on.
-The time in-between samples is 300 seconds, a good starting point, which is
-the same as five minutes.
-
-<P>
-<PRE> 1 sample &quot;averaged&quot; stays 1 period of 5 minutes
+   interfaces.ifTable.ifEntry.ifDescr.5 = &quot;Loopback0&quot;</PRE>
+<P>On this cisco equipment, I would like to monitor the ``Ethernet0''
+interface and see that it is number four. I try:</P>
+<PRE>
+   [user at host /home/alex]$ snmpget cisco public 2.2.1.10.4 2.2.1.16.4</PRE>
+<PRE>
+   interfaces.ifTable.ifEntry.ifInOctets.4 = 2290729126
+   interfaces.ifTable.ifEntry.ifOutOctets.4 = 1256486519</PRE>
+<P>So now I have two OIDs to monitor and they are (in full, this time):</P>
+<PRE>
+   1.3.6.1.2.1.2.2.1.10</PRE>
+<P>and</P>
+<PRE>
+   1.3.6.1.2.1.2.2.1.16</PRE>
+<P>both with an interface number of 4.</P>
+<P>Don't get fooled, this wasn't my first try. It took some time for me too
+to understand what all these numbers mean, it does help a lot when they
+get translated into descriptive text... At least, when people are talking
+about MIBs and OIDs you know what it's all about.
+Do not forget the interface number (0 if it is not interface dependent)
+and try snmpwalk if you don't get an answer from snmpget.</P>
+<P>If you understand above part, and get numbers from your device, continue
+on with this tutorial. If not, then go back and re-read this part.</P>
+<P>
+<H2><A NAME="a real world example">A Real World Example</A></H2>
+<P>Let the fun begin. First, create a new database. It contains data from
+two counters, called input and output. The data is put into archives
+that average it. They take 1, 6, 24 or 288 samples at a time.
+They also go into archives that keep the maximum numbers. This will be
+explained later on. The time in-between samples is 300 seconds, a good
+starting point, which is the same as five minutes.</P>
+<PRE>
+ 1 sample &quot;averaged&quot; stays 1 period of 5 minutes
  6 samples averaged become one average on 30 minutes
  24 samples averaged become one average on 2 hours
- 288 samples averaged become one average on 1 day
-</PRE>
-<P>
-Lets try to be compatible with MRTG: MRTG stores about the following amount
-of data:
-
-<P>
-<PRE> 600 5-minute samples:    2   days and 2 hours
+ 288 samples averaged become one average on 1 day</PRE>
+<P>Lets try to be compatible with MRTG:
+MRTG stores about the following amount of data:</P>
+<PRE>
+ 600 5-minute samples:    2   days and 2 hours
  600 30-minute samples:  12.5 days
  600 2-hour samples:     50   days
- 600 1-day samples:     732   days
-</PRE>
-<P>
-These ranges are appended so the total amount of data kept is approximately
-797 days. RRDtool stores the data differently, it doesn't start the
-``weekly'' archive where the ``daily'' archive stopped. For both archives
-the most recent data will be near ``now'' and therefore we will need to
-keep more data than MRTG does!
-
-<P>
-We will need:
-
-<P>
-<PRE> 600 samples of 5 minutes  (2 days and 2 hours)
+ 732 1-day samples:     732   days</PRE>
+<P>These ranges are appended so the total amount of data kept is approximately
+797 days.  RRDtool stores the data differently, it doesn't start the ``weekly''
+archive where the ``daily'' archive stopped.  For both archives the most recent
+data will be near ``now'' and therefore we will need to keep more data than
+MRTG does!</P>
+<P>We will need:</P>
+<PRE>
+ 600 samples of 5 minutes  (2 days and 2 hours)
  700 samples of 30 minutes (2 days and 2 hours, plus 12.5 days)
  775 samples of 2 hours    (above + 50 days)
- 797 samples of 1 day      (above + 732 days, rounded up to 797)
-</PRE>
-<P>
-<PRE>   rrdtool create myrouter.rrd         \
+ 797 samples of 1 day      (above + 732 days, rounded up to 797)</PRE>
+<PRE>
+   rrdtool create myrouter.rrd         \
             DS:input:COUNTER:600:U:U   \
             DS:output:COUNTER:600:U:U  \
             RRA:AVERAGE:0.5:1:600      \
@@ -816,196 +604,151 @@
             RRA:MAX:0.5:1:600          \
             RRA:MAX:0.5:6:700          \
             RRA:MAX:0.5:24:775         \
-            RRA:MAX:0.5:288:797
-</PRE>
-<P>
-Next thing to do is collect data and store it. Here is an example. It is
-written partially in pseudo code so you will have to find out what to do
-exactly on your OS to make it work.
-
-<P>
-<PRE>   while not the end of the universe
+            RRA:MAX:0.5:288:797</PRE>
+<P>Next thing to do is collect data and store it. Here is an example.
+It is written partially in pseudo code so you will have to find out what
+to do exactly on your OS to make it work.</P>
+<PRE>
+   while not the end of the universe
    do
       get result of
          snmpget router community 2.2.1.10.4
       into variable $in
       get result of
          snmpget router community 2.2.1.16.4
-      into variable $out
-</PRE>
-<P>
-<PRE>      rrdtool update myrouter.rrd N:$in:$out
-</PRE>
-<P>
-<PRE>      wait for 5 minutes
-   done
-</PRE>
-<P>
-Then, after collecting data for a day, try to create an image using:
-
-<P>
-<PRE>   rrdtool graph myrouter-day.gif --start -86400 \
+      into variable $out</PRE>
+<PRE>
+      rrdtool update myrouter.rrd N:$in:$out</PRE>
+<PRE>
+      wait for 5 minutes
+   done</PRE>
+<P>Then, after collecting data for a day, try to create an image using:</P>
+<PRE>
+   rrdtool graph myrouter-day.gif --start -86400 \
             DEF:inoctets=myrouter.rrd:input:AVERAGE \
             DEF:outoctets=myrouter.rrd:output:AVERAGE \
             AREA:inoctets#00FF00:&quot;In traffic&quot; \
-            LINE1:outoctets#0000FF:&quot;Out traffic&quot;
-</PRE>
-<P>
-This should produce a picture with one day worth of traffic. One day is 24
-hours of 60 minutes of 60 seconds: 24*60*60=86400, we start at now minus
-86400 seconds. We define (with DEFs) inoctets and outoctets as the average
-values from the database myrouter.rrd and draw an area for the ``in''
-traffic and a line for the ``out'' traffic.
-
-<P>
-View the image and keep logging data for a few more days. If you like, you
-could try the examples from the test database and see if you can get
-various options and calculations working.
-
-<P>
-Suggestion:
-
-<P>
-Display in bytes per second and in bits per second. Make the Ethernet
-graphics go red if they are over four megabits per second.
-
-<P>
-<HR>
-<H2><A NAME="Consolidation_Functions">Consolidation Functions</A></H2>
-<P>
-A few paragraphs back I mentioned the possibility of keeping the maximum
-values instead of the average values. Let's go into this a bit more.
-
-<P>
-Recall all the stuff about the speed of the car. Suppose we drove at 144
+            LINE1:outoctets#0000FF:&quot;Out traffic&quot;</PRE>
+<P>This should produce a picture with one day worth of traffic.
+One day is 24 hours of 60 minutes of 60 seconds: 24*60*60=86400, we
+start at now minus 86400 seconds. We define (with DEFs) inoctets and
+outoctets as the average values from the database myrouter.rrd and draw
+an area for the ``in'' traffic and a line for the ``out'' traffic.</P>
+<P>View the image and keep logging data for a few more days.
+If you like, you could try the examples from the test database and
+see if you can get various options and calculations working.</P>
+<P>Suggestion:</P>
+<P>Display in bytes per second and in bits per second. Make the Ethernet
+graphics go red if they are over four megabits per second.</P>
+<P>
+<H2><A NAME="consolidation functions">Consolidation Functions</A></H2>
+<P>A few paragraphs back I mentioned the possibility of keeping
+the maximum values instead of the average values. Let's go
+into this a bit more.</P>
+<P>Recall all the stuff about the speed of the car. Suppose we drove at 144
 KM/H during 5 minutes and then were stopped by the police for 25 minutes.
 At the end of the lecture we would take our laptop and create+view the
-image taken from the database. If we look at the second RRA we did create,
-we would have the average from 6 samples. The samples measured would be
-144+0+0+0+0+0=144, divided by 30 minutes, corrected for the error by 1000,
-translated into KM/H, with a result of 24 KM/H. I would still get a ticket
-but not for speeding anymore :)
-
-<P>
-Obviously, in this case, we shouldn't look at the averages. In some cases
-they are handy. If you want to know how much KM you had traveled, the
-picture would be the right one to look at. On the other hand, for the speed
-that we traveled at, the maximum number seen is much more valuable. (later
-we will see more types)
-
-<P>
-It is the same for data. If you want to know the amount, look at the
-averages. If you want to know the rate, look at the maximum. Over time,
-they will grow apart more and more. In the last database we have created,
-there are two archives that keep data per day. The archive that keeps
-averages will show low numbers, the archive that shows maxima will have
-higher numbers. For my car this would translate in averages per day of
-96/24=4 KM/H (as I travel about 94 kilometers on a day) during week days,
-and maximum of 120 KM/H on weekdays (my top speed that I reach every day).
-
-<P>
-Big difference. Do not look at the second graph to estimate the distances
-that I travel and do not look at the first graph to estimate my speed. This
-will work if the samples are close together, as they are in five minutes,
-but not if you average.
-
-<P>
-On some days, I go for a long ride. If I go across Europe and travel for
-over 12 hours, the first graph will rise to about 60 KM/H. The second one
-will show 180 KM/H. This means that I traveled a distance of 60 KM/H times
-24 H = 1440 KM. I did this with a higher speed and a maximum around 180
-KM/H. This doesn't mean that I traveled for 8 hours at a constant speed of
-180 KM/H ! This is a real example: go with the flow through Germany (fast!)
-and stop a few times for gas and coffee. Drive slowly through Austria and
-the Netherlands. Be careful in the mountains and villages. If you would
-look at the graphs created from the five-minute averages you would get a
-totally different picture. You would see the same values on the average and
-maximum graphs (provided I measured every 300 seconds). You would be able
-to see when I stopped, when I was in top gear, when I drove over fast
-hiways etc. The granularity of the data is much higher, so you can see
-more. However, this takes 12 samples per hour, or 288 values per day, so it
-would be too much to keep for a long period of time. Therefore we average
-it, eventually to one value per day. From this one value, we cannot see
-much detail.
-
-<P>
-Make sure you understand the last few paragraphs. There is no value in only
-a line and a few axis, you need to know what they mean and interpret the
-data in a good way. This is true for all data.
-
-<P>
-The biggest mistake you can make is to use the collected data for something
-that it is not suitable for. You would be better off if you would not have
-the graphics at all in that case.
-
-<P>
-<HR>
-<H2><A NAME="Let_s_review_what_you_now_should">Let's review what you now should know.</A></H2>
-<P>
-You now know how to create a database. You can put the numbers in it, get
-them out again by creating an image, do math on the data from the database
-and view the outcome instead of the raw data. You know about the difference
-between averages and maxima, and when to use which (or at least you have an
-idea).
-
-<P>
-RRDtool can do more than what we have learned up to now. Before you
-continue with the rest of this doc, I recommend that you reread from the
-start and try some modifications on the examples. Make sure you fully
-understand everything. It will be worth the effort and helps you not only
-with the rest of this doc but also in your day to day monitoring long after
-you read this introduction.
-
-<P>
-<HR>
-<H2><A NAME="Data_Source_Types">Data Source Types</A></H2>
-<P>
-All right, you feel like continuing. Welcome back and get ready for an
-increased speed in the examples and explanation.
-
-<P>
-You know that in order to view a counter over time, you have to take two
-numbers and divide the difference of them between the time lapsed. This
-makes sense for the examples I gave you but there are other possibilities.
-For instance, I'm able to retrieve the temperature from my router in three
-places namely the inlet, the so called hot-spot and the exhaust. These
-values are not counters. If I take the difference of the two samples and
-divide that by 300 seconds I would be asking for the temperature change per
-second. Hopefully this is zero! If not, the computerroom is on fire :)
-
-<P>
-So, what can we do ? We can tell RRDtool to store the values we measure
+image taken from the database. If we look at the second RRA we did
+create, we would have the average from 6 samples. The samples measured
+would be 144+0+0+0+0+0=144, divided by 30 minutes, corrected for the
+error by 1000, translated into KM/H, with a result of 24 KM/H.
+I would still get a ticket but not for speeding anymore :)</P>
+<P>Obviously, in this case, we shouldn't look at the averages. In some
+cases they are handy. If you want to know how much KM you had traveled,
+the picture would be the right one to look at. On the other hand, for
+the speed that we traveled at, the maximum number seen is much more
+valuable. (later we will see more types)</P>
+<P>It is the same for data. If you want to know the amount, look at the
+averages. If you want to know the rate, look at the maximum.
+Over time, they will grow apart more and more. In the last database
+we have created, there are two archives that keep data per day. The
+archive that keeps averages will show low numbers, the archive that
+shows maxima will have higher numbers.
+For my car this would translate in averages per day of 96/24=4 KM/H
+(as I travel about 94 kilometers on a day) during week days, and
+maximum of 120 KM/H on weekdays (my top speed that I reach every day).</P>
+<P>Big difference. Do not look at the second graph to estimate the
+distances that I travel and do not look at the first graph to
+estimate my speed. This will work if the samples are close together,
+as they are in five minutes, but not if you average.</P>
+<P>On some days, I go for a long ride. If I go across Europe and travel
+for over 12 hours, the first graph will rise to about 60 KM/H. The
+second one will show 180 KM/H. This means that I traveled a distance
+of 60 KM/H times 24 H = 1440 KM. I did this with a higher speed and
+a maximum around 180 KM/H. This doesn't mean that I traveled for 8
+hours at a constant speed of 180 KM/H !
+This is a real example: go with the flow through Germany (fast!) and stop
+a few times for gas and coffee. Drive slowly through Austria and the
+Netherlands. Be careful in the mountains and villages. If you would
+look at the graphs created from the five-minute averages you would
+get a totally different picture. You would see the same values on the
+average and maximum graphs (provided I measured every 300 seconds).
+You would be able to see when I stopped, when I was in top gear, when
+I drove over fast hiways etc. The granularity of the data is much
+higher, so you can see more. However, this takes 12 samples per hour,
+or 288 values per day, so it would be too much to keep for a long
+period of time. Therefore we average it, eventually to one value per
+day. From this one value, we cannot see much detail.</P>
+<P>Make sure you understand the last few paragraphs. There is no value
+in only a line and a few axis, you need to know what they mean and
+interpret the data in a good way. This is true for all data.</P>
+<P>The biggest mistake you can make is to use the collected data for
+something that it is not suitable for. You would be better off if
+you would not have the graphics at all in that case.</P>
+<P>
+<H2><A NAME="let's review what you now should know.">Let's review what you now should know.</A></H2>
+<P>You now know how to create a database. You can put the numbers in it,
+get them out again by creating an image, do math on the data from the
+database and view the outcome instead of the raw data.
+You know about the difference between averages and maxima, and when
+to use which (or at least you have an idea).</P>
+<P>RRDtool can do more than what we have learned up to now. Before you
+continue with the rest of this doc, I recommend that you reread from
+the start and try some modifications on the examples. Make sure you
+fully understand everything. It will be worth the effort and helps
+you not only with the rest of this doc but also in your day to day
+monitoring long after you read this introduction.</P>
+<P>
+<H2><A NAME="data source types">Data Source Types</A></H2>
+<P>All right, you feel like continuing. Welcome back and get ready
+for an increased speed in the examples and explanation.</P>
+<P>You know that in order to view a counter over time, you have to
+take two numbers and divide the difference of them between the
+time lapsed.  This makes sense for the examples I gave you but there
+are other possibilities.  For instance, I'm able to retrieve the
+temperature from my router in three places namely the inlet, the
+so called hot-spot and the exhaust.  These values are not counters.
+If I take the difference of the two samples and divide that by
+300 seconds I would be asking for the temperature change per second.
+Hopefully this is zero! If not, the computerroom is on fire :)</P>
+<P>So, what can we do ?  We can tell RRDtool to store the values we measure
 directly as they are (this is not entirely true but close enough). The
 graphs we make will look much better, they will show a rather constant
-value. I know when the router is busy (it works -&gt; it uses more
-electricity -&gt; it generates more heat -&gt; the temperature rises). I
-know when the doors are left open (the room is cooled -&gt; the warm air
-from the rest of the building flows into the computer room -&gt; the inlet
-temperature rises) etc. The data type we use when creating the database
-before was counter, we now have a different data type and thus a different
-name for it. It is called GAUGE. There are more such data types:
-
-<P>
-<PRE> - COUNTER   we already know this one
+value. I know when the router is busy (it
+works -&gt; it uses more electricity -&gt; it generates more heat -&gt; the
+temperature rises). I know when the doors are left open (the room is
+cooled -&gt; the warm air from the rest of the building flows into the
+computer room -&gt; the inlet temperature rises) etc. The data type we
+use when creating the database before was counter, we now have a
+different data type and thus a different name for it. It is called
+GAUGE. There are more such data types:</P>
+<PRE>
+ - COUNTER   we already know this one
  - GAUGE     we just learned this one
  - DERIVE
- - ABSOLUTE
-</PRE>
-<P>
-The two new types are DERIVE and ABSOLUTE. Absolute can be used like
-counter with one difference: RRDtool assumes the counter is reset when it's
-read. That is: its delta is known without calculation by RRDtool whereas
-RRDtool needs to calculate it for the counter type. Example: our first
-example (12345, 12357, 12363, 12363) would read: unknown, 12, 6, 0. The
-rest of the calculations stay the same. The other one, derive, is like
-counter. Unlike counter, it can also decrease so it can have a negative
-delta. Again, the rest of the calculations stay the same.
-
-<P>
-Let's try them all:
-
-<P>
-<PRE>   rrdtool create all.rrd --start 978300900 \
+ - ABSOLUTE</PRE>
+<P>The two new types are DERIVE and ABSOLUTE. Absolute can be used like
+counter with one difference: RRDtool assumes the counter is reset when
+it's read. That is: its delta is known without calculation by RRDtool
+whereas RRDtool needs to calculate it for the counter type.
+Example: our first example (12345, 12357, 12363, 12363) would read:
+unknown, 12, 6, 0. The rest of the calculations stay the same.
+The other one, derive, is like counter. Unlike counter, it can also
+decrease so it can have a negative delta. Again, the rest of the
+calculations stay the same.</P>
+<P>Let's try them all:</P>
+<PRE>
+   rrdtool create all.rrd --start 978300900 \
             DS:a:COUNTER:600:U:U \
             DS:b:GAUGE:600:U:U \
             DS:c:DERIVE:600:U:U \
@@ -1026,262 +769,212 @@
             DEF:linea=all.rrd:a:AVERAGE LINE3:linea#FF0000:&quot;Line A&quot; \
             DEF:lineb=all.rrd:b:AVERAGE LINE3:lineb#00FF00:&quot;Line B&quot; \
             DEF:linec=all.rrd:c:AVERAGE LINE3:linec#0000FF:&quot;Line C&quot; \
-            DEF:lined=all.rrd:d:AVERAGE LINE3:lined#000000:&quot;Line D&quot;
-</PRE>
+            DEF:lined=all.rrd:d:AVERAGE LINE3:lined#000000:&quot;Line D&quot;</PRE>
 <P>
-<HR>
-<H2><A NAME="RRDtool_under_the_Microscope">RRDtool under the Microscope</A></H2>
+<H2><A NAME="rrdtool under the microscope">RRDtool under the Microscope</A></H2>
 <UL>
 <LI>
-<P>
-Line A is a counter so it should continuously increment and RRDtool should
-calculate the differences. Also, RRDtool needs to divide the difference by
-the amount of time lapsed. This should end up as a straight line at 1 (the
-deltas are 300, the time is 300).
-
+Line A is a counter so it should continuously increment and RRDtool
+should calculate the differences. Also, RRDtool needs to divide the
+difference by the amount of time lapsed. This should end up as a
+straight line at 1 (the deltas are 300, the time is 300).
+<P></P>
 <LI>
-<P>
 Line B is of type gauge. These are ``real'' values so they should match
 what we put in: a sort of a wave.
-
+<P></P>
 <LI>
-<P>
-Line C is derive. It should be a counter that can decrease. It does so
-between 2400 and 0, with 1800 in-between.
-
+Line C is derive. It should be a counter that can decrease. It does
+so between 2400 and 0, with 1800 in-between.
+<P></P>
 <LI>
-<P>
-Line D is of type absolute. This is like counter but it works on values
-without calculating the difference. The numbers are the same and as you can
-see (hopefully) this has a different result.
-
-</UL>
-<P>
-This translates in the following values, starting at 23:10 and ending at
-00:10 the next day (where U means unknown/unplotted):
-
-<P>
-<PRE> - Line A:  u  u  1  1  1  1  1  1  1  1  1  u
+Line D is of type absolute. This is like counter but it works on
+values without calculating the difference. The numbers are the same
+and as you can see (hopefully) this has a different result.
+<P></P></UL>
+<P>This translates in the following values, starting at 23:10 and ending
+at 00:10 the next day (where U means unknown/unplotted):</P>
+<PRE>
+ - Line A:  u  u  1  1  1  1  1  1  1  1  1  u
  - Line B:  u  1  3  5  3  1  2  4  6  4  2  u
  - Line C:  u  u  2  2  2  0 -2 -6  2  0  2  u
- - Line D:  u  1  2  3  4  5  6  7  8  9 10  u
-</PRE>
-<P>
-If your GIF shows all this, you know you have typed the data correct, the
-RRDtool executable is working properly, your viewer doesn't fool you and
-you successfully entered the year 2000 :) You could try the same example
-four times, each time with only one of the lines.
-
-<P>
-Let's go over the data again:
-
+ - Line D:  u  1  2  3  4  5  6  7  8  9 10  u</PRE>
+<P>If your GIF shows all this, you know you have typed the data correct,
+the RRDtool executable is working properly, your viewer doesn't fool you
+and you successfully entered the year 2000 :)
+You could try the same example four times, each time with only one of
+the lines.</P>
+<P>Let's go over the data again:</P>
 <UL>
 <LI>
-<P>
-Line A: 300,600,900 and so on. The counter delta is a constant 300 and so
-it the time delta. A number divided by itself is always 1 (except when
-dividing by zero which is undefined/illegal). Why is it that the first
-point is unknown ? We do know what we put into the database ? True ! But we
-didn't have a value to calculate the delta from so we don't know where we
-started. It would be wrong to assume we started at zero so we don't !
-
+Line A: 300,600,900 and so on. The counter delta is a constant 300 and
+so it the time delta. A number divided by itself is always 1 (except
+when dividing by zero which is undefined/illegal).
+Why is it that the first point is unknown ? We do know what we put into
+the database ? True ! But we didn't have a value to calculate the delta
+from so we don't know where we started. It would be wrong to assume we
+started at zero so we don't !
+<P></P>
 <LI>
-<P>
 Line B: There is nothing to calculate. The numbers are as is.
-
+<P></P>
 <LI>
-<P>
-Line C: Again, the start-out value is unknown. The same story is valid like
-for line A. In this case the deltas are not constant so the line is not. If
-we would put the same numbers in the database as we did for line A, we
-would have gotten the same line. Unlike type counter, this type can
-decrease and I hope to show you later on why there is a difference.
-
+Line C: Again, the start-out value is unknown. The same story is valid
+like for line A. In this case the deltas are not constant so the line
+is not. If we would put the same numbers in the database as we did for
+line A, we would have gotten the same line. Unlike type counter,
+this type can decrease and I hope to show you later on why
+there is a difference.
+<P></P>
 <LI>
-<P>
 Line D: Here the device calculates the deltas. Therefore we DO know the
-first delta and it is plotted. We had the same input as with line A but the
-meaning of this input is different. Therefore the line is different. In
-this case the deltas increase each time with 300. The time delta stays at a
-constant 300 and therefore the division of the two gives increasing
-results.
-
-</UL>
-<P>
-<HR>
-<H2><A NAME="Counter_Wraps">Counter Wraps</A></H2>
-<P>
-There are a few more basics to show. Some important options are still to be
-covered and we haven't look at counter wraps yet. First the counter wrap:
-In our car we notice that our counter shows 999987. We travel 20 KM and the
-counter should go to 1000007. Unfortunately, there are only six digits on
-our counter so it really shows 000007. If we would plot that on a type
+first delta and it is plotted. We had the same input as with line A but
+the meaning of this input is different. Therefore the line is different.
+In this case the deltas increase each time with 300. The time delta
+stays at a constant 300 and therefore the division of the two gives
+increasing results.
+<P></P></UL>
+<P>
+<H2><A NAME="counter wraps">Counter Wraps</A></H2>
+<P>There are a few more basics to show. Some important options are still to
+be covered and we haven't look at counter wraps yet. First the counter wrap:
+In our car we notice that our counter shows 999987. We travel 20 KM and
+the counter should go to 1000007. Unfortunately, there are only six digits
+on our counter so it really shows 000007. If we would plot that on a type
 DERIVE, it would mean that the counter was set back 999980 KM. It wasn't,
 and there has to be some protection for this. This protection is only
 available for type COUNTER which should be used for this kind of counter
 anyways. How does it work ? Type counter should never decrease and
-therefore RRDtool must assume it wrapped if it does decrease ! If the delta
-is negative, this can be compensated for by adding the maximum value of the
-counter + 1. For our car this would be:
-
-<P>
-<PRE> Delta = 7 - 999987 = -999980    (instead of 1000007-999987=20)
-</PRE>
-<P>
-<PRE> Real delta = -999980 + 999999 + 1 = 20
-</PRE>
-<P>
-At the time of writing this document, RRDtool knows of counters that are
-either 32 bits or 64 bits of size. These counters can handle the following
-different values:
-
-<P>
-<PRE> - 32 bits: 0 ..           4294967295
- - 64 bits: 0 .. 18446744073709551615
-</PRE>
-<P>
-If these numbers look strange to you, you would like to view them in their
-hexadecimal form:
-
-<P>
-<PRE> - 32 bits: 0 ..         FFFFFFFF
- - 64 bits: 0 .. FFFFFFFFFFFFFFFF
-</PRE>
-<P>
-RRDtool handles both counters the same. If an overflow occurs and the delta
-would be negative, RRDtool first adds the maximum of a small counter + 1 to
-the delta. If the delta is still negative, it had to be the large counter
-that wrapped. Add the maximum possible value of the large counter + 1 and
-subtract the falsely added small value. There is a risk in this: suppose
-the large counter wrapped while adding a huge delta, it could happen in
-theory that adding the smaller value would make the delta positive. In this
-unlikely case the results would not be correct. The increase should be
-nearly as high as the maximum counter value for that to happen so chances
-are you would have several other problems as well and this particular
-problem would not even be worth thinking about. Even though I did include
-an example of it so you can judge that for yourself.
-
-<P>
-The next section gives you some numerical examples for counter-wraps. Try
-to do the calculations yourself or just believe me if your calculator can't
-handle the numbers :)
-
-<P>
-Correction numbers:
-
-<P>
-<PRE> - 32 bits: (4294967295+1) =                                 4294967296
- - 64 bits: (18446744073709551615+1)-correction1 = 18446744069414584320
-</PRE>
-<P>
-<PRE> Before:        4294967200
+therefore RRDtool must assume it wrapped if it does decrease !
+If the delta is negative, this can be compensated for by adding the
+maximum value of the counter + 1. For our car this would be:</P>
+<PRE>
+ Delta = 7 - 999987 = -999980    (instead of 1000007-999987=20)</PRE>
+<PRE>
+ Real delta = -999980 + 999999 + 1 = 20</PRE>
+<P>At the time of writing this document, RRDtool knows of counters that
+are either 32 bits or 64 bits of size. These counters can handle the
+following different values:</P>
+<PRE>
+ - 32 bits: 0 ..           4294967295
+ - 64 bits: 0 .. 18446744073709551615</PRE>
+<P>If these numbers look strange to you, you would like to view them in
+their hexadecimal form:</P>
+<PRE>
+ - 32 bits: 0 ..         FFFFFFFF
+ - 64 bits: 0 .. FFFFFFFFFFFFFFFF</PRE>
+<P>RRDtool handles both counters the same. If an overflow occurs and
+the delta would be negative, RRDtool first adds the maximum of a small
+counter + 1 to the delta. If the delta is still negative, it had to be
+the large counter that wrapped. Add the maximum possible value of the
+large counter + 1 and subtract the falsely added small value.
+There is a risk in this: suppose the large counter wrapped while adding
+a huge delta, it could happen in theory that adding the smaller value
+would make the delta positive. In this unlikely case the results would
+not be correct. The increase should be nearly as high as the maximum
+counter value for that to happen so chances are you would have several
+other problems as well and this particular problem would not even be
+worth thinking about. Even though I did include an example of it so you
+can judge that for yourself.</P>
+<P>The next section gives you some numerical examples for counter-wraps.
+Try to do the calculations yourself or just believe me if your calculator
+can't handle the numbers :)</P>
+<P>Correction numbers:</P>
+<PRE>
+ - 32 bits: (4294967295+1) =                                 4294967296
+ - 64 bits: (18446744073709551615+1)-correction1 = 18446744069414584320</PRE>
+<PRE>
+ Before:        4294967200
  Increase:             100
  Should become: 4294967300
  But really is:          4
  Delta:        -4294967196
- Correction1:  -4294967196 +4294967296 = 100
-</PRE>
-<P>
-<PRE> Before:        18446744073709551000
+ Correction1:  -4294967196 +4294967296 = 100</PRE>
+<PRE>
+ Before:        18446744073709551000
  Increase:                       800
  Should become: 18446744073709551800
  But really is:                  184
  Delta:        -18446744073709550816
  Correction1:  -18446744073709550816 +4294967296 = -18446744069414583520
- Correction2:  -18446744069414583520 +18446744069414584320 = 800
-</PRE>
-<P>
-<PRE> Before:        18446744073709551615 ( maximum value )
+ Correction2:  -18446744069414583520 +18446744069414584320 = 800</PRE>
+<PRE>
+ Before:        18446744073709551615 ( maximum value )
  Increase:      18446744069414584320 ( absurd increase, minimum for
  Should become: 36893488143124135935             this example to work )
  But really is: 18446744069414584319
  Delta:                  -4294967296
  Correction1:  -4294967296 + 4294967296 = 0
- (not negative -&gt; no correction2)
-</PRE>
-<P>
-<PRE> Before:        18446744073709551615 ( maximum value )
+ (not negative -&gt; no correction2)</PRE>
+<PRE>
+ Before:        18446744073709551615 ( maximum value )
  Increase:      18446744069414584319 ( one less increase )
  Should become: 36893488143124135934
  But really is: 18446744069414584318
  Delta:                  -4294967297
  Correction1:  -4294967297 +4294967296 = -1
- Correction2:  -1 +18446744069414584320 = 18446744069414584319
-</PRE>
-<P>
-As you can see from the last two examples, you need strange numbers for
-RRDtool to fail (provided it's bug free of course) so this should not
-happen. However, SNMP or whatever method you choose to collect the data
-might also report wrong numbers occasionally. We can't prevent all errors
-but there are some things we can do. The RRDtool ``create'' command takes
-two special parameters for this. They define the minimum and maximum
-allowed value. Until now, we used ``U'', meaning ``unknown''. If you
-provide values for one or both of them and if RRDtool receives values that
-are outside these limits, it will ignore those values. For a thermometer in
-degrees Celsius, the absolute minimum is just under -273. For my router, I
-can assume this minimum is much higher so I would say it is 10. The maximum
-temperature for my router I would state as 80. Any higher and the device
-would be out of order. For my car, I would never expect negative numbers
-and also I would not expect numbers to be higher than 230. Anything else,
-and there must have been an error. Remember: the opposite is not true, if
-the numbers pass this check it doesn't mean that they are correct. Always
-judge the graph with a healthy dose of paranoia if it looks weird.
-
-<P>
-<HR>
-<H2><A NAME="Data_Resampling">Data Resampling</A></H2>
-<P>
-One important feature of RRDtool has not been explained yet: It is
-virtually impossible to collect the data and feed it into RRDtool on exact
-intervals. RRDtool therefore interpolates the data so it is on exact
-intervals. If you do not know what this means or how it works, then here's
-the help you seek:
-
-<P>
-Suppose a counter increases with exactly one for every second. You want to
-measure it in 300 seconds intervals. You should retrieve values that are
-exactly 300 apart. However, due to various circumstances you are a few
-seconds late and the interval is 303. The delta will also be 303 in that
-case. Obviously RRDtool should not put 303 in the database and make you
-believe that the counter increased 303 in 300 seconds. This is where
-RRDtool interpolates: it alters the 303 value as if it would have been
-stored earlier and it will be 300 in 300 seconds. Next time you are at
-exactly the right time. This means that the current interval is 297 seconds
-and also the counter increased with 297. Again RRDtool alters the value and
-stores 300 as it should be.
-
-<P>
-<PRE>      in the RDD                 in reality
-</PRE>
-<P>
-<PRE> time+000:   0 delta=&quot;U&quot;   time+000:    0 delta=&quot;U&quot;
+ Correction2:  -1 +18446744069414584320 = 18446744069414584319</PRE>
+<P>As you can see from the last two examples, you need strange numbers
+for RRDtool to fail (provided it's bug free of course) so this should
+not happen.  However, SNMP or whatever method you choose to collect the
+data might also report wrong numbers occasionally.  We can't prevent all
+errors but there are some things we can do.  The RRDtool ``create'' command
+takes two special parameters for this. They define
+the minimum and maximum allowed value. Until now, we used ``U'', meaning
+``unknown''. If you provide values for one or both of them and if RRDtool
+receives values that are outside these limits, it will ignore those
+values. For a thermometer in degrees Celsius, the absolute minimum is
+just under -273. For my router, I can assume this minimum is much higher
+so I would say it is 10. The maximum temperature for my router I would
+state as 80. Any higher and the device would be out of order.
+For my car, I would never expect negative numbers and also I would not
+expect numbers to be higher than 230. Anything else, and there must have
+been an error. Remember: the opposite is not true, if the numbers pass
+this check it doesn't mean that they are correct. Always judge the
+graph with a healthy dose of paranoia if it looks weird.</P>
+<P>
+<H2><A NAME="data resampling">Data Resampling</A></H2>
+<P>One important feature of RRDtool has not been explained yet:
+It is virtually impossible to collect the data and feed it into RRDtool
+on exact intervals. RRDtool therefore interpolates the data so it is on
+exact intervals. If you do not know what this means or how it works,
+then here's the help you seek:</P>
+<P>Suppose a counter increases with exactly one for every second. You want
+to measure it in 300 seconds intervals. You should retrieve values
+that are exactly 300 apart. However, due to various circumstances you
+are a few seconds late and the interval is 303. The delta will also be
+303 in that case. Obviously RRDtool should not put 303 in the database
+and make you believe that the counter increased 303 in 300 seconds.
+This is where RRDtool interpolates: it alters the 303 value as if it
+would have been stored earlier and it will be 300 in 300 seconds.
+Next time you are at exactly the right time. This means that the current
+interval is 297 seconds and also the counter increased with 297. Again
+RRDtool alters the value and stores 300 as it should be.</P>
+<PRE>
+      in the RDD                 in reality</PRE>
+<PRE>
+ time+000:   0 delta=&quot;U&quot;   time+000:    0 delta=&quot;U&quot;
  time+300: 300 delta=300   time+300:  300 delta=300
  time+600: 600 delta=300   time+603:  603 delta=303
- time+900: 900 delta=300   time+900:  900 delta=297
-</PRE>
-<P>
-Let's create two identical databases. I've chosen the time range 920805000
-to 920805900 as this goes very well with the example numbers.
-
-<P>
-<PRE>   rrdtool create seconds1.rrd   \
+ time+900: 900 delta=300   time+900:  900 delta=297</PRE>
+<P>Let's create two identical databases. I've chosen the time range 920805000
+to 920805900 as this goes very well with the example numbers.</P>
+<PRE>
+   rrdtool create seconds1.rrd   \
       --start 920804700          \
       DS:seconds:COUNTER:600:U:U \
-      RRA:AVERAGE:0.5:1:24
-</PRE>
-<P>
-<PRE>   for Unix: cp seconds1.rrd seconds2.rrd
+      RRA:AVERAGE:0.5:1:24</PRE>
+<PRE>
+   for Unix: cp seconds1.rrd seconds2.rrd
    for Dos:  copy seconds1.rrd seconds2.rrd
-   for vms:  how would I know :)
-</PRE>
-<P>
-<PRE>   rrdtool update seconds1.rrd \
+   for vms:  how would I know :)</PRE>
+<PRE>
+   rrdtool update seconds1.rrd \
       920805000:000 920805300:300 920805600:600 920805900:900
    rrdtool update seconds2.rrd \
-      920805000:000 920805300:300 920805603:603 920805900:900
-</PRE>
-<P>
-<PRE>   rrdtool graph seconds1.gif                       \
+      920805000:000 920805300:300 920805603:603 920805900:900</PRE>
+<PRE>
+   rrdtool graph seconds1.gif                       \
       --start 920804700 --end 920806200             \
       --height 200                                  \
       --upper-limit 1.05 --lower-limit 0.95 --rigid \
@@ -1296,55 +989,42 @@
       DEF:seconds=seconds2.rrd:seconds:AVERAGE      \
       CDEF:unknown=seconds,UN                       \
       LINE2:seconds#0000FF                          \
-      AREA:unknown#FF0000
-</PRE>
-<P>
-Both graphs should show the same.
-
+      AREA:unknown#FF0000</PRE>
+<P>Both graphs should show the same.</P>
 <P>
 <HR>
-<H1><A NAME="WRAPUP">WRAPUP</A></H1>
-<P>
-It's time to wrap up this document. You now know all the basics to be able
-to work with RRDtool and to read the documentation available. There is
-plenty more to discover about RRDtool and you will find more and more uses
-for the package. You could create easy graphics using just the examples
-provided and using only RRDtool. You could also use the front ends that are
-available.
-
+<H1><A NAME="wrapup">WRAPUP</A></H1>
+<P>It's time to wrap up this document. You now know all the basics to be
+able to work with RRDtool and to read the documentation available.
+There is plenty more to discover about RRDtool and you will find more and
+more uses for the package. You could create easy graphics using just the
+examples provided and using only RRDtool. You could also use the front
+ends that are available.</P>
 <P>
 <HR>
-<H1><A NAME="MAILINGLIST">MAILINGLIST</A></H1>
-<P>
-Remember to subscribe to the mailing-list. Even if you are not answering
+<H1><A NAME="mailinglist">MAILINGLIST</A></H1>
+<P>Remember to subscribe to the mailing-list. Even if you are not answering
 the mails that come by, it helps both you and the rest. A lot of the stuff
 that I know about MRTG (and therefore about RRDtool) I've learned while
 just reading the list without posting to it. I did not need to ask the
-basic questions as they are answered in the FAQ (read it!) and in various
-mails by other users. With thousands of users all over the world, there
-will always be people who ask questions that you can answer because you
-read this and other documentation and they didn't.
-
-<P>
-<HR>
-<H1><A NAME="SEE_ALSO">SEE ALSO</A></H1>
-<P>
-The RRDtool manpages
-
-<P>
-<HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-I hope you enjoyed the examples and their descriptions. If you do, help
-other people by pointing them to this document when they are asking basic
-questions. They will not only get their answer but at the same time learn a
-whole lot more.
-
-<P>
-Alex van den Bogaerdt
-&lt;<A HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt;
-
-
+basic questions as they are answered in the FAQ (read it!) and
+in various mails by other users.
+With thousands of users all over the world, there will always be people
+who ask questions that you can answer because you read this and other
+documentation and they didn't.</P>
+<P>
+<HR>
+<H1><A NAME="see also">SEE ALSO</A></H1>
+<P>The RRDtool manpages</P>
+<P>
+<HR>
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>I hope you enjoyed the examples and their descriptions. If you do, help
+other people by pointing them to this document when they are asking
+basic questions. They will not only get their answer but at the same
+time learn a whole lot more.</P>
+<P>Alex van den Bogaerdt
+&lt;<A HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt;</P>
 
 </BODY>
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdfetch.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdfetch.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdfetch.txt	Sat Jul 13 21:26:22 2002
@@ -9,14 +9,14 @@
      rrdtool fetch - fetch data from an rrd.
 
 SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
-     rrrrrrrrddddttttoooooooollll ffffeeeettttcccchhhh _f_i_l_e_n_a_m_e _C_F [--------rrrreeeessssoooolllluuuuttttiiiioooonnnn|----rrrr _r_e_s_o_l_u_t_i_o_n] [--------
-     ssssttttaaaarrrrtttt|----ssss _s_t_a_r_t] [--------eeeennnndddd|----eeee _e_n_d]
+     rrrrrrrrddddttttoooooooollll ffffeeeettttcccchhhh _f_i_l_e_n_a_m_e _C_F [--------rrrreeeessssoooolllluuuuttttiiiioooonnnn|----rrrr _r_e_s_o_l_u_t_i_o_n]
+     [--------ssssttttaaaarrrrtttt|----ssss _s_t_a_r_t] [--------eeeennnndddd|----eeee _e_n_d]
 
 DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
      The ffffeeeettttcccchhhh function is normally used internally by the graph
      function, to get data from RRRRRRRRDDDDs. ffffeeeettttcccchhhh will analyze the RRRRRRRRDDDD
      and will try to retrieve the data in the resolution
-     requested.  The data fetched is printed to stdout. *_U_N_K_N_O_W_N*
+     requested.  The data fetched is printed to stdout. _*_U_N_K_N_O_W_N_*
      data is often represented by the string "NaN" depending on
      your OSs printf function.
 
@@ -27,14 +27,14 @@
              applied to the data you want to fetch?
              (AVERAGE,MIN,MAX,LAST)
 
-     --------
-             rrrreeeessssoooolllluuuuttttiiiioooonnnn|-rrrr _r_e_s_o_l_u_t_i_o_n (default is the highest resolution)
+     --------rrrreeeessssoooolllluuuuttttiiiioooonnnn|----rrrr _r_e_s_o_l_u_t_i_o_n (default is the highest
+             resolution)
              what interval should the values have (seconds per
              value). rrrrrrrrddddffffeeeettttcccchhhh will try to match your request, but
              it will return data even if no absolute match is
              possible.
 
-     --------ssssttttaaaarrrrtttt|-ssss _s_t_a_r_t (default end-1day)
+     --------ssssttttaaaarrrrtttt|----ssss _s_t_a_r_t (default end-1day)
              when should the data begin. A time in seconds since
              epoch (1970-01-01) is required. Negative numbers are
              relative to the current time. By default one day
@@ -42,13 +42,13 @@
              TIME SPECIFICATION section for a detailed
              explanation on  ways to specify start time.
 
-     --------eeeennnndddd|-eeee _e_n_d (default now)
+     --------eeeennnndddd|----eeee _e_n_d (default now)
              when should the data end. Time in seconds since
              epoch. See also AT-STYLE TIME SPECIFICATION section
              for a detailed explanation of how to specify end
              time.
 
-     AAAATTTT-SSSSTTTTYYYYLLLLEEEE TTTTIIIIMMMMEEEE SSSSPPPPEEEECCCCIIIIFFFFIIIICCCCAAAATTTTIIIIOOOONNNN
+     AAAATTTT----SSSSTTTTYYYYLLLLEEEE TTTTIIIIMMMMEEEE SSSSPPPPEEEECCCCIIIIFFFFIIIICCCCAAAATTTTIIIIOOOONNNN
 
      Apart from the traditional _S_e_c_o_n_d_s _s_i_n_c_e _e_p_o_c_h, rrdtool does
      also understand at-style time specification.  The
@@ -60,7 +60,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      1
+2001-02-20             Last change: 1.0.33                      1
 
 
 
@@ -77,25 +77,28 @@
      a reference moment in time (for time offset to be applied
      to). When present, it should come first, when omitted, it
      defaults to nnnnoooowwww. On its own part, time reference consists of
-     _t_i_m_e-_o_f-_d_a_y reference (which should come first, if present)
+     _t_i_m_e_-_o_f_-_d_a_y reference (which should come first, if present)
      and _d_a_y reference.
 
-     _T_i_m_e-_o_f-_d_a_y can be specified as HHHHHHHH::::MMMMMMMM, HHHHHHHH....MMMMMMMM, or just HHHHHHHH,
+     _T_i_m_e_-_o_f_-_d_a_y can be specified as HHHHHHHH::::MMMMMMMM, HHHHHHHH....MMMMMMMM, or just HHHHHHHH,
      you can suffix it with aaaammmm or ppppmmmm or use 24-hours clock. The
      few special times of day are understood as well, these
      include mmmmiiiiddddnnnniiiigggghhhhtttt (00:00), nnnnoooooooonnnn (12:00) and British tttteeeeaaaattttiiiimmmmeeee
      (16:00).
 
-     The _d_a_y can be specified as _m_o_n_t_h-_n_a_m_e _d_a_y-_o_f-_t_h_e-_m_o_n_t_h and
+     The _d_a_y can be specified as _m_o_n_t_h_-_n_a_m_e _d_a_y_-_o_f_-_t_h_e_-_m_o_n_t_h and
      optional 2- or 4-digit _y_e_a_r number (e.g. March 8 1999).
-     Alternatively, you can use _d_a_y-_o_f-_w_e_e_k-_n_a_m_e (e.g. Monday),
+     Alternatively, you can use _d_a_y_-_o_f_-_w_e_e_k_-_n_a_m_e (e.g. Monday),
      or one of the words: yyyyeeeesssstttteeeerrrrddddaaaayyyy, ttttooooddddaaaayyyy, ttttoooommmmoooorrrrrrrroooowwww.  You can
      also specify _d_a_y as a full date in several numerical
-     formats; these include: MMMMMMMM////DDDDDDDD////[[[[YYYYYYYY]]]]YYYYYYYY, DDDDDDDD....MMMMMMMM....[[[[YYYYYYYY]]]]YYYYYYYY, YYYYYYYYYYYYYYYYMMMMMMMMDDDDDDDD
-     (_N_O_T_E_1: this is different from the original _a_t(1) behavior,
-     which interprets a single-number date as MMDD[YY]YY) _N_O_T_E_2:
-     if you specify _d_a_y this way, the _t_i_m_e-_o_f-_d_a_y is REQUIRED to
-     be present.
+     formats; these include: MMMMMMMM////DDDDDDDD////[[[[YYYYYYYY]]]]YYYYYYYY, DDDDDDDD....MMMMMMMM....[[[[YYYYYYYY]]]]YYYYYYYY,
+     YYYYYYYYYYYYYYYYMMMMMMMMDDDDDDDD.
+
+     _N_O_T_E_1: this is different from the original _a_t(1) behavior,
+     which interprets a single-number date as MMDD[YY]YY.
+
+     _N_O_T_E_2: if you specify _d_a_y this way, the _t_i_m_e_-_o_f_-_d_a_y is
+     REQUIRED to be present.
 
      Finally, you can use words nnnnoooowwww, ssssttttaaaarrrrtttt, or eeeennnndddd as your time
      reference. NNNNoooowwww refers to the current moment (and is also a
@@ -121,12 +124,9 @@
      several time offsets can be concatenated (e.g., -5h45min =
      -5h-45min = -6h+15min = -7h+1h30m-15min, etc.)
 
-     _N_O_T_E_3: If you specify time offset in days, weeks, months, or
-     years, you will end with the time offset that may vary
-
 
 
-24/Oct/1999            Last change: 1.0.13                      2
+2001-02-20             Last change: 1.0.33                      2
 
 
 
@@ -137,6 +137,8 @@
 
 
 
+     _N_O_T_E_3: If you specify time offset in days, weeks, months, or
+     years, you will end with the time offset that may vary
      depending on you time reference, because all those time
      units have no single well defined time interval value
      (1 year contains either 365 or 366 days, 1 month is 28 to 31
@@ -165,7 +167,7 @@
 
      _N_O_T_E_4: The single-letter abbreviation for both mmmmoooonnnntttthhhhssss and
      mmmmiiiinnnnuuuutttteeeessss is mmmm. To disambiguate, the parser tries to read your
-     mind :)  by applying the following two heuristics:
+     mind :) by applying the following two heuristics:
 
      1  If mmmm is used in context of (i.e. right after the) years,
         months, weeks, or days it is assumed to mean mmmmoooonnnntttthhhhssss,
@@ -190,9 +192,7 @@
 
 
 
-
-
-24/Oct/1999            Last change: 1.0.13                      3
+2001-02-20             Last change: 1.0.33                      3
 
 
 
@@ -207,29 +207,29 @@
 
      _O_c_t _1_2 -- October 12 this year
 
-     -_1_m_o_n_t_h or -_1_m -- current time of day, only a month before
+     _-_1_m_o_n_t_h or _-_1_m -- current time of day, only a month before
      (may yield surprises, see the NOTE3 above)
 
-     _n_o_o_n _y_e_s_t_e_r_d_a_y -_3_h_o_u_r_s -- yesterday morning; can be put also
-     as _9_a_m-_1_d_a_y
+     _n_o_o_n _y_e_s_t_e_r_d_a_y _-_3_h_o_u_r_s -- yesterday morning; can be put also
+     as _9_a_m_-_1_d_a_y
 
-     _2_3:_5_9 _3_1._1_2._1_9_9_9 -- 1 minute to the year 2000
+     _2_3_:_5_9 _3_1_._1_2_._1_9_9_9 -- 1 minute to the year 2000
 
-     _1_2/_3_1/_9_9 _1_1:_5_9_p_m -- 1 minute to the year 2000 for
+     _1_2_/_3_1_/_9_9 _1_1_:_5_9_p_m -- 1 minute to the year 2000 for
      imperialists
 
-     _1_2_a_m _0_1/_0_1/_0_1 -- start of the new millennium
+     _1_2_a_m _0_1_/_0_1_/_0_1 -- start of the new millennium
 
-     _e_n_d-_3_w_e_e_k_s or _e-_3_w -- 3 weeks before end time (may be used
+     _e_n_d_-_3_w_e_e_k_s or _e_-_3_w -- 3 weeks before end time (may be used
      as start time specification)
 
-     _s_t_a_r_t+_6_h_o_u_r_s or _s+_6_h -- 6 hours after start time (may be
+     _s_t_a_r_t_+_6_h_o_u_r_s or _s_+_6_h -- 6 hours after start time (may be
      used as end time specification)
 
      _9_3_1_2_2_5_5_3_7 -- 18:45  July 5th, 1999 (yes, seconds since 1970
      are valid as well)
 
-     _1_9_9_7_0_7_0_3 _1_2:_4_5 -- 12:45  July 3th, 1997 (not quote standard,
+     _1_9_9_7_0_7_0_3 _1_2_:_4_5 -- 12:45  July 3th, 1997 (not quote standard,
      but I love this ...)
 
 AAAAUUUUTTTTHHHHOOOORRRR
@@ -258,7 +258,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      4
+2001-02-20             Last change: 1.0.33                      4
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrddump.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrddump.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrddump.html	Sat Jul 13 21:26:22 2002
@@ -1,58 +1,49 @@
 <HTML>
 <HEAD>
 <TITLE>rrddump</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-rrdtool dump - dump the contents of an <STRONG>RRD</STRONG> to XML format
-
-<P>
+<H1><A NAME="name">NAME</A></H1>
+<P>rrdtool dump - dump the contents of an <STRONG>RRD</STRONG> to XML format</P>
+<div align="right"><a href="rrddump.pdf">PDF</a> version.</div><P>
 <HR>
-<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
-<P>
-<STRONG>rrdtool</STRONG>  <STRONG>dump</STRONG>  <EM>filename.rrd</EM>  &gt;  <EM>filename.xml</EM> 
-
- 
-
+<H1><A NAME="synopsis">SYNOPSIS</A></H1>
+<P><STRONG>rrdtool</STRONG> <STRONG>dump</STRONG> <EM>filename.rrd</EM> &gt; <EM>filename.xml</EM></P>
 <P>
 <HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-The <STRONG>dump</STRONG> function prints the contents of an <STRONG>RRD</STRONG> in human readable (?) XML format. This format can be read by rrdrestore.
-Together they allow you to transfer your files from one architecture to
-another as well as manipulating the contents of an <STRONG>RRD</STRONG> file in a somewhat more convenient manner.
-
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>The <STRONG>dump</STRONG> function prints the contents of an <STRONG>RRD</STRONG> in human
+readable (?) XML format. This format can be read by rrdrestore.
+Together they allow you to transfer your files from one architecture
+to another as well as manipulating the contents of an <STRONG>RRD</STRONG> file in a
+somewhat more convenient manner.</P>
 <DL>
-<DT><STRONG><A NAME="item_filename">filename.rrd</A></STRONG><DD>
-<P>
+<DT><STRONG><A NAME="item_filename%2Errd"><EM>filename.rrd</EM></A></STRONG><BR>
+<DD>
 The name of the <STRONG>RRD</STRONG> you want to dump.
-
-</DL>
+<P></P></DL>
 <P>
 <HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;
-
-
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;</P>
 
 </BODY>
 

Added: trunk/orca/packages/rrdtool-1.0.33/doc/rrdinfo.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdinfo.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdinfo.txt	Sat Jul 13 21:26:23 2002
@@ -0,0 +1,66 @@
+
+
+
+rrdtool                                                RRDINFO(1)
+
+
+
+NNNNAAAAMMMMEEEE
+     rrdtool info - extract header information from an rrd
+
+SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
+     rrrrrrrrddddttttoooooooollll iiiinnnnffffoooo _f_i_l_e_n_a_m_e_._r_r_d
+
+DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
+     The iiiinnnnffffoooo function prints the header information from an rrd
+     in a parsing friendly format.
+
+     Check the rrdcreate manpage if you are uncertain about the
+     meaning of the individual keys.
+
+EEEEXXXXAAAAMMMMPPPPLLLLEEEE
+     This is the output generated by running iiiinnnnffffoooo on a simple rrd
+     which contains two datasources and one rra. Note that the
+     number after the _l_a_s_t___u_p_d_a_t_e keyword is in seconds since
+     1970. The string NNNNaaaaNNNN stands for _*_U_N_K_N_O_W_N_* data. In the
+     example it means that this rrd has neither minimum not
+     maximum values defined for either of its datasources.
+
+      filename = "randome.rrd"
+      rrd_version = "0001"
+      step = 300
+      last_update = 955892996
+      ds[a].type = "GAUGE"
+      ds[a].minimal_heartbeat = 600
+      ds[a].min = NaN
+      ds[a].max = NaN
+      ds[a].last_ds = "UNKN"
+      ds[a].value = 2.1824421548e+04
+      ds[a].unknown_sec = 0
+      ds[b].type = "GAUGE"
+      ds[b].minimal_heartbeat = 600
+      ds[b].min = NaN
+      ds[b].max = NaN
+      ds[b].last_ds = "UNKN"
+      ds[b].value = 3.9620838224e+03
+      ds[b].unknown_sec = 0
+      rra[0].cf = "AVERAGE"
+      rra[0].pdp_per_row = 1
+      rra[0].cdp_prep[0].value = nan
+      rra[0].cdp_prep[0].unknown_datapoints = 0
+      rra[0].cdp_prep[1].value = nan
+      rra[0].cdp_prep[1].unknown_datapoints = 0
+
+
+     _f_i_l_e_n_a_m_e_._r_r_d
+             The name of the RRRRRRRRDDDD you want to dump.
+
+AAAAUUUUTTTTHHHHOOOORRRR
+     Tobias Oetiker <oetiker at ee.ethz.ch>
+
+
+
+2001-02-20             Last change: 1.0.33                      1
+
+
+

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdfetch.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdfetch.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdfetch.pod	Sat Jul 13 21:26:23 2002
@@ -2,6 +2,8 @@
 
 rrdtool fetch - fetch data from an rrd.
 
+=for html <div align="right"><a href="rrdfetch.pdf">PDF</a> version.</div>
+
 =head1 SYNOPSIS
 
 B<rrdtool> B<fetch> I<filename> I<CF> 
@@ -78,9 +80,11 @@
 Alternatively, you can use I<day-of-week-name> (e.g. Monday),
 or one of the words: B<yesterday>, B<today>, B<tomorrow>.
 You can also specify I<day> as a full date in several numerical formats;
-these include: B<MM/DD/[YY]YY>, B<DD.MM.[YY]YY>, B<YYYYMMDD>
-(I<NOTE1>: this is different from the original at(1) behavior,
-which interprets a single-number date as MMDD[YY]YY)
+these include: B<MM/DD/[YY]YY>, B<DD.MM.[YY]YY>, B<YYYYMMDD>.
+
+I<NOTE1>: this is different from the original at(1) behavior,
+which interprets a single-number date as MMDD[YY]YY.
+
 I<NOTE2>: if you specify I<day> this way, the I<time-of-day> is REQUIRED
 to be present.
 
@@ -94,7 +98,6 @@
 (e.g., Dec for December, Sun for Sunday, etc.). The words B<now>,
 B<start>, B<end> can be abbreviated to B<n>, B<s>, B<e>.
 
-
 =head2 TIME OFFSET SPECIFICATION
 
 Time offset specification is used to add (or subtract) certain time

Added: trunk/orca/packages/rrdtool-1.0.33/doc/rrdinfo.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdinfo.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdinfo.pod	Sat Jul 13 21:26:23 2002
@@ -0,0 +1,64 @@
+=head1 NAME
+
+rrdtool info - extract header information from an rrd
+
+=for html <div align="right"><a href="rrdinfo.pdf">PDF</a> version.</div>
+
+=head1 SYNOPSIS
+
+B<rrdtool> B<info> I<filename.rrd>
+
+=head1 DESCRIPTION
+
+The B<info> function prints the header information from an rrd in
+a parsing friendly format.
+
+Check L<rrdcreate> if you are uncertain about the meaning of the
+individual keys.
+
+=head1 EXAMPLE
+
+This is the output generated by running B<info> on a simple rrd which
+contains two datasources and one rra. Note that the number after the
+I<last_update> keyword is in seconds since 1970. The string B<NaN>
+stands for I<*UNKNOWN*> data. In the example it means that this rrd
+has neither minimum not maximum values defined for either of its
+datasources.
+
+ filename = "randome.rrd"
+ rrd_version = "0001"
+ step = 300
+ last_update = 955892996
+ ds[a].type = "GAUGE"
+ ds[a].minimal_heartbeat = 600
+ ds[a].min = NaN
+ ds[a].max = NaN
+ ds[a].last_ds = "UNKN"
+ ds[a].value = 2.1824421548e+04
+ ds[a].unknown_sec = 0
+ ds[b].type = "GAUGE"
+ ds[b].minimal_heartbeat = 600
+ ds[b].min = NaN
+ ds[b].max = NaN
+ ds[b].last_ds = "UNKN"
+ ds[b].value = 3.9620838224e+03
+ ds[b].unknown_sec = 0
+ rra[0].cf = "AVERAGE"
+ rra[0].pdp_per_row = 1
+ rra[0].cdp_prep[0].value = nan
+ rra[0].cdp_prep[0].unknown_datapoints = 0
+ rra[0].cdp_prep[1].value = nan
+ rra[0].cdp_prep[1].unknown_datapoints = 0
+
+=over 8
+
+=item I<filename.rrd>
+
+The name of the B<RRD> you want to dump.
+
+=back
+
+=head1 AUTHOR
+
+Tobias Oetiker E<lt>oetiker at ee.ethz.chE<gt>
+

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/RRDp.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/RRDp.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/RRDp.txt	Sat Jul 13 21:26:24 2002
@@ -60,7 +60,7 @@
 
 
 
-13/Feb/2000            Last change: 1.0.13                      1
+2001-02-22             Last change: 1.0.33                      1
 
 
 
@@ -126,7 +126,7 @@
 
 
 
-13/Feb/2000            Last change: 1.0.13                      2
+2001-02-22             Last change: 1.0.33                      2
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rpntutorial.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rpntutorial.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rpntutorial.html	Sat Jul 13 21:26:24 2002
@@ -1,270 +1,194 @@
 <HTML>
 <HEAD>
 <TITLE>rpntutorial</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
-	<LI><A HREF="#Reading_Comparison_Operators">Reading Comparison Operators</A>
-	<LI><A HREF="#Reading_the_IF_Operator">Reading the IF Operator</A>
-	<LI><A HREF="#Some_Examples">Some Examples</A>
-	<LI><A HREF="#Exercises">Exercises</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
+	<LI><A HREF="#reading comparison operators">Reading Comparison Operators</A></LI>
+	<LI><A HREF="#reading the if operator">Reading the IF Operator</A></LI>
+	<LI><A HREF="#some examples">Some Examples</A></LI>
+	<LI><A HREF="#exercises">Exercises</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-rpntutorial - Reading RRDTtool RPN Expressions by Steve Rader
-
-<P>
-<HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-This tutorial should help you get to grips with rrdtool RPN expressions as
-seen in CDEF arguments of rrdtool graph.
-
-<P>
-<HR>
-<H1><A NAME="Reading_Comparison_Operators">Reading Comparison Operators</A></H1>
-<P>
-The LT, LE, GT, GE and EQ RPN logic operators are not as tricky as they
-appear. These operators act on the two values on the stack preceding them
-(to the left). Read these two values on the stack from left to right
-inserting the operator in the middle. If the resulting statement is true,
-the replace the three values from the stack with ``1''. If the statement if
-false, replace the three values with ``0''.
-
-<P>
-For example think about ``2,1,GT''. This RPN expression could be read as
-``is two greater than one?'' The answer to that question is ``true''. So
-the three values should be replaced with ``1''. Thus the RPN expression
-2,1,GT evaluates to 1.
-
-<P>
-Now also consider ``2,1,LE''. This RPN expression could be read as ``is two
-less than or equal to one?''. The natural response is ``no'' and thus the
-RPN expression 2,1,LE evaluates to 0. 
-
-<P>
-<HR>
-<H1><A NAME="Reading_the_IF_Operator">Reading the IF Operator</A></H1>
-<P>
-The IF RPN logic operator can be straightforward also. The key to reading
-IF operators is to understand that the condition part of the traditional
-``if X than Y else Z'' notation has *already* been evaluated. So the IF
-operator acts on only one value on the stack: the third value to the left
-of the IF value. The second value to the left of the IF corresponds to the
-true (``Y'') branch. And the first value to the left of the IF corresponds
-to the false (``Z'') branch. Read the RPN expression ``X,Y,Z,IF'' from left
-to right like so: ``if X then Y else Z''.
-
-<P>
-For example, consider ``1,10,100,IF''. It looks bizzare to me. But when I
-read ``if 1 then 10 else 100'' it's crystal clear: 1 is true so the answer
-is 10. Note that only zero is false; all other values are true.
-``2,20,200,IF'' (``if 2 then 20 else 200'') evaluates to 20. And
-``0,1,2,IF'' (``if 0 then 1 else 2) evaluates to 2.
-
-<P>
-Notice that none of the above examples really simulate the whole ``if X
-then Y else Z'' statement. This is because computer programmers read this
-statement as ``if Some Condition then Y else Z''. So it's important to be
-able to read IF operators along with the LT, LE, GT, GE and EQ operators.
-
-<P>
-<HR>
-<H1><A NAME="Some_Examples">Some Examples</A></H1>
-<P>
-While compound expressions can look overly complex, they can be considered
-elegantly simple. To quickly comprehend RPN expressions, you must know the
-the algorithm for evaluating RPN expressions: iterate searches from the
-left to the right looking for an operator, when it's found, apply that
-operator by popping the operator and some number of values (and by
-definition, not operators) off the stack.
-
-<P>
-For example, the stack ``1,2,3,+,+'' gets ``2,3,+'' evaluated (as ``2+3'')
-during the first iteration which is replaced by 5. This results in the
-stack ``1,5,+''. Finally, ``1,5,+'' is evaluated resulting in the answer 6.
-For convenience sake, it's useful to write this set of operations as:
-
-<P>
-<PRE> 1) 1,2,3,+,+    eval is 2,3,+ = 5    result is 1,5,+
+<H1><A NAME="name">NAME</A></H1>
+<P>rpntutorial - Reading RRDTtool RPN Expressions by Steve Rader</P>
+<div align="right"><a href="rpntutorial.pdf">PDF</a> version.</div><P>
+<HR>
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>This tutorial should help you get to grips with rrdtool RPN expressions
+as seen in CDEF arguments of rrdtool graph.</P>
+<P>
+<HR>
+<H1><A NAME="reading comparison operators">Reading Comparison Operators</A></H1>
+<P>The LT, LE, GT, GE and EQ RPN logic operators are not as tricky as
+they appear.  These operators act on the two values on the stack
+preceding them (to the left).  Read these two values on the stack
+from left to right inserting the operator in the middle.  If the
+resulting statement is true, the replace the three values from the
+stack with ``1''.  If the statement if false, replace the three values
+with ``0''.</P>
+<P>For example think about ``2,1,GT''.  This RPN expression could be
+read as ``is two greater than one?''  The answer to that question is
+``true''.  So the three values should be replaced with ``1''.  Thus the
+RPN expression 2,1,GT evaluates to 1.</P>
+<P>Now also consider ``2,1,LE''.  This RPN expression could be read as ``is
+two less than or equal to one?''.   The natural response is ``no''
+and thus the RPN expression 2,1,LE evaluates to 0.</P>
+<P>
+<HR>
+<H1><A NAME="reading the if operator">Reading the IF Operator</A></H1>
+<P>The IF RPN logic operator can be straightforward also.  The key
+to reading IF operators is to understand that the condition part
+of the traditional ``if X than Y else Z'' notation has *already*
+been evaluated.  So the IF operator acts on only one value on the
+stack: the third value to the left of the IF value.  The second
+value to the left of the IF corresponds to the true (``Y'') branch.
+And the first value to the left of the IF corresponds to the false
+(``Z'') branch.  Read the RPN expression ``X,Y,Z,IF'' from left to
+right like so: ``if X then Y else Z''.</P>
+<P>For example, consider ``1,10,100,IF''.  It looks bizzare to me.
+But when I read ``if 1 then 10 else 100'' it's crystal clear: 1 is true
+so the answer is 10.  Note that only zero is false; all other values
+are true.  ``2,20,200,IF'' (``if 2 then 20 else 200'') evaluates to 20.
+And ``0,1,2,IF'' (``if 0 then 1 else 2) evaluates to 2.</P>
+<P>Notice that none of the above examples really simulate the whole
+``if X then Y else Z'' statement.  This is because computer programmers
+read this statement as ``if Some Condition then Y else Z''.  So it's
+important to be able to read IF operators along with the LT, LE,
+GT, GE and EQ operators.</P>
+<P>
+<HR>
+<H1><A NAME="some examples">Some Examples</A></H1>
+<P>While compound expressions can look overly complex, they can be
+considered elegantly simple.  To quickly comprehend RPN expressions,
+you must know the the algorithm for evaluating RPN expressions:
+iterate searches from the left to the right looking for an operator,
+when it's found, apply that operator by popping the operator and some
+number of values (and by definition, not operators) off the stack.</P>
+<P>For example, the stack ``1,2,3,+,+'' gets ``2,3,+'' evaluated (as ``2+3'')
+during the first iteration which is replaced by 5.  This results in
+the stack ``1,5,+''.  Finally, ``1,5,+'' is evaluated resulting in the
+answer 6.  For convenience sake, it's useful to write this set of
+operations as:</P>
+<PRE>
+ 1) 1,2,3,+,+    eval is 2,3,+ = 5    result is 1,5,+
  2) 1,5,+        eval is 1,5,+ = 6    result is 6
- 3) 6
-</PRE>
-<P>
-Let's use that notation to conviently solve some complex RPN expressions
-with multiple logic operators:
-
-<P>
-<PRE> 1) 20,10,GT,10,20,IF  eval is 20,10,GT = 1     result is 1,10,20,IF
-</PRE>
-<P>
-read the eval as pop ``20 is greater than 10'' so push 1 2) 1,10,20,IF eval
-is 1,10,20,IF = 10 result is 10
-
-<P>
-read pop ``if 1 then 10 else 20'' so push 10. Only 10 is left so 10 is the
-answer.
-
-<P>
-Let's read a complex RPN expression that also has the traditional
-multiplication operator:
-
-<P>
-<PRE> 1) 128,8,*,7000,GT,7000,128,8,*,IF  eval 128,8,*       result is 1024
+ 3) 6</PRE>
+<P>Let's use that notation to conviently solve some complex RPN expressions
+with multiple logic operators:</P>
+<PRE>
+ 1) 20,10,GT,10,20,IF  eval is 20,10,GT = 1     result is 1,10,20,IF</PRE>
+<P>read the eval as pop ``20 is greater than 10'' so push 1
+</P>
+<PRE>
+
+ 2) 1,10,20,IF         eval is 1,10,20,IF = 10  result is 10</PRE>
+<P>read pop ``if 1 then 10 else 20'' so push 10.  Only 10 is left so
+10 is the answer.</P>
+<P>Let's read a complex RPN expression that also has the traditional
+multiplication operator:</P>
+<PRE>
+ 1) 128,8,*,7000,GT,7000,128,8,*,IF  eval 128,8,*       result is 1024
  2) 1024,7000,GT,7000,128,8,*,IF     eval 1024,7000,GT  result is 0
  3) 0,128,8,*,IF                     eval 128,8,*       result is 1024
- 4) 0,7000,1024,IF                                      result is 1024
-</PRE>
-<P>
-Now let's go back to the first example of multiple logic operators but
-replace the value 20 with the variable ``input'':
-
-<P>
-<PRE> 1) input,10,GT,10,input,IF  eval is input,10,GT  result is A
-</PRE>
-<P>
-Read eval as ``if input &gt; 10 then true'' and replace ``input,10,GT''
-with ``A: 2) A,10,input,IF eval is A,10,input,IF
-
-<P>
-read ``if A then 10 else input''. Now replace A it's verbose description
-and--voila!--you have a easily readable description of the expression:
-
-<P>
-<PRE> if input &gt; 10 then 10 else input
-</PRE>
-<P>
-Lastly, let's to back the first most complex example and replace the value
-128 with ``input'':
-
-<P>
-<PRE> 1) input,8,*,7000,GT,7000,input,8,*,IF  eval input,8,*     result is A
-</PRE>
-<P>
-where A is ``input * 8''
-
-<P>
-<PRE> 2) A,7000,GT,7000,input,8,*,IF          eval is A,7000,GT  result is B
-</PRE>
-<P>
-where B is ``if ((input * 8) &gt; 7000) then true''
-
-<P>
-<PRE> 3) B,7000,input,8,*,IF                  eval is input,8,*  result is C
-</PRE>
-<P>
-where C is ``input * 8''
-
-<P>
-<PRE> 4) B,7000,C,IF
-</PRE>
-<P>
-At last we have a readable decoding of the complex RPN expression with a
-variable:
-
-<P>
-<PRE> if ((input * 8) &gt; 7000) then 7000 else (input * 8)
-</PRE>
-<P>
-<HR>
-<H1><A NAME="Exercises">Exercises</A></H1>
-<P>
-Exercise 1:
-
-<P>
-Compute ``3,2,*,1,+ and ''3,2,1,+,*`` by hand. Rewrite them in traditional
-notation. Explain why they have different answers.
-
-<P>
-Answer 1:
-
-<P>
-<PRE>    3*2+1 = 7 and 3*(2+1) = 9.  These expressions have
+ 4) 0,7000,1024,IF                                      result is 1024</PRE>
+<P>Now let's go back to the first example of multiple logic operators
+but replace the value 20 with the variable ``input'':</P>
+<PRE>
+ 1) input,10,GT,10,input,IF  eval is input,10,GT  result is A</PRE>
+<P>Read eval as ``if input &gt; 10 then true'' and replace ``input,10,GT''
+with ``A:
+</P>
+<PRE>
+
+ 2) A,10,input,IF            eval is A,10,input,IF</PRE>
+<P>read ``if A then 10 else input''.  Now replace A it's verbose
+description and--voila!--you have a easily readable description
+of the expression:</P>
+<PRE>
+ if input &gt; 10 then 10 else input</PRE>
+<P>Lastly, let's to back the first most complex example and replace
+the value 128 with ``input'':</P>
+<PRE>
+ 1) input,8,*,7000,GT,7000,input,8,*,IF  eval input,8,*     result is A</PRE>
+<P>where A is ``input * 8''</P>
+<PRE>
+ 2) A,7000,GT,7000,input,8,*,IF          eval is A,7000,GT  result is B</PRE>
+<P>where B is ``if ((input * 8) &gt; 7000) then true''</P>
+<PRE>
+ 3) B,7000,input,8,*,IF                  eval is input,8,*  result is C</PRE>
+<P>where C is ``input * 8''</P>
+<PRE>
+ 4) B,7000,C,IF</PRE>
+<P>At last we have a readable decoding of the complex RPN expression with
+a variable:</P>
+<PRE>
+ if ((input * 8) &gt; 7000) then 7000 else (input * 8)</PRE>
+<P>
+<HR>
+<H1><A NAME="exercises">Exercises</A></H1>
+<P>Exercise 1:</P>
+<P>Compute ``3,2,*,1,+ and ''3,2,1,+,*`` by hand.  Rewrite them in
+traditional notation.  Explain why they have different answers.</P>
+<P>Answer 1:</P>
+<PRE>
+    3*2+1 = 7 and 3*(2+1) = 9.  These expressions have
     different answers because the altering of the plus and 
-    times operators alter the order of their evaluation.
-</PRE>
-<P>
-Exercise 2:
-
-<P>
-One may be tempted to shorten the expression
-
-<P>
-<PRE> input,8,*,56000,GT,56000,input,*,8,IF
-</PRE>
-<P>
-by removing the redundant use of ``input,8,*'' like so:
-
-<P>
-<PRE> input,56000,GT,56000,input,IF,8,*
-</PRE>
-<P>
-Use tradition notation to show these expressions are not the same. Write an
-expression that's equivalent to the first expression but uses the LE and
-DIV operators.
-
-<P>
-Answer 2:
-
-<P>
-<PRE>    if (input &lt;= 56000/8 ) { input*8 } else { 56000 }
-    input,56000,8,DIV,LT,input,8,*,56000,IF
-</PRE>
-<P>
-Exercise 3:
-
-<P>
-Briefly explain why traditional mathematic notation requires the use of
-parentheses. Explain why RPN notation does not require the use of
-parentheses.
-
-<P>
-Answer 3:
-
-<P>
-<PRE>    Traditional mathematic expressions are evaluated by
+    times operators alter the order of their evaluation.</PRE>
+<P>Exercise 2:</P>
+<P>One may be tempted to shorten the expression</P>
+<PRE>
+ input,8,*,56000,GT,56000,input,*,8,IF</PRE>
+<P>by removing the redundant use of ``input,8,*'' like so:</P>
+<PRE>
+ input,56000,GT,56000,input,IF,8,*</PRE>
+<P>Use tradition notation to show these expressions are not the same.
+Write an expression that's equivalent to the first expression but
+uses the LE and DIV operators.</P>
+<P>Answer 2:</P>
+<PRE>
+    if (input &lt;= 56000/8 ) { input*8 } else { 56000 }
+    input,56000,8,DIV,LT,input,8,*,56000,IF</PRE>
+<P>Exercise 3:</P>
+<P>Briefly explain why traditional mathematic notation requires the
+use of parentheses.  Explain why RPN notation does not require
+the use of parentheses.</P>
+<P>Answer 3:</P>
+<PRE>
+    Traditional mathematic expressions are evaluated by
     doing multiplication and division first, then addition and
     subtraction.  Perentences are used to force the evaluation of
     addition before multiplication (etc).  RPN does not require
     parentheses because the ordering of objects on the stack
-    can force the evaluation of addition before multiplication.
-</PRE>
-<P>
-Exercise 4:
-
-<P>
-Explain why it is desirable for the RRDtool developers to implement RPN
-notation instead of traditional mathematical notation.
-
-<P>
-Answer 4:
-
-<P>
-<PRE>    The algorithm that implements traditional mathematical
+    can force the evaluation of addition before multiplication.</PRE>
+<P>Exercise 4:</P>
+<P>Explain why it is desirable for the RRDtool developers to implement
+RPN notation instead of traditional mathematical notation.</P>
+<P>Answer 4:</P>
+<PRE>
+    The algorithm that implements traditional mathematical
     notation is more complex then algorithm used for RPN.
     So implementing RPN allowed Tobias Oetiker to write less
     code!  (The code is also less complex and therefore less
-    likely to have bugs.)
-</PRE>
+    likely to have bugs.)</PRE>
 <P>
 <HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-steve rader &lt;<A HREF="mailto:rader at wiscnet.net">rader at wiscnet.net</A>&gt;
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>steve rader &lt;<A HREF="mailto:rader at wiscnet.net">rader at wiscnet.net</A>&gt;</P>
 
 </BODY>
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdgraph.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdgraph.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdgraph.txt	Sat Jul 13 21:26:24 2002
@@ -10,17 +10,18 @@
      several RRD
 
 SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
-     rrrrrrrrddddttttoooooooollll ggggrrrraaaapppphhhh _f_i_l_e_n_a_m_e [----ssss|--------ssssttttaaaarrrrtttt _s_e_c_o_n_d_s] [----eeee|--------
-     eeeennnndddd _s_e_c_o_n_d_s] [----xxxx|--------xxxx----ggggrrrriiiidddd _x-_a_x_i_s _g_r_i_d _a_n_d _l_a_b_e_l] [----yyyy|--------yyyy----
-     ggggrrrriiiidddd _y-_a_x_i_s _g_r_i_d _a_n_d _l_a_b_e_l] [--------aaaalllltttt----yyyy----ggggrrrriiiidddd] [--------aaaalllltttt----aaaauuuuttttoooossssccccaaaalllleeee]
-     [----vvvv|--------vvvveeeerrrrttttiiiiccccaaaallll----llllaaaabbbbeeeellll _t_e_x_t] [----wwww|--------wwwwiiiiddddtttthhhh _p_i_x_e_l_s] [----hhhh|--------
-     hhhheeeeiiiigggghhhhtttt _p_i_x_e_l_s] [----iiii|--------iiiinnnntttteeeerrrrllllaaaacccceeeedddd] [----ffff|--------iiiimmmmggggiiiinnnnffffoooo _f_o_r_m_a_t_s_t_r_i_n_g]
-     [----aaaa|--------iiiimmmmggggffffoooorrrrmmmmaaaatttt GGGGIIIIFFFF|PPPPNNNNGGGG] [----zzzz|--------llllaaaazzzzyyyy] [----oooo|--------llllooooggggaaaarrrriiiitttthhhhmmmmiiiicccc]
-     [----uuuu|--------uuuuppppppppeeeerrrr----lllliiiimmmmiiiitttt _v_a_l_u_e] [----llll|--------lllloooowwwweeeerrrr----lllliiiimmmmiiiitttt _v_a_l_u_e] [----rrrr|--------
-     rrrriiiiggggiiiidddd] [----bbbb|--------bbbbaaaasssseeee _v_a_l_u_e] [----cccc|--------ccccoooolllloooorrrr _C_O_L_O_R_T_A_G####_r_r_g_g_b_b]
-
-     [----tttt|--------ttttiiiittttlllleeee _t_i_t_l_e] [DDDDEEEEFFFF::::_v_n_a_m_e====_r_r_d::::_d_s-_n_a_m_e::::_C_F]
-     [CCCCDDDDEEEEFFFF::::_v_n_a_m_e====_r_p_n-_e_x_p_r_e_s_s_i_o_n] [PPPPRRRRIIIINNNNTTTT::::_v_n_a_m_e::::_C_F::::_f_o_r_m_a_t]
+     rrrrrrrrddddttttoooooooollll ggggrrrraaaapppphhhh _f_i_l_e_n_a_m_e [----ssss|--------ssssttttaaaarrrrtttt _s_e_c_o_n_d_s]
+     [----eeee|--------eeeennnndddd _s_e_c_o_n_d_s] [----xxxx|--------xxxx----ggggrrrriiiidddd _x_-_a_x_i_s _g_r_i_d _a_n_d _l_a_b_e_l]
+     [----yyyy|--------yyyy----ggggrrrriiiidddd _y_-_a_x_i_s _g_r_i_d _a_n_d _l_a_b_e_l] [--------aaaalllltttt----yyyy----ggggrrrriiiidddd] [--------aaaalllltttt----
+     aaaauuuuttttoooossssccccaaaalllleeee] [--------aaaalllltttt----aaaauuuuttttoooossssccccaaaalllleeee----mmmmaaaaxxxx] [--------uuuunnnniiiittttssss----eeeexxxxppppoooonnnneeeennnntttt] _v_a_l_u_e]>
+     [----vvvv|--------vvvveeeerrrrttttiiiiccccaaaallll----llllaaaabbbbeeeellll _t_e_x_t] [----wwww|--------wwwwiiiiddddtttthhhh _p_i_x_e_l_s]
+     [----hhhh|--------hhhheeeeiiiigggghhhhtttt _p_i_x_e_l_s] [----iiii|--------iiiinnnntttteeeerrrrllllaaaacccceeeedddd]
+     [----ffff|--------iiiimmmmggggiiiinnnnffffoooo _f_o_r_m_a_t_s_t_r_i_n_g] [----aaaa|--------iiiimmmmggggffffoooorrrrmmmmaaaatttt GGGGIIIIFFFF|PPPPNNNNGGGG]
+     [----zzzz|--------llllaaaazzzzyyyy] [----oooo|--------llllooooggggaaaarrrriiiitttthhhhmmmmiiiicccc] [----uuuu|--------uuuuppppppppeeeerrrr----lllliiiimmmmiiiitttt _v_a_l_u_e]
+     [----llll|--------lllloooowwwweeeerrrr----lllliiiimmmmiiiitttt _v_a_l_u_e] [----rrrr|--------rrrriiiiggggiiiidddd] [--------sssstttteeeepppp _v_a_l_u_e]
+     [----bbbb|--------bbbbaaaasssseeee _v_a_l_u_e] [----cccc|--------ccccoooolllloooorrrr _C_O_L_O_R_T_A_G####_r_r_g_g_b_b]
+     [----tttt|--------ttttiiiittttlllleeee _t_i_t_l_e] [DDDDEEEEFFFF::::_v_n_a_m_e====_r_r_d::::_d_s_-_n_a_m_e::::_C_F]
+     [CCCCDDDDEEEEFFFF::::_v_n_a_m_e====_r_p_n_-_e_x_p_r_e_s_s_i_o_n] [PPPPRRRRIIIINNNNTTTT::::_v_n_a_m_e::::_C_F::::_f_o_r_m_a_t]
      [GGGGPPPPRRRRIIIINNNNTTTT::::_v_n_a_m_e::::_C_F::::_f_o_r_m_a_t] [CCCCOOOOMMMMMMMMEEEENNNNTTTT::::_t_e_x_t]
      [HHHHRRRRUUUULLLLEEEE::::_v_a_l_u_e####_r_r_g_g_b_b[::::_l_e_g_e_n_d]] [VVVVRRRRUUUULLLLEEEE::::_t_i_m_e####_r_r_g_g_b_b[::::_l_e_g_e_n_d]]
      [LLLLIIIINNNNEEEE{1111|2222|3333}::::_v_n_a_m_e[####_r_r_g_g_b_b[::::_l_e_g_e_n_d]]]
@@ -34,33 +35,32 @@
      reports.
 
      _f_i_l_e_n_a_m_e
-             The name of the graph to generate. Since rrrrrrrrddddttttoooooooollll
-             outputs GIFs and PNGs, it's recommended that the
-             filename end in either ._g_i_f or ._p_n_g.  rrrrrrrrddddttttoooooooollll does
-             not enforce this, however.  If the  _f_i_l_e_n_a_m_e is set
-             to '-' the image file will be written to standard
-             out.  All other output will get suppressed.
+         The name of the graph to generate. Since rrrrrrrrddddttttoooooooollll outputs
+         GIFs and PNGs, it's recommended that the filename end in
+         either _._g_i_f or _._p_n_g.  rrrrrrrrddddttttoooooooollll does not enforce this,
+         however.  If the  _f_i_l_e_n_a_m_e is set to '-' the image file
+         will be written to standard out.  All other output will
+         get suppressed.
 
-             PNG output is recommended, since it takes up to 40%
-             less disk space and 20-30% less time to generate
-             than a GIF file.
+         PNG output is recommended, since it takes up to 40% less
+         disk space and 20-30% less time to generate than a GIF
+         file.
 
-             If no graph functions are called, the graph will not
-             be created.
+         If no graph functions are called, the graph will not be
+         created.
 
-     -ssss|--------ssssttttaaaarrrrtttt _s_e_c_o_n_d_s (default end-1day)
-             The time when the graph should begin. Time in
-             seconds since epoch (1970-01-01) is required.
-             Negative numbers are relative to the current time.
-             By default one day worth of data will be graphed.
-             See also AT-STYLE TIME SPECIFICATION section in the
-             _r_r_d_f_e_t_c_h documentation for a detailed explanation on
-             how to specify time.
+     ----ssss|--------ssssttttaaaarrrrtttt _s_e_c_o_n_d_s (default end-1day)
+         The time when the graph should begin. Time in seconds
+         since epoch (1970-01-01) is required. Negative numbers
+         are relative to the current time. By default one day
+         worth of data will be graphed.  See also AT-STYLE TIME
+         SPECIFICATION section in the _r_r_d_f_e_t_c_h documentation for
+         a detailed explanation on how to specify time.
 
 
 
 
-12/Feb/2000            Last change: 1.0.13                      1
+2001-02-20             Last change: 1.0.33                      1
 
 
 
@@ -71,62 +71,62 @@
 
 
 
-     -eeee|--------eeeennnndddd _s_e_c_o_n_d_s (default now)
-             The time when the graph should end. Time in seconds
-             since epoch.  See also AT-STYLE TIME SPECIFICATION
-             section in the _r_r_d_f_e_t_c_h documentation for a detailed
-             explanation of ways to specify time.
-
-     -xxxx|--------xxxx----ggggrrrriiiidddd _x-_a_x_i_s _g_r_i_d _a_n_d _l_a_b_e_l (default autoconfigure)
-             The x-axis label is quite complex to configure. So
-             if you don't have very special needs, you can rely
-             on the autoconfiguration to get this right.
-
-             The x-axis label is configured, using the following
-             format:
-
-             _G_T_M::::_G_S_T::::_M_T_M::::_M_S_T::::_L_T_M:_L_S_T::::_L_P_R::::_L_F_M
-
-             You have to configure three elements making up the
-             x-axis labels and grid. The base grid (_G??), the
-             major grid (_M??) and the labels (_L??). The
-             configuration is based on the idea that you first
-             specify a well known amount of time (?_T_M) and then
-             say how many times it has to pass between each grid
-             line or label (?_S_T). For the label you have to
-             define two additional items: The precision of the
-             label in seconds (_L_P_R) and the strftime format used
-             to generate the text of the label (_L_F_M).
-
-             The ?_T_M elements must be one of the following
-             keywords: SSSSEEEECCCCOOOONNNNDDDD, MMMMIIIINNNNUUUUTTTTEEEE, HHHHOOOOUUUURRRR, DDDDAAAAYYYY, WWWWEEEEEEEEKKKK, MMMMOOOONNNNTTTTHHHH or
-             YYYYEEEEAAAARRRR.
+     ----eeee|--------eeeennnndddd _s_e_c_o_n_d_s (default now)
+         The time when the graph should end. Time in seconds
+         since epoch.  See also AT-STYLE TIME SPECIFICATION
+         section in the _r_r_d_f_e_t_c_h documentation for a detailed
+         explanation of ways to specify time.
+
+     ----xxxx|--------xxxx----ggggrrrriiiidddd _x_-_a_x_i_s _g_r_i_d _a_n_d _l_a_b_e_l (default autoconfigure)
+         The x-axis label is quite complex to configure. So if
+         you don't have very special needs, you can rely on the
+         autoconfiguration to get this right.
+
+         If you want no x-grid at all, use the magic setting
+         nnnnoooonnnneeee.
+
+         The x-axis label and grid can be configured, using the
+         following format:
+
+         _G_T_M::::_G_S_T::::_M_T_M::::_M_S_T::::_L_T_M:_L_S_T::::_L_P_R::::_L_F_M
+
+         You have to configure three elements making up the x-
+         axis labels and grid. The base grid (_G_?_?), the major
+         grid (_M_?_?) and the labels (_L_?_?). The configuration is
+         based on the idea that you first specify a well known
+         amount of time (_?_T_M) and then say how many times it has
+         to pass between each grid line or label (_?_S_T). For the
+         label you have to define two additional items: The
+         precision of the label in seconds (_L_P_R) and the strftime
+         format used to generate the text of the label (_L_F_M).
+
+         The _?_T_M elements must be one of the following keywords:
+         SSSSEEEECCCCOOOONNNNDDDD, MMMMIIIINNNNUUUUTTTTEEEE, HHHHOOOOUUUURRRR, DDDDAAAAYYYY, WWWWEEEEEEEEKKKK, MMMMOOOONNNNTTTTHHHH or YYYYEEEEAAAARRRR.
+
+         If you wanted a graph with a base grid every 10 minutes
+         and a major one every hour, with labels every hour you
+         would use the following x-axis definition.
+
+         `MINUTE:10:HOUR:1:HOUR:1:0:%X'
+
+         The precision in this example is 0 because the %X format
+         is exact. If the label was the name of the day, we would
+         have had a precision of 24 hours, because when you say
+         something like 'Monday' you mean the whole day and not
+         Monday morning 00:00. Thus the label should be
+         positioned at noon. By defining a precision of 24 hours
+         or rather 86400 seconds, you make sure that this
+         happens.
+
+     ----yyyy|--------yyyy----ggggrrrriiiidddd _g_r_i_d _s_t_e_p:_l_a_b_e_l _f_a_c_t_o_r (default autoconfigure)
+         Makes vertical grid lines appear at _g_r_i_d _s_t_e_p interval.
+         Every _l_a_b_e_l _f_a_c_t_o_r gridstep, a major grid line is
+         printed, along with label showing the value of the grid
+         line.
 
-             If you wanted a graph with a base grid every 10
-             minutes and a major one every hour, with labels
-             every hour you would use the following x-axis
-             definition.
 
-             MINUTE:10:HOUR:1:HOUR:1:0:%X
 
-             The precision in this example is 0 because the %X
-             format is exact. If the label was the name of the
-             day, we would have had a precision of 24 hours,
-             because when you say something like 'Monday' you
-             mean the whole day and not Monday morning 00:00.
-             Thus the label should be positioned at noon. By
-             defining a precision of 24 hours or rather 86400
-             seconds, you make sure that this happens.
-
-     -yyyy|--------yyyy----ggggrrrriiiidddd _g_r_i_d _s_t_e_p:_l_a_b_e_l _f_a_c_t_o_r (default autoconfigure)
-             Makes vertical grid lines appear at _g_r_i_d _s_t_e_p
-             interval. Every _l_a_b_e_l _f_a_c_t_o_r gridstep, a major grid
-             line is printed, along with label showing the value
-             of the grid line.
-
-
-
-12/Feb/2000            Last change: 1.0.13                      2
+2001-02-20             Last change: 1.0.33                      2
 
 
 
@@ -137,62 +137,62 @@
 
 
 
+         If you want no y-grid at all set specify the magic word
+         nnnnoooonnnneeee.
+
      --------aaaalllltttt----yyyy----ggggrrrriiiidddd
-             Place Y grid dynamically based on graph Y range.
-             Algorithm ensures that you always have grid, that
-             there are enough but not too many grid lines and the
-             grid is metric. That is grid lines are placed every
-             1, 2, 5 or 10 units.  (contributed by Sasha Mikheev)
+         Place Y grid dynamically based on graph Y range.
+         Algorithm ensures that you always have grid, that there
+         are enough but not too many grid lines and the grid is
+         metric. That is grid lines are placed every 1, 2, 5 or
+         10 units.  (contributed by Sasha Mikheev)
 
      --------aaaalllltttt----aaaauuuuttttoooossssccccaaaalllleeee
-             Compute Y range  based on function absolute minimum
-             and maximum values. Default algorithm uses
-             predefined set of ranges. This is good in many cases
-             but it fails miserably when you need to graph
-             something like 260 + 0.001 * _s_i_n(x). Default
-             algorithm will use Y range from 250 to 300 and on
-             the graph you will see almost straight line. With
-             --alt-autoscale Y range will be from slightly less
-             the 260 - 0.001 to slightly more then 260 + 0.001
-             and periodic behavior will be seen.   (contributed
-             by Sasha Mikheev)
+         Compute Y range  based on function absolute minimum and
+         maximum values. Default algorithm uses predefined set of
+         ranges.  This is good in many cases but it fails
+         miserably when you need to graph something like 260 +
+         0.001 * _s_i_n(x). Default algorithm will use Y range from
+         250 to 300 and on the graph you will see almost straight
+         line. With --alt-autoscale Y range will be from slightly
+         less the 260 - 0.001 to slightly more then 260 + 0.001
+         and periodic behavior will be seen.   (contributed by
+         Sasha Mikheev)
+
+     --------aaaalllltttt----aaaauuuuttttoooossssccccaaaalllleeee----mmmmaaaaxxxx
+         Where --alt-autoscale will modify both the absolute
+         maximum AND minimum values, this option will only affect
+         the maximum value. The minimum value, if not defined on
+         the command line, will be 0. This option can be useful
+         when graphing router traffic when the WAN line uses
+         compression, and thus the throughput may be higher than
+         the WAN line speed.
+
+     --------uuuunnnniiiittttssss----eeeexxxxppppoooonnnneeeennnntttt _v_a_l_u_e (default autoconfigure)
+         This sets the 10**exponent scaling of the y-axis values.
+         Normally values will be scaled to the appropriate units
+         (k, M, etc.).  However you may wish to display units
+         always in k (Kilo, 10e3) even if the data is in the M
+         (Mega, 10e6) range for instance.  Value should be an
+         integer which is a multiple of 3 between -18 and 18
+         inclusive.  It is the exponent on the units you which to
+         use.  For example, use 3 to display the y-axis values in
+         k (Kilo, 10e3, thousands), use -6 to display the y-axis
+         values in u (Micro, 10e-6, millionths).  Use a value of
+         0 to prevent any scaling of the y-axis values.
+
+     ----vvvv|--------vvvveeeerrrrttttiiiiccccaaaallll----llllaaaabbbbeeeellll _t_e_x_t
+         vertical label on the left side of the graph. This is
+         normally used to specify the units used.
+
+     ----wwww|--------wwwwiiiiddddtttthhhh _p_i_x_e_l_s (default 400 pixel)
+         Width of the drawing area within the graph. This affects
+         the size of the gif.
 
-     -vvvv|--------vvvveeeerrrrttttiiiiccccaaaallll----llllaaaabbbbeeeellll _t_e_x_t
-             vertical label on the left side of the graph. This
-             is normally used to specify the units used.
 
-     -wwww|--------wwwwiiiiddddtttthhhh _p_i_x_e_l_s (default 400 pixel)
-             Width of the drawing area within the graph. This
-             affects the size of the gif.
 
-     -hhhh|--------hhhheeeeiiiigggghhhhtttt _p_i_x_e_l_s (default 100 pixel)
-             Width of the drawing area within the graph. This
-             affects the size of the gif.
 
-     -iiii|--------iiiinnnntttteeeerrrrllllaaaacccceeeedddd (default: false)
-             If you set this option, then the resulting GIF will
-             be interlaced.  Most web browsers display these
-             incrementally as they load. If you do not use this
-             option, the GIFs default to being progressive
-             scanned. The only effect of this option is to
-             control the format of the GIF on disk. It makes no
-             changes to the layout or contents of the graph.
-
-     -ffff|--------iiiimmmmggggiiiinnnnffffoooo _f_o_r_m_a_t_s_t_r_i_n_g
-             After the image has been created, the graph function
-             uses printf together with this format string to
-             create output similar to the PRINT function, only
-             that the printf is supplied with the parameters
-             _f_i_l_e_n_a_m_e, _x_s_i_z_e and _y_s_i_z_e. In order to generate an
-             IIIIMMMMGGGG tag suitable for including the graph into a web
-             page, the command line would look like this:
-
-              --imginfo '<IMG SRC="/img/%s" WIDTH="%lu" HEIGHT="%lu" ALT="Demo">'
-
-
-
-
-12/Feb/2000            Last change: 1.0.13                      3
+2001-02-20             Last change: 1.0.33                      3
 
 
 
@@ -203,62 +203,62 @@
 
 
 
-     -aaaa|--------iiiimmmmggggffffoooorrrrmmmmaaaatttt GGGGIIIIFFFF|PPPPNNNNGGGG (default: GIF)
-             Allows you to produce PNG output from rrdtool.
-
-     -zzzz|--------llllaaaazzzzyyyy (default: false)
-             Only generate the graph, if the current gif is out
-             of date or not existent.
-
-     -uuuu|--------uuuuppppppppeeeerrrr----lllliiiimmmmiiiitttt _v_a_l_u_e (default autoconfigure)
-             This is not the upper limit of a graph!  But rather,
-             this is the minimum upper bound of a graph.  Use
-             this to expand graphs up.  For example, the value
-             100 will result in graphs that have a upper bound of
-             100 or more.  Setting the upper limit to the maximum
-             value for some DS will result in disabling RRDtool's
-             autoscaling down (ie it will "expand" graphs up.)
-             To disable RRDtool's autoscaling up (to the max
-             value for the DSs graphed), use a nifty CDEF like
-             so:  CDEF:mcpu=cpu,100,GT,100,cpu,IF.  If this CDEF
-             is applied to all DSs in a graph, then the graph
-             will have an upper limit of 100.
-
-     -llll|--------lllloooowwwweeeerrrr----lllliiiimmmmiiiitttt _v_a_l_u_e (default autoconfigure)
-             This is not the lower limit of a graph.  But rather,
-             this is the maximum lower bound of a graph.  For
-             example, the value -100 will result in a graph that
-             has a lower limit of -100 or less.  Use this keyword
-             to expand graphs down.
-
-     -rrrr|--------rrrriiiiggggiiiidddd
-             rigid boundaries mode.  Normally rrdgraph will
-             automatically expand the lower and upper limit if
-             the graph contains a value outside the valid range.
-             With the r option you can disable this behavior
+     ----hhhh|--------hhhheeeeiiiigggghhhhtttt _p_i_x_e_l_s (default 100 pixel)
+         Width of the drawing area within the graph. This affects
+         the size of the gif.
+
+     ----iiii|--------iiiinnnntttteeeerrrrllllaaaacccceeeedddd (default: false)
+         If you set this option, then the resulting GIF will be
+         interlaced.  Most web browsers display these
+         incrementally as they load. If you do not use this
+         option, the GIFs default to being progressive scanned.
+         The only effect of this option is to control the format
+         of the GIF on disk. It makes no changes to the layout or
+         contents of the graph.
+
+     ----ffff|--------iiiimmmmggggiiiinnnnffffoooo _f_o_r_m_a_t_s_t_r_i_n_g
+         After the image has been created, the graph function
+         uses printf together with this format string to create
+         output similar to the PRINT function, only that the
+         printf is supplied with the parameters _f_i_l_e_n_a_m_e, _x_s_i_z_e
+         and _y_s_i_z_e. In order to generate an IIIIMMMMGGGG tag suitable for
+         including the graph into a web page, the command line
+         would look like this:
+
+          --imginfo '<IMG SRC="/img/%s" WIDTH="%lu" HEIGHT="%lu" ALT="Demo">'
+
+
+     ----aaaa|--------iiiimmmmggggffffoooorrrrmmmmaaaatttt GGGGIIIIFFFF|PPPPNNNNGGGG (default: GIF)
+         Allows you to produce PNG output from rrdtool.
+
+     ----zzzz|--------llllaaaazzzzyyyy (default: false)
+         Only generate the graph, if the current gif is out of
+         date or not existent.
+
+     ----uuuu|--------uuuuppppppppeeeerrrr----lllliiiimmmmiiiitttt _v_a_l_u_e (default autoconfigure)
+         Defines the value normally located at the upper border
+         of the graph. If the graph contains higher values, the
+         upper border will move upwards to accomodate these
+         values as well.
+
+         If you want to define an upper-limit which will not move
+         in any event you have to set the --------rrrriiiiggggiiiidddd option as well.
+
+     ----llll|--------lllloooowwwweeeerrrr----lllliiiimmmmiiiitttt _v_a_l_u_e (default autoconfigure)
+         This is not the lower limit of a graph.  But rather,
+         this is the maximum lower bound of a graph.  For
+         example, the value -100 will result in a graph that has
+         a lower limit of -100 or less.  Use this keyword to
+         expand graphs down.
+
+     ----rrrr|--------rrrriiiiggggiiiidddd
+         rigid boundaries mode.  Normally rrdgraph will
+         automatically expand the lower and upper limit if the
+         graph contains a value outside the valid range. With the
 
-     -bbbb|--------bbbbaaaasssseeee _v_a_l_u_e
-             if you are graphing memory (and NOT network traffic)
-             this switch should be set to 1024 so that one Kb is
-             1024 byte. For traffic measurement, 1 kb/s is 1000
-             b/s.
 
-     -oooo|--------llllooooggggaaaarrrriiiitttthhhhmmmmiiiicccc
-             logarithmic y-axis scaling
 
-     -cccc|--------ccccoooolllloooorrrr _C_O_L_O_R_T_A_G####_r_r_g_g_b_b (default colors)
-             override the colors for the standard elements of the
-             graph. The _C_O_L_O_R_T_A_G must be one of the following
-             symbolic names: BBBBAAAACCCCKKKK ground, CCCCAAAANNNNVVVVAAAASSSS, SSSSHHHHAAAADDDDEEEEAAAA left/top
-             border, SSSSHHHHAAAADDDDEEEEBBBB right/bottom border, GGGGRRRRIIIIDDDD, MMMMGGGGRRRRIIIIDDDD
-             major grid, FFFFOOOONNNNTTTT, FFFFRRRRAAAAMMMMEEEE and axis of the graph or
-             AAAARRRRRRRROOOOWWWW. This option can be called multiple times to
-             set several colors.
-
-
-
-
-12/Feb/2000            Last change: 1.0.13                      4
+2001-02-20             Last change: 1.0.33                      4
 
 
 
@@ -269,128 +269,194 @@
 
 
 
-     -tttt|--------ttttiiiittttlllleeee _t_e_x_t (default no title)
-             Define a title to be written into the graph
+         r option you can disable this behavior
 
-     DDDDEEEEFFFF::::_v_n_a_m_e====_r_r_d::::_d_s-_n_a_m_e::::_C_F
-             Define virtual name for a data source. This name can
-             then be used in the functions explained below. The
-             DEF call automatically chooses an RRRRRRRRAAAA which contains
-             _C_F consolidated data in a resolution appropriate for
-             the size of the graph to be drawn.  Ideally this
-             means that one data point from the RRRRRRRRAAAA should be
-             represented by one pixel in the graph.  If the
-             resolution of the RRRRRRRRAAAA is higher than the resolution
-             of the graph, the data in the RRA will be further
-             consolidated according to the consolidation function
-             (_C_F) chosen.
+     ----bbbb|--------bbbbaaaasssseeee _v_a_l_u_e
+         if you are graphing memory (and NOT network traffic)
+         this switch should be set to 1024 so that one Kb is 1024
+         byte. For traffic measurement, 1 kb/s is 1000 b/s.
+
+     ----oooo|--------llllooooggggaaaarrrriiiitttthhhhmmmmiiiicccc
+         logarithmic y-axis scaling
+
+     ----cccc|--------ccccoooolllloooorrrr _C_O_L_O_R_T_A_G####_r_r_g_g_b_b (default colors)
+         override the colors for the standard elements of the
+         graph. The _C_O_L_O_R_T_A_G must be one of the following
+         symbolic names: BBBBAAAACCCCKKKK ground, CCCCAAAANNNNVVVVAAAASSSS, SSSSHHHHAAAADDDDEEEEAAAA left/top
+         border, SSSSHHHHAAAADDDDEEEEBBBB right/bottom border, GGGGRRRRIIIIDDDD, MMMMGGGGRRRRIIIIDDDD major
+         grid, FFFFOOOONNNNTTTT, FFFFRRRRAAAAMMMMEEEE and axis of the graph or AAAARRRRRRRROOOOWWWW. This
+         option can be called multiple times to set several
+         colors.
+
+     ----gggg|--------nnnnoooo----lllleeeeggggeeeennnndddd
+         Suppress generation of legend; only render the graph.
+
+     ----tttt|--------ttttiiiittttlllleeee _t_e_x_t (default no title)
+         Define a title to be written into the graph
+
+     --------sssstttteeeepppp _v_a_l_u_e (default automatic)
+         By default rrdgraph calculates the width of one pixle in
+         the time domain and tries to get data at that resolution
+         from the RRD. With this switch you can override this
+         behaviour. If you want rrdgraph to get data at 1 hour
+         resolution from the RRD, then you can set the step to
+         3600 seconds. Note, that a step smaller than 1 pixle
+         will be silently ignored.
+
+     DDDDEEEEFFFF::::_v_n_a_m_e====_r_r_d::::_d_s_-_n_a_m_e::::_C_F
+         Define virtual name for a data source. This name can
+         then be used in the functions explained below. The DEF
+         call automatically chooses an RRRRRRRRAAAA which contains _C_F
+         consolidated data in a resolution appropriate for the
+         size of the graph to be drawn.  Ideally this means that
+         one data point from the RRRRRRRRAAAA should be represented by one
+         pixel in the graph.  If the resolution of the RRRRRRRRAAAA is
+         higher than the resolution of the graph, the data in the
+         RRA will be further consolidated according to the
+         consolidation function (_C_F) chosen.
+
+     CCCCDDDDEEEEFFFF::::_v_n_a_m_e====_r_p_n_-_e_x_p_r_e_s_s_i_o_n
+         Create a new virtual data source by evaluating a
+         mathematical expression, specified in Reverse Polish
+         Notation (RPN). If you have ever used a traditional HP
+         calculator you already know RPN. The idea behind RPN
+         notation is, that you have a stack and push your data
 
-     CCCCDDDDEEEEFFFF::::_v_n_a_m_e====_r_p_n-_e_x_p_r_e_s_s_i_o_n
-             Create a new virtual data source by evaluating a
-             mathematical expression, specified in Reverse Polish
-             Notation (RPN). If you have ever used a traditional
-             HP calculator you already know RPN. The idea behind
-             RPN notation is, that you have a stack and push your
-             data onto this stack. When ever you execute an
-             operation, it takes as many data values from the
-             stack as needed. The pushing of data is implicit, so
-             when ever you specify a number or a variable, it
-             gets pushed automatically.
 
-             If this is all a big load of incomprehensible words
-             for you, maybe an example helps (a more complete
-             explanation is given in [1]): The expression
-             _v_n_a_m_e+_3/_2 becomes vname,3,2,/,+ in RPN. First the
-             three values get pushed onto the stack (which now
-             contains (the current value of) vname, a 3 and a 2).
-             Then the / operator pops two values from the stack
-             (3 and 2), divides the first argument by the second
-             (3/2) and pushes the result (1.5) back onto the
-             stack. Then the + operator pops two values (vname
-             and 1.5) from the stack; both values are added up
-             and the result gets pushes back onto the stack. In
-             the end there is only one value left on the stack:
-             The result of the expression.
 
-             The _r_p_n-_e_x_p_r_e_s_s_i_o_n in the CCCCDDDDEEEEFFFF function takes both,
-             constant values as well as _v_n_a_m_e variables. The
-             following operators can be used on these values:
+2001-02-20             Last change: 1.0.33                      5
 
-     +, -, *, /, %   pops two values from the stack applies the
-                     selected operator and pushes the result back
-                     onto the stack. The % operator stands for
-                     the modulo operation.
 
 
 
 
-12/Feb/2000            Last change: 1.0.13                      5
 
+rrdtool                                               RRDGRAPH(1)
 
 
 
+         onto this stack. When ever you execute an operation, it
+         takes as many data values from the stack as needed. The
+         pushing of data is implicit, so when ever you specify a
+         number or a variable, it gets pushed automatically.
+
+         If this is all a big load of incomprehensible words for
+         you, maybe an example helps (a more complete explanation
+         is given in [1]): The expression _v_n_a_m_e_+_3_/_2 becomes
+         `vname,3,2,/,+' in RPN. First the three values get
+         pushed onto the stack (which now contains (the current
+         value of) vname, a 3 and a 2).  Then the / operator pops
+         two values from the stack (3 and 2), divides the first
+         argument by the second (3/2) and pushes the result (1.5)
+         back onto the stack. Then the + operator pops two values
+         (vname and 1.5) from the stack; both values are added up
+         and the result gets pushes back onto the stack. In the
+         end there is only one value left on the stack: The
+         result of the expression.
+
+         The _r_p_n_-_e_x_p_r_e_s_s_i_o_n in the CCCCDDDDEEEEFFFF function takes both,
+         constant values as well as _v_n_a_m_e variables. The
+         following operators can be used on these values:
+
+         +, -, *, /, %
+             pops two values from the stack applies the selected
+             operator and pushes the result back onto the stack.
+             The % operator stands for the modulo operation.
+
+         SIN, COS, LOG, EXP, FLOOR, CEIL
+             pops one value from the stack, applies the selected
+             function and pushes the result back onto the stack.
+
+         LT, LE, GT, GE, EQ
+             pops two values from the stack, compares them
+             according to the selected condition and pushes
+             either 1 back onto the stack if the condition is
+             true and 0 if the condition was not true.
+
+         IF  pops three values from the stack. If the last value
+             is not 0, the second value will be pushed back onto
+             the stack, otherwise the first value is pushed back.
+
+             If the stack contains the values A, B, C, D, E are
+             presently on the stack, the IF operator will pop the
+             values E D and C of the stack. It will look at C and
+             if it is not 0 it will push D back onto the stack,
+             otherwise E will be sent back to the stack.
+
+         MIN, MAX
+             selects the lesser or larger of the two top stack
+             values respectively
 
 
-rrdtool                                               RRDGRAPH(1)
 
 
+2001-02-20             Last change: 1.0.33                      6
 
-     SIN, COS, LOG, EXP
-                     pops one value from the stack, applies the
-                     selected function and pushes the result back
-                     onto the stack.
 
-     LT, LE, GT, GE, EQ
-                     pops two values from the stack, compares
-                     them according to the selected condition and
-                     pushes either 1 back onto the stack if the
-                     condition is true and 0 if the condition was
-                     not true.
 
-     IF              pops three values from the stack. If the
-                     last value is not 0, the second value will
-                     be pushed back onto the stack, otherwise the
-                     first value is pushed back.
 
-                     If the stack contains the values A, B, C, D,
-                     E are presently on the stack, the IF
-                     operator will pop the values E D and C of
-                     the stack. It will look at C and if it is
-                     not 0 it will push D back onto the stack,
-                     otherwise E will be sent back to the stack.
 
-     DUP, EXC, POP   These manipulate the stack directly.  DUP
-                     will duplicate the top of the stack, pushing
-                     the result back onto the stack.  EXC will
-                     exchange the top two elements of the stack,
-                     and POP will pop off the top element of the
-                     stack.  Having insufficient elements on the
-                     stack for these operations is an error.
 
-     UN              Pops one value off the stack, if it is
-                     *_U_N_K_N_O_W_N*, 1 will be pushed back otherwise
-                     0.
+rrdtool                                               RRDGRAPH(1)
 
-     UNKN            Push an *_U_N_K_N_O_W_N* value onto the stack.
 
-     PREV            Push *_U_N_K_N_O_W_N* if its at the first value of
-                     a data set or otherwise the value of this
-                     CDEF at the previous time step. This allows
-                     you to perform calculations across the data.
 
-     INF, NEGINF     Push a positive or negative infinite (oo)
-                     value onto the stack. When drawing an
-                     infinite number it appears right at the top
-                     or bottom edge of the graph, depending
-                     whether you have a positive or negative
-                     infinite number.
+         LIMIT
+             replaces the value with _*_U_N_K_N_O_W_N_* if it is outside
+             the limits specified by the two values above it on
+             the stack.
+
+              CDEF:a=alpha,0,100,LIMIT
+
+
+         DUP, EXC, POP
+             These manipulate the stack directly.  DUP will
+             duplicate the top of the stack, pushing the result
+             back onto the stack.  EXC will exchange the top two
+             elements of the stack, and POP will pop off the top
+             element of the stack.  Having insufficient elements
+             on the stack for these operations is an error.
+
+         UN  Pops one value off the stack, if it is _*_U_N_K_N_O_W_N_*, 1
+             will be pushed back otherwise 0.
+
+         UNKN
+             Push an _*_U_N_K_N_O_W_N_* value onto the stack.
+
+         PREV
+             Push _*_U_N_K_N_O_W_N_* if its at the first value of a data
+             set or otherwise the value of this CDEF at the
+             previous time step. This allows you to perform
+             calculations across the data.
+
+         INF, NEGINF
+             Push a positive or negative infinite (oo) value onto
+             the stack. When drawing an infinite number it
+             appears right at the top or bottom edge of the
+             graph, depending whether you have a positive or
+             negative infinite number.
+
+         NOW Push the current (real world) time onto the stack.
+
+         TIME
+             Push the time the current sample was taken onto the
+             stack. This is the number of non-skip seconds since
+             0:00:00 January 1, 1970.
+
+         LTIME
+             This is like TIME ++++ ccccuuuurrrrrrrreeeennnntttt ttttiiiimmmmeeeezzzzoooonnnneeee ooooffffffffsssseeeetttt iiiinnnn
+             sssseeeeccccoooonnnnddddssss. The current offset takes daylight saving
+             time into account, given your OS supports this. If
+             you were looking at a sample, in Zurich, in summer,
+             the offset would be 2*3600 seconds, as Zurich at
+             that time of year is 2 hours ahead of UTC.
 
-     NOW             Push the current (real world) time onto the
-                     stack.
+             Note that the timezone offset is always calculated
+             for the time the current sample was taken at. It has
 
 
 
-12/Feb/2000            Last change: 1.0.13                      6
+2001-02-20             Last change: 1.0.33                      7
 
 
 
@@ -401,102 +467,109 @@
 
 
 
-     TIME            Push the time the current sample was taken
-                     onto the stack.
+             nuthing todo with the time you are doing the
+             calculation.
 
-                     Please note that you may only use _v_n_a_m_e
-                     variables that you previously defined by
-                     either DDDDEEEEFFFF or CCCCDDDDEEEEFFFF. Furthermore, as of this
-                     writing (version 0.99.25), you must use at
-                     least one _v_n_a_m_e per expression, that is
-                     "CDEF:fourtytwo=2,40,+" will yield an error
-                     message but not a _v_n_a_m_e fourtytwo that's
-                     always equal to 42.
+         Please note that you may only use _v_n_a_m_e variables that
+         you previously defined by either DDDDEEEEFFFF or CCCCDDDDEEEEFFFF.
+         Furthermore, as of this writing (version 0.99.25), you
+         must use at least one _v_n_a_m_e per expression, that is
+         "CDEF:fourtytwo=2,40,+" will yield an error message but
+         not a _v_n_a_m_e fourtytwo that's always equal to 42.
 
      PPPPRRRRIIIINNNNTTTT::::_v_n_a_m_e::::_C_F::::_f_o_r_m_a_t
-             Calculate the chosen consolidation function _C_F over
-             the data-source variable _v_n_a_m_e and printf the result
-             to stdout using _f_o_r_m_a_t.  In the _f_o_r_m_a_t string there
-             should be a '%lf' or '%le' marker in the place where
-             the number should be printed.
-
-             If an additional '%s' is found AFTER the marker, the
-             value will be scaled and an appropriate SI magnitude
-             unit will be printed in place of the '%s' marker.
-             The scaling will take the '--base' argument into
-             consideration!
-
-             If a '%S' is used instead of a '%s', then instead of
-             calculating the appropriate SI magnitude unit for
-             this value, the previously calculated SI magnitude
-             unit will be used.  This is useful if you want all
-             the values in a PRINT statement to have the same SI
-             magnitude unit.  If there was no previous SI
-             magnitude calculation made, then '%S' behaves like a
-             '%s', unless the value is 0, in which case it does
-             not remember a SI magnitude unit and a SI magnitude
-             unit will only be calculated when the next '%s' is
-             seen or the next '%S' for a non-zero value.
+         Calculate the chosen consolidation function _C_F over the
+         data-source variable _v_n_a_m_e and `printf' the result to
+         stdout using _f_o_r_m_a_t.  In the _f_o_r_m_a_t string there should
+         be a '%lf' or '%le' marker in the place where the number
+         should be printed.
+
+         If an additional '%s' is found AFTER the marker, the
+         value will be scaled and an appropriate SI magnitude
+         unit will be printed in place of the '%s' marker. The
+         scaling will take the '--base' argument into
+         consideration!
+
+         If a '%S' is used instead of a '%s', then instead of
+         calculating the appropriate SI magnitude unit for this
+         value, the previously calculated SI magnitude unit will
+         be used.  This is useful if you want all the values in a
+         PRINT statement to have the same SI magnitude unit.  If
+         there was no previous SI magnitude calculation made,
+         then '%S' behaves like a '%s', unless the value is 0, in
+         which case it does not remember a SI magnitude unit and
+         a SI magnitude unit will only be calculated when the
+         next '%s' is seen or the next '%S' for a non-zero value.
+
+         If you want to put a '%' into your PRINT string, use
+         '%%' instead.
 
      GGGGPPPPRRRRIIIINNNNTTTT::::_v_n_a_m_e::::_C_F::::_f_o_r_m_a_t
-             Same as PPPPRRRRIIIINNNNTTTT but the result is printed into the
-             graph below the legend.
+         Same as PPPPRRRRIIIINNNNTTTT but the result is printed into the graph
+         below the legend.
+
+     CCCCaaaavvvveeeeaaaatttt:::: When using the PPPPRRRRIIIINNNNTTTT and GGGGRRRRPPPPRRRRIIIINNNNTTTT functions to
+     calculate data summaries over time periods bounded by the
+     current time, it is important to note that the last sample
+     will almost always yield a value of UNKNOWN as it lies after
+     the last update time.  This can result in slight data
+     skewing, particularly with the AAAAVVVVEEEERRRRAAAAGGGGEEEE function.  In order
+     to avoid this, make sure that your end time is at least one
+     heartbeat prior to the current time.
 
      CCCCOOOOMMMMMMMMEEEENNNNTTTT::::_t_e_x_t
-             Like GGGGPPPPRRRRIIIINNNNTTTT but the _t_e_x_t is simply printed into the
-             graph.
+         Like GGGGPPPPRRRRIIIINNNNTTTT but the _t_e_x_t is simply printed into the
 
-     HHHHRRRRUUUULLLLEEEE::::_v_a_l_u_e####_r_r_g_g_b_b[::::_l_e_g_e_n_d]
-             Draw a horizontal rule into the graph and optionally
-             add a legend
 
-     VVVVRRRRUUUULLLLEEEE::::_t_i_m_e####_r_r_g_g_b_b[::::_l_e_g_e_n_d]
-             Draw a vertical rule into the graph and optionally
-             add a legend
 
+2001-02-20             Last change: 1.0.33                      8
 
 
-12/Feb/2000            Last change: 1.0.13                      7
 
 
 
 
+rrdtool                                               RRDGRAPH(1)
 
 
-rrdtool                                               RRDGRAPH(1)
 
+         graph.
+
+     HHHHRRRRUUUULLLLEEEE::::_v_a_l_u_e####_r_r_g_g_b_b[::::_l_e_g_e_n_d]
+         Draw a horizontal rule into the graph and optionally add
+         a legend
 
+     VVVVRRRRUUUULLLLEEEE::::_t_i_m_e####_r_r_g_g_b_b[::::_l_e_g_e_n_d]
+         Draw a vertical rule into the graph and optionally add a
+         legend
 
      LLLLIIIINNNNEEEE{1111|2222|3333}::::_v_n_a_m_e[####_r_r_g_g_b_b[::::_l_e_g_e_n_d]]
-             Plot for the requested data, using the color
-             specified. Write a legend into the graph. The 3
-             possible keywords LLLLIIIINNNNEEEE1111, LLLLIIIINNNNEEEE2222, and LLLLIIIINNNNEEEE3333 generate
-             increasingly wide lines. If no color is defined, the
-             drawing is done 'blind' this is useful in connection
-             with the SSSSTTTTAAAACCCCKKKK function when you want to ADD the
-             values of two data-sources without showing it in the
-             graph.
+         Plot for the requested data, using the color specified.
+         Write a legend into the graph. The 3 possible keywords
+         LLLLIIIINNNNEEEE1111, LLLLIIIINNNNEEEE2222, and LLLLIIIINNNNEEEE3333 generate increasingly wide
+         lines. If no color is defined, the drawing is done
+         'blind' this is useful in connection with the SSSSTTTTAAAACCCCKKKK
+         function when you want to ADD the values of two data-
+         sources without showing it in the graph.
 
      AAAARRRREEEEAAAA:_v_n_a_m_e[####_r_r_g_g_b_b[::::_l_e_g_e_n_d]]
-             Does the same as LLLLIIIINNNNEEEE????, but the area between 0 and
-             the graph will be filled with the color specified.
+         Does the same as LLLLIIIINNNNEEEE????, but the area between 0 and the
+         graph will be filled with the color specified.
 
      SSSSTTTTAAAACCCCKKKK:_v_n_a_m_e[####_r_r_g_g_b_b[::::_l_e_g_e_n_d]]
-             Does the same as LLLLIIIINNNNEEEE????, but the graph gets stacked
-             on top of the previous LLLLIIIINNNNEEEE????, AAAARRRREEEEAAAA or SSSSTTTTAAAACCCCKKKK graph.
-             Depending on the type of the previous graph, the
-             SSSSTTTTAAAACCCCKKKK will be either a LLLLIIIINNNNEEEE???? or an AAAARRRREEEEAAAA.  This
-             obviously implies that the first SSSSTTTTAAAACCCCKKKK must be
-             preceded by an AAAARRRREEEEAAAA or LLLLIIIINNNNEEEE???? -- you need something
-             to stack something onto in the first place ;)
-
-             Note, that when you STACK onto *UNKNOWN* data,
-             rrdtool will not draw any graphics ... *UNKNOWN* is
-             not zero ... if you want it to zero then you might
-             want to use a CDEF argument with IF and UN functions
-             to turn *UNKNOWN* into zero ...
-
-             =back
+         Does the same as LLLLIIIINNNNEEEE????, but the graph gets stacked on
+         top of the previous LLLLIIIINNNNEEEE????, AAAARRRREEEEAAAA or SSSSTTTTAAAACCCCKKKK graph.
+         Depending on the type of the previous graph, the SSSSTTTTAAAACCCCKKKK
+         will be either a LLLLIIIINNNNEEEE???? or an AAAARRRREEEEAAAA.  This obviously
+         implies that the first SSSSTTTTAAAACCCCKKKK must be preceded by an AAAARRRREEEEAAAA
+         or LLLLIIIINNNNEEEE???? -- you need something to stack something onto
+         in the first place ;)
+
+         Note, that when you STACK onto *UNKNOWN* data, rrdtool
+         will not draw any graphics ... *UNKNOWN* is not zero ...
+         if you want it to zero then you might want to use a CDEF
+         argument with IF and UN functions to turn *UNKNOWN* into
+         zero ...
 
 NNNNOOOOTTTTEEEESSSS oooonnnn lllleeeeggggeeeennnndddd aaaarrrrgggguuuummmmeeeennnnttttssss
      EEEEssssccccaaaappppiiiinnnngggg tttthhhheeee ccccoooolllloooonnnn
@@ -512,26 +585,26 @@
 
      The text printed below the actual graph can be formated by
      appending special escaped characters at the end of a text.
-     When ever such a character occurs, all pending text is
-     pushed onto the graph according to the character specified.
 
-     Valid markers are: \\\\jjjj for justified, \\\\llll for left aligned, \\\\rrrr
-     for right aligned and \\\\cccc for centered. In the next section
-     there is an example showing how to use centered formating.
 
 
+2001-02-20             Last change: 1.0.33                      9
 
 
-12/Feb/2000            Last change: 1.0.13                      8
 
 
 
 
+rrdtool                                               RRDGRAPH(1)
 
 
-rrdtool                                               RRDGRAPH(1)
 
+     When ever such a character occurs, all pending text is
+     pushed onto the graph according to the character specified.
 
+     Valid markers are: \\\\jjjj for justified, \\\\llll for left aligned, \\\\rrrr
+     for right aligned and \\\\cccc for centered. In the next section
+     there is an example showing how to use centered formating.
 
      Normally there are two space characters inserted between
      every two items printed into the graph. The space following
@@ -542,9 +615,8 @@
 
       GPRINT:a:MAX:%lf%s\g
 
-     A special case is COMMENT:B<\s> this inserts some additional vertical space
-     before placing the next row of legends.
-
+     A special case is COMMENT:\\\\ssss this inserts some additional
+     vertical space before placing the next row of legends.
 
 NNNNOOOOTTTTEEEE oooonnnn RRRReeeettttuuuurrrrnnnn VVVVaaaalllluuuueeeessss
      Whenever rrd_graph gets called, it prints a line telling the
@@ -554,14 +626,14 @@
 EEEEXXXXAAAAMMMMPPPPLLLLEEEE 1111
        rrdtool graph demo.gif --title="Demo Graph" \
                DEF:cel=demo.rrd:exhaust:AVERAGE \
-               "CDEF:far=cel,32,-,0.55555,*" \
+               "CDEF:far=cel,1.8,*,32,+"" \
                LINE2:cel#00a000:"D. Celsius" \
                LINE2:far#ff0000:"D. Fahrenheit\c"
 
 
 EEEEXXXXAAAAMMMMPPPPLLLLEEEE 2222
      This example demonstrates the syntax for using IF and UN to
-     set *_U_N_K_N_O_W_N* values to 0.  This technique is useful if you
+     set _*_U_N_K_N_O_W_N_* values to 0.  This technique is useful if you
      are aggregating interface data where the start dates of the
      data sets doesn't match.
 
@@ -575,20 +647,14 @@
               AREA:agginput#00cc00:Input Aggregate \
               LINE1:agginput#0000FF:Output Aggregate
 
-     Assuming that idat1 has a data value of I<*UNKNOWN*>, the CDEF expression
+     Assuming that idat1 has a data value of _*_U_N_K_N_O_W_N_*, the CDEF
+     expression
 
-      idat1,UN,0,idat1,IF
 
-     leaves us with a stack with contents of 1,0,NaN and the IF
-     function will pop off the 3 values and replace them with 0.
-     If idat1 had a real value like 7942099, then the stack would
-     have 0,0,7942099 and the real value would be the
-     replacement.
 
 
 
-
-12/Feb/2000            Last change: 1.0.13                      9
+2001-02-20             Last change: 1.0.33                     10
 
 
 
@@ -599,6 +665,14 @@
 
 
 
+      idat1,UN,0,idat1,IF
+
+     leaves us with a stack with contents of 1,0,NaN and the IF
+     function will pop off the 3 values and replace them with 0.
+     If idat1 had a real value like 7942099, then the stack would
+     have 0,0,7942099 and the real value would be the
+     replacement.
+
 EEEEXXXXAAAAMMMMPPPPLLLLEEEE 3333
      This example shows two ways to use the INF function. First
      it makes the background change color during half of the
@@ -618,7 +692,7 @@
               STACK:val2#00C000:Value2 \
               STACK:val3#FFFF00:Value3 \
               STACK:val4#FFC000:Value4 \
-              AREA:whipeout#FF0000:Unknown
+              AREA:wipeout#FF0000:Unknown
 
      The first CDEF uses val4 as a dummy value. It's value is
      removed immediately from the stack. Then a decision is made
@@ -628,7 +702,7 @@
 
      The second CDEF looks if any of val1,val2,val3,val4 is
      unknown. It does so by checking the outcome of
-     _s_u_m(val1,val2,val3,val4). Again, INF is returned when the
+     sum(val1,val2,val3,val4). Again, INF is returned when the
      condition is true, UNKN is used to not plot the data.
 
      The different items are plotted in a particular order. First
@@ -637,24 +711,16 @@
      but not least, overlay everything with eye-hurting red to
      signal any unknown data.
 
-     Note that this example assumesthat your data is in the
+     Note that this example assumes that your data is in the
      positive half of the y-axis otherwhise you would would have
      to add NEGINF in order to extend the coverage of the rea to
      whole graph.
 
-AAAAUUUUTTTTHHHHOOOORRRR
-     Tobias Oetiker <oetiker at ee.ethz.ch>
-
-RRRREEEEFFFFEEEERRRREEEENNNNCCCCEEEESSSS
-     [1] http://www.dotpoint.com/xnumber/rpn_or_adl.htm
-
 
 
 
 
-
-
-12/Feb/2000            Last change: 1.0.13                     10
+2001-02-20             Last change: 1.0.33                     11
 
 
 
@@ -665,7 +731,11 @@
 
 
 
+AAAAUUUUTTTTHHHHOOOORRRR
+     Tobias Oetiker <oetiker at ee.ethz.ch>
 
+RRRREEEEFFFFEEEERRRREEEENNNNCCCCEEEESSSS
+     [1] http://www.dotpoint.com/xnumber/rpn_or_adl.htm
 
 
 
@@ -716,11 +786,7 @@
 
 
 
-
-12/Feb/2000            Last change: 1.0.13                     11
-
-
-
+2001-02-20             Last change: 1.0.33                     12
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/RRDs.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/RRDs.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/RRDs.txt	Sat Jul 13 21:26:25 2002
@@ -12,6 +12,7 @@
        use RRDs;
        RRDs::error
        RRDs::last ...
+       RRDs::info ...
        RRDs::create ...
        RRDs::update ...
        RRDs::graph ...
@@ -27,24 +28,27 @@
      SYNOPSIS are explained in the regular rrdtool documentation.
      The commandline call
 
-      rrdtool update mydemo.rrd N:12:13
+      rrdtool update mydemo.rrd --template in:out N:12:13
 
      gets turned into
 
-      RRDs::update ("mydemo.rrd", "N:12:13");
+      RRDs::update ("mydemo.rrd", "--template", "in:out", "N:12:13");
 
+     Note that
+
+      --template=in:out
+
+     is also valid.
 
      EEEErrrrrrrroooorrrr HHHHaaaannnnddddlllliiiinnnngggg
 
      The RRD functions will not abort your program even when they
-     can not make sense out of the arguments you fed them. There
-     are two ways to determine if an error has occured.
+     can not make sense out of the arguments you fed them.
 
-     First the every function will return the value -1 if an
-     error occured.  Second, the function RRDs::error can be
-     called to get the error message from the last function call.
-     If RRDs::error does not return an error then the previous
-     function has completed its task succesfully.
+     The function RRDs::error should be called to get the error
+     status after each function call. If RRDs::error does not
+     return anything then the previous function has completed its
+     task successfully.
 
       use RRDs;
       RRDs::update ("mydemo.rrd","N:12:13");
@@ -52,15 +56,11 @@
       die "ERROR while updating mydemo.rrd: $ERR\n" if $ERR;
 
 
-     RRRReeeettttuuuurrrrnnnn VVVVaaaalllluuuueeeessss
-
-     The functions RRDs::last, RRDs::graph and RRDs::fetch return
-     their findings.
 
 
 
 
-13/Feb/2000            Last change: 1.0.13                      1
+2001-02-22             Last change: 1.0.33                      1
 
 
 
@@ -71,20 +71,34 @@
 
 
 
-     RRDs::last returns a single INTEGER representing the last
+     RRRReeeettttuuuurrrrnnnn VVVVaaaalllluuuueeeessss
+
+     The functions RRDs::last, RRDs::graph, RRDs::info and
+     RRDs::fetch return their findings.
+
+     RRRRRRRRDDDDssss::::::::llllaaaasssstttt returns a single INTEGER representing the last
      update time.
 
       $lastupdate = RRDs::last ...
 
-     RRDs::graph returns an pointer to an ARRAY containing the
-     x-size and y-size of the created gif and results of the
-     PRINT arguments.
+     RRRRRRRRDDDDssss::::::::ggggrrrraaaapppphhhh returns an pointer to an ARRAY containing the x-
+     size and y-size of the created gif and results of the PRINT
+     arguments.
 
       ($averages,$xsize,$ysize) = RRDs::graph ...
       print "Gifsize: ${xsize}x${ysize}\n";
       print "Averages: ", (join ", ", @$averages);
 
-     RRDs::fetch is the most complex of the pack regarding return
+     RRRRRRRRDDDDssss::::::::iiiinnnnffffoooo returns a pointer to a hash. The keys of the hash
+     represent the property names of the rrd and the values of
+     the hash are the values of the properties.
+
+      $hash = RRDs::info "example.rrd";
+      foreach my $key (keys %$hash){
+        print "$key = $$hash{$key}\n";
+      }
+
+     RRRRRRRRDDDDssss::::::::ffffeeeettttcccchhhh is the most complex of the pack regarding return
      values. There are 4 values. Two normal integers, a pointer
      to an array and a pointer to a array of pointers.
 
@@ -107,26 +121,12 @@
      extension.
 
 AAAAUUUUTTTTHHHHOOOORRRR
-     Tobias Oetiker <oeitker at ee.ethy.ch>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+     Tobias Oetiker <oetiker at ee.ethz.ch>
 
 
 
 
-13/Feb/2000            Last change: 1.0.13                      2
+2001-02-22             Last change: 1.0.33                      2
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdcgi.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdcgi.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdcgi.txt	Sat Jul 13 21:26:25 2002
@@ -10,8 +10,8 @@
      templates
 
 SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
-     #!/path/to/rrrrrrrrddddccccggggiiii [--------ggggooooooooddddffffoooorrrr|----gggg _s_e_c_o_n_d_s] [--------ffffiiiilllltttteeeerrrr] [--------
-     rrrreeeeffffrrrreeeesssshhhh|----rrrr]
+     #!/path/to/rrrrrrrrddddccccggggiiii [--------ggggooooooooddddffffoooorrrr|----gggg _s_e_c_o_n_d_s] [--------ffffiiiilllltttteeeerrrr]
+     [--------rrrreeeeffffrrrreeeesssshhhh|----rrrr]
 
 DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
      rrrrrrrrddddccccggggiiii is a sort of very limited script interpreter. Its
@@ -32,7 +32,7 @@
              Assume that rrdcgi is being run as a filter and not
              as a cgi.
 
-     --------rrrreeeeffffrrrreeeesssshhhh|-rrrr
+     --------rrrreeeeffffrrrreeeesssshhhh|----rrrr
              If the --------ggggooooooooddddffffoooorrrr flag is specified, then --------rrrreeeeffffrrrreeeesssshhhh
              will cause rrdcgi to output a Refresh header with
              the value of the --------ggggooooooooddddffffoooorrrr value.
@@ -60,7 +60,7 @@
 
 
 
-6/Feb/2000             Last change: 1.0.13                      1
+2001-02-20             Last change: 1.0.33                      1
 
 
 
@@ -71,6 +71,15 @@
 
 
 
+     RRD::GETENV _v_a_r_i_a_b_l_e
+             Get the value of an environment variable.
+
+              <RRD::GETENV REMOTE_USER>
+
+             might give you the name of the remote user given you
+             are using some sort of access control on the
+             directory
+
      PPPPaaaassssssss 2222
 
      RRD::GOODFOR _s_e_c_o_n_d_s
@@ -93,12 +102,12 @@
              Time. Note that the values permitted to TZ depend on
              your OS.
 
-     RRD::TIME::LAST _r_r_d-_f_i_l_e _s_t_r_f_t_i_m_e-_f_o_r_m_a_t
+     RRD::TIME::LAST _r_r_d_-_f_i_l_e _s_t_r_f_t_i_m_e_-_f_o_r_m_a_t
              This gets replaced by the last modification time of
              the selected RRD. The time is _s_t_r_f_t_i_m_e-formated with
              the string specified in the second argument.
 
-     RRD::TIME::NOW _s_t_r_f_t_i_m_e-_f_o_r_m_a_t
+     RRD::TIME::NOW _s_t_r_f_t_i_m_e_-_f_o_r_m_a_t
              This gets replaced by the current time of day. The
              time is _s_t_r_f_t_i_m_e-formated with the string specified
              in the argument.
@@ -114,28 +123,29 @@
              arguments to the RRRRRRRRDDDD::::::::GGGGRRRRAAAAPPPPHHHH tag work as described in
              the rrrrrrrrddddggggrrrraaaapppphhhh manual page.
 
-             Use the --------llllaaaazzzzyyyy option in your RRD::GRAPH tags, to
-             reduce the load on your server. This option makes
-             sure that graphs are only regenerated when the old
-             ones are out of date.
 
-             If you do not specify your own --------iiiimmmmggggiiiinnnnffffoooo format, the
-             following will be used:
 
-              <IMG SRC="%s" WIDTH="%lu" HEIGHT="%lu">
+
+2001-02-20             Last change: 1.0.33                      2
 
 
 
-6/Feb/2000             Last change: 1.0.13                      2
 
 
 
+rrdtool                                                 RRDCGI(1)
 
 
 
-rrdtool                                                 RRDCGI(1)
+             Use the --------llllaaaazzzzyyyy option in your RRD::GRAPH tags, to
+             reduce the load on your server. This option makes
+             sure that graphs are only regenerated when the old
+             ones are out of date.
 
+             If you do not specify your own --------iiiimmmmggggiiiinnnnffffoooo format, the
+             following will be used:
 
+              <IMG SRC="%s" WIDTH="%lu" HEIGHT="%lu">
 
              Note that %s stands for the filename part of the
              graph generated, all directories given in the GIF
@@ -172,6 +182,27 @@
      it from a form which sets RRD_NAME. RRD_NAME is then used to
      select which RRD you want to use a source for your graph.
 
+
+
+
+
+
+
+
+
+
+
+2001-02-20             Last change: 1.0.33                      3
+
+
+
+
+
+
+rrdtool                                                 RRDCGI(1)
+
+
+
       #!/usr/local/bin/rrdcgi
       <HTML>
       <HEAD><TITLE>RRDCGI Demo</TITLE></HEAD>
@@ -188,21 +219,6 @@
                DEF:cel=<RRD::CV::PATH RRD_NAME>.rrd:exhaust:AVERAGE
                LINE2:cel#00a000:"D. Celsius">
 
-
-
-
-
-6/Feb/2000             Last change: 1.0.13                      3
-
-
-
-
-
-
-rrdtool                                                 RRDCGI(1)
-
-
-
       </P>
       </BODY>
       </HTML>
@@ -242,89 +258,7 @@
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-6/Feb/2000             Last change: 1.0.13                      4
-
-
-
-
-
-
-rrdtool                                                 RRDCGI(1)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-6/Feb/2000             Last change: 1.0.13                      5
-
-
-
+2001-02-20             Last change: 1.0.33                      4
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdtool.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdtool.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdtool.html	Sat Jul 13 21:26:25 2002
@@ -1,222 +1,218 @@
 <HTML>
 <HEAD>
 <TITLE>rrdtool</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
 	<UL>
 
-		<LI><A HREF="#OVERVIEW">OVERVIEW</A>
-		<LI><A HREF="#FUNCTIONS">FUNCTIONS</A>
-		<LI><A HREF="#HOW_DOES_RRDTOOL_WORK_">HOW DOES RRDTOOL WORK?</A>
-		<LI><A HREF="#REMOTE_CONTROL">REMOTE CONTROL</A>
+		<LI><A HREF="#overview">OVERVIEW</A></LI>
+		<LI><A HREF="#functions">FUNCTIONS</A></LI>
+		<LI><A HREF="#how does rrdtool work">HOW DOES RRDTOOL WORK?</A></LI>
+		<LI><A HREF="#remote control">REMOTE CONTROL</A></LI>
 	</UL>
 
-	<LI><A HREF="#SEE_ALSO">SEE ALSO</A>
-	<LI><A HREF="#BUGS">BUGS</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#see also">SEE ALSO</A></LI>
+	<LI><A HREF="#bugs">BUGS</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-rrdtool - round robin database tool
-
-<P>
-<HR>
-<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
-<P>
-<STRONG>rrdtool</STRONG>  <STRONG>-</STRONG> | <EM>function</EM>
-
-
-
-<P>
-<HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-<HR>
-<H2><A NAME="OVERVIEW">OVERVIEW</A></H2>
-<P>
-It is pretty easy to gather status information from all sorts of things,
-ranging from the temperature in your office to the number of octets which
-have passed through the FDDI interface of your router. But it is not so
-trivial to store this data in a efficient and systematic manner. This is
-where <STRONG>rrdtool</STRONG> kicks in. It lets you
-<EM>log and analyze</EM> the data you gather from all kinds of data-sources (<STRONG>DS</STRONG>). The data analysis part of rrdtool is based on the ability to quickly
-generate graphical representations of the data values collected over a
-definable time period.
-
-<P>
-In this man page you will find general information on the design and
+<H1><A NAME="name">NAME</A></H1>
+<P>rrdtool - round robin database tool</P>
+<div align="right"><a href="rrdtool.pdf">PDF</a> version.</div><P>
+<HR>
+<H1><A NAME="synopsis">SYNOPSIS</A></H1>
+<P><STRONG>rrdtool</STRONG> <STRONG>-</STRONG> | <EM>function</EM></P>
+<P>
+<HR>
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>
+<H2><A NAME="overview">OVERVIEW</A></H2>
+<P>It is pretty easy to gather status information from all sorts of
+things, ranging from the temperature in your office to the number of
+octets which have passed through the FDDI interface of your
+router. But it is not so trivial to store this data in a efficient and
+systematic manner. This is where <STRONG>rrdtool</STRONG> kicks in. It lets you
+<EM>log and analyze</EM> the data you gather from all kinds of data-sources
+(<STRONG>DS</STRONG>). The data analysis part of rrdtool is based on the ability to
+quickly generate graphical representations of the data values
+collected over a definable time period.</P>
+<P>In this man page you will find general information on the design and
 functionality of the Round Robin Database Tool (rrdtool). For a more
 detailed description of how to use the individual functions of the
-<STRONG>rrdtool</STRONG> check the corresponding man page.
-
-<P>
-For an introduction to the usage of rrdtool make sure you check <A HREF="././rrdtutorial.html#">the rrdtutorial manpage</A>.
-
+<STRONG>rrdtool</STRONG> check the corresponding man page.</P>
+<P>For an introduction to the usage of rrdtool make sure you check <A HREF="././rrdtutorial.html">the rrdtutorial manpage</A>.</P>
 <P>
-<HR>
-<H2><A NAME="FUNCTIONS">FUNCTIONS</A></H2>
-<P>
-While the man pages talk of command line switches you have to set in order
-to make <STRONG>rrdtool</STRONG> work it is important to note that the <STRONG>rrdtool</STRONG> can be 'remote controlled' through a set of pipes. This saves a
-considerable amount of startup time when you plan to make <STRONG>rrdtool</STRONG> do a lot of things quickly. Check the section on <A HREF="#Remote_Control">Remote Control</A> further down.
-
+<H2><A NAME="functions">FUNCTIONS</A></H2>
+<P>While the man pages talk of command line switches you have to set in
+order to make <STRONG>rrdtool</STRONG> work it is important to note that the
+<STRONG>rrdtool</STRONG> can be 'remote controlled' through a set of pipes. This
+saves a considerable amount of startup time when you plan to make
+<STRONG>rrdtool</STRONG> do a lot of things quickly. Check the section on <A HREF="#remote control">Remote Control</A> further down. There is also a number of language bindings
+for rrdtool which allow you to use it directly from perl, python, tcl,
+php, ...</P>
 <DL>
-<DT><STRONG><A NAME="item_create">create</A></STRONG><DD>
-<P>
-Set up a new Round Robin Database (RRD). Check <A HREF="././rrdcreate.html#">the rrdcreate manpage</A>.
-
-<DT><STRONG><A NAME="item_update">update</A></STRONG><DD>
-<P>
-Store new data values into an RRD. Check <A HREF="././rrdupdate.html#">the rrdupdate manpage</A>.
-
-<DT><STRONG><A NAME="item_graph">graph</A></STRONG><DD>
-<P>
+<DT><STRONG><A NAME="item_create"><STRONG>create</STRONG></A></STRONG><BR>
+<DD>
+Set up a new Round Robin Database (RRD). Check <A HREF="././rrdcreate.html">the rrdcreate manpage</A>.
+<P></P>
+<DT><STRONG><A NAME="item_update"><STRONG>update</STRONG></A></STRONG><BR>
+<DD>
+Store new data values into an RRD. Check <A HREF="././rrdupdate.html">the rrdupdate manpage</A>.
+<P></P>
+<DT><STRONG><A NAME="item_graph"><STRONG>graph</STRONG></A></STRONG><BR>
+<DD>
 Create a graph from data stored in one or several RRD. Apart from
-generating graphs, data can also be extracted to stdout. Check <A HREF="././rrdgraph.html#">the rrdgraph manpage</A>.
-
-<DT><STRONG><A NAME="item_dump">dump</A></STRONG><DD>
-<P>
-Dump the contents of an RRD in plain ASCII. In connection with restore you
-can use it to transport an rrd from one architecture to another. Check <A HREF="././rrddump.html#">the rrddump manpage</A>.
-
-<DT><STRONG><A NAME="item_restore">restore</A></STRONG><DD>
-<P>
-Restore an RRD in XML format to a binary rrd ... Check <A HREF="././rrdrestore.html#">the rrdrestore manpage</A>
-
-
-
-<DT><STRONG><A NAME="item_fetch">fetch</A></STRONG><DD>
-<P>
-Get data for a certain time period from a RRD. The graph function uses
-fetch to retrieve its data from an rrd. Check <A HREF="././rrdfetch.html#">the rrdfetch manpage</A>.
-
-<DT><STRONG><A NAME="item_tune">tune</A></STRONG><DD>
-<P>
-Alter setup of an RRD. Check <A HREF="././rrdtune.html#">the rrdtune manpage</A>.
-
-<DT><STRONG><A NAME="item_last">last</A></STRONG><DD>
-<P>
-Find last update time of an RRD. Check <A HREF="././rrdlast.html#">the rrdlast manpage</A>.
-
-<DT><STRONG><A NAME="item_rrdresize">rrdresize</A></STRONG><DD>
-<P>
-Change the size of individual RRAs ... Dangerous! Check <A HREF="././rrdresize.html#">the rrdresize manpage</A>.
-
-<DT><STRONG><A NAME="item_rrdcgi">rrdcgi</A></STRONG><DD>
-<P>
+generating graphs, data can also be extracted to stdout. Check <A HREF="././rrdgraph.html">the rrdgraph manpage</A>.
+<P></P>
+<DT><STRONG><A NAME="item_dump"><STRONG>dump</STRONG></A></STRONG><BR>
+<DD>
+Dump the contents of an RRD in plain ASCII. In connection with 
+restore you can use it to transport an rrd from one architecture to another.
+Check <A HREF="././rrddump.html">the rrddump manpage</A>.
+<P></P>
+<DT><STRONG><A NAME="item_restore"><STRONG>restore</STRONG></A></STRONG><BR>
+<DD>
+Restore an RRD in XML format to a binary rrd ... Check <A HREF="././rrdrestore.html">the rrdrestore manpage</A>
+<P></P>
+<DT><STRONG><A NAME="item_fetch"><STRONG>fetch</STRONG></A></STRONG><BR>
+<DD>
+Get data for a certain time period from a RRD. The graph function
+uses fetch to retrieve its data from an rrd. Check <A HREF="././rrdfetch.html">the rrdfetch manpage</A>.
+<P></P>
+<DT><STRONG><A NAME="item_tune"><STRONG>tune</STRONG></A></STRONG><BR>
+<DD>
+Alter setup of an RRD. Check <A HREF="././rrdtune.html">the rrdtune manpage</A>.
+<P></P>
+<DT><STRONG><A NAME="item_last"><STRONG>last</STRONG></A></STRONG><BR>
+<DD>
+Find last update time of an RRD. Check <A HREF="././rrdlast.html">the rrdlast manpage</A>.
+<P></P>
+<DT><STRONG><A NAME="item_rrdresize"><STRONG>rrdresize</STRONG></A></STRONG><BR>
+<DD>
+Change the size of individual RRAs ... Dangerous! Check <A HREF="././rrdresize.html">the rrdresize manpage</A>.
+<P></P>
+<DT><STRONG><A NAME="item_rrdcgi"><STRONG>rrdcgi</STRONG></A></STRONG><BR>
+<DD>
 This is a standalone tool for producing rrd graphs on the fly. Check
-<A HREF="././rrdcgi.html#">the rrdcgi manpage</A>.
-
-</DL>
+<A HREF="././rrdcgi.html">the rrdcgi manpage</A>.
+<P></P></DL>
 <P>
-<HR>
-<H2><A NAME="HOW_DOES_RRDTOOL_WORK_">HOW DOES RRDTOOL WORK?</A></H2>
+<H2><A NAME="how does rrdtool work">HOW DOES RRDTOOL WORK?</A></H2>
 <DL>
-<DT><STRONG><A NAME="item_Data">Data acquisition</A></STRONG><DD>
-<P>
-When monitoring the state of a system, it is convenient to have the data
-available at a constant interval. Unfortunately you may not always be able
-to fetch data at exactly the time you want to. Therefore <STRONG>rrdtool</STRONG> lets you update the logfile at any time you want. It will automatically
-interpolate the value of the data-source (<STRONG>DS</STRONG>) at the latest official time-slot and write this value to the log. The
-value you have supplied is stored as well and is also taken into account
-when interpolating the next log entry.
-
-<DT><STRONG><A NAME="item_Consolidation">Consolidation</A></STRONG><DD>
-<P>
-You may log data at a 1 minute interval, but you are also be interested to
-know the development of the data over the last year. You could do this by
-simply storing the data in 1 minute interval, for one year. While this
-would take considerable disk space it would also take a lot of time to
-analyze the data when you wanted to create a graph covering the whole year. <STRONG>rrdtool</STRONG> offers a solution to this of this problem through its data consolidation
-feature. When setting up an Round Robin Database (<STRONG>RRD</STRONG>), you can define at which interval this consolidation should occur, and
-what consolidation function (<STRONG>CF</STRONG>) (average, minimum, maximum, total, last) should be used to build the
-consolidated values (see rrdcreate). You can define any number of different
-consolidation setups within one <STRONG>RRD</STRONG>. They will all be maintained on the fly when new data is loaded into the <STRONG>RRD</STRONG>.
-
-<DT><STRONG><A NAME="item_Round">Round Robin Archives</A></STRONG><DD>
-<P>
-Data values of the same consolidation setup are stored into Round Robin
-Archives (<STRONG>RRA</STRONG>). This is a very efficient manner to store data for a certain amount of
-time, while using a known amount of storage space. 
-
-<P>
-It works like this: If you want to store 1000 values in 5 minute interval, <STRONG>rrdtool</STRONG> will allocate space for 1000 data values and a header area. In the header
-it will store a pointer telling which one of the values in the storage area
-was last written to. New values are written to the Round Robin Archive in a
-... you guess it ... round robin manner. This automatically limits the
-history to the last 1000 values. Because you can define several <STRONG>RRA</STRONG>s within a single <STRONG>RRD</STRONG>, you can setup another one, storing 750 data values at a 2 hour interval
+<DT><STRONG><A NAME="item_Data_acquisition">Data acquisition</A></STRONG><BR>
+<DD>
+When monitoring the state of a system, it is convenient to have the
+data available at a constant interval. Unfortunately you may not
+always be able to fetch data at exactly the time you want
+to. Therefore <STRONG>rrdtool</STRONG> lets you update the logfile at any time you
+want. It will automatically interpolate the value of the data-source
+(<STRONG>DS</STRONG>) at the latest official time-slot and write this value to the
+log. The value you have supplied is stored as well and is also taken
+into account when interpolating the next log entry.
+<P></P>
+<DT><STRONG><A NAME="item_Consolidation">Consolidation</A></STRONG><BR>
+<DD>
+You may log data at a 1 minute interval, but you are also be
+interested to know the development of the data over the last year. You
+could do this by simply storing the data in 1 minute interval, for one
+year. While this would take considerable disk space it would also take
+a lot of time to analyze the data when you wanted to create a graph
+covering the whole year. <STRONG>rrdtool</STRONG> offers a solution to this of this
+problem through its data consolidation feature. When setting up
+an Round Robin Database (<STRONG>RRD</STRONG>), you can define at which interval
+this consolidation should occur, and what consolidation function
+(<STRONG>CF</STRONG>) (average, minimum, maximum, total, last) should be used to
+build the consolidated values (see rrdcreate). You can define any
+number of different consolidation setups within one <STRONG>RRD</STRONG>. They will
+all be maintained on the fly when new data is loaded into the <STRONG>RRD</STRONG>.
+<P></P>
+<DT><STRONG><A NAME="item_Round_Robin_Archives">Round Robin Archives</A></STRONG><BR>
+<DD>
+Data values of the same consolidation setup are stored into Round
+Robin Archives (<STRONG>RRA</STRONG>). This is a very efficient manner to store data
+for a certain amount of time, while using a known amount of storage
+space.
+<P>It works like this: If you want to store 1000 values in 5 minute
+interval, <STRONG>rrdtool</STRONG> will allocate space for 1000 data values and a
+header area. In the header it will store a pointer telling
+which one of the values in the storage area was last written to. New
+values are written to the Round Robin Archive in a ...  you guess it
+... round robin manner. This automatically limits the history to the last
+1000 values. Because you can define several <STRONG>RRA</STRONG>s within a single <STRONG>RRD</STRONG>,
+you can setup another one, storing 750 data values at a 2 hour interval
 and thus keeping a log for the last two months although at a lower
-resolution.
-
-<P>
-The use of <STRONG>RRA</STRONG>s guarantees that the <STRONG>RRD</STRONG> does not grow over time and that old data is automatically eliminated. By
-using the consolidation feature, you can still keep data for a very long
-time, while gradually reducing the resolution of the data along the time
-axis. Using different consolidation functions (<STRONG>CF</STRONG>) allows you to store exactly the type of information that actually
-interests you. (Maximum one minute traffic on the LAN, minimum temperature
-of the wine cellar, total minutes down time ...)
-
-<DT><STRONG><A NAME="item_Unknown">Unknown Data</A></STRONG><DD>
-<P>
-As mentioned earlier, the <STRONG>RRD</STRONG> stores data at a constant interval. Now it may happen that no new data is
-available when a value has to be written to the <STRONG>RRD</STRONG>. Data acquisition may not be possible for one reason or an other. The <STRONG>rrdtool</STRONG> handles these situations by storing an <EM>*UNKNOWN*</EM> value into the database. The value '<EM>*UNKNOWN*</EM>' is supported through all the functions of the database. When
-consolidating the amount of <EM>*UNKNOWN*</EM> data is accumulated and when a new consolidated value is ready to be
-written to its Round Robin Archive (<STRONG>RRA</STRONG>) a validity check is performed to make sure that the percentage of unknown
-data in the new value is below a configurable level. If so, an <EM>*UNKNOWN*</EM> value will be written to the <STRONG>RRA</STRONG>.
-
-<DT><STRONG><A NAME="item_Graphing">Graphing</A></STRONG><DD>
-<P>
-The <STRONG>rrdtool</STRONG> also allows one to generate reports in numerical and graphical form based
-on the data stored in one or several
-<STRONG>RRD</STRONG>s. The graphing feature is fully configurable. Size, color and contents of
-the graph can be defined freely. Check <A HREF="././rrdgraph.html#">the rrdgraph manpage</A>
+resolution.</P>
+<P>The use of <STRONG>RRA</STRONG>s guarantees that the <STRONG>RRD</STRONG> does not grow over
+time and that old data is automatically eliminated. By using the
+consolidation feature, you can still keep data for a very long time,
+while gradually reducing the resolution of the data along the time
+axis. Using different consolidation functions (<STRONG>CF</STRONG>) allows you to
+store exactly the type of information that actually interests
+you. (Maximum one minute traffic on the LAN, minimum temperature of
+the wine cellar, total minutes down time ...)</P>
+<P></P>
+<DT><STRONG><A NAME="item_Unknown_Data">Unknown Data</A></STRONG><BR>
+<DD>
+As mentioned earlier, the <STRONG>RRD</STRONG> stores data at a constant
+interval. Now it may happen that no new data is available when a
+value has to be written to the <STRONG>RRD</STRONG>. Data acquisition may not be
+possible for one reason or an other. The <STRONG>rrdtool</STRONG> handles these
+situations by storing an <EM>*UNKNOWN*</EM> value into the database. The
+value '<EM>*UNKNOWN*</EM>' is supported through all the functions of the
+database. When consolidating the amount of <EM>*UNKNOWN*</EM> data is
+accumulated and when a new consolidated value is ready to be written
+to its Round Robin Archive (<STRONG>RRA</STRONG>) a validity check is performed to
+make sure that the percentage of unknown data in the new value is
+below a configurable level. If so, an <EM>*UNKNOWN*</EM> value will be
+written to the <STRONG>RRA</STRONG>.
+<P></P>
+<DT><STRONG><A NAME="item_Graphing">Graphing</A></STRONG><BR>
+<DD>
+The <STRONG>rrdtool</STRONG> also allows one to generate reports in numerical and
+graphical form based on the data stored in one or several
+<STRONG>RRD</STRONG>s. The graphing feature is fully configurable. Size, color and
+contents of the graph can be defined freely. Check <A HREF="././rrdgraph.html">the rrdgraph manpage</A>
 for more information on this.
-
-</DL>
-<P>
-<HR>
-<H2><A NAME="REMOTE_CONTROL">REMOTE CONTROL</A></H2>
+<P></P></DL>
 <P>
-When you start <STRONG>rrdtool</STRONG> with the command line option '<STRONG>-</STRONG>', it waits for input via standard in. With this feature you can improve
-performance by attaching <STRONG>rrdtool</STRONG> to another process (mrtg is one example) through a set of pipes. Over the
-pipes <STRONG>rrdtool</STRONG> accepts the same arguments as on the command line. When a command is
-completed, rrdtool will print the string '<CODE>OK</CODE>', followed by timing information of the form <STRONG>u:</STRONG><EM>usertime</EM>  <STRONG>s:</STRONG><EM>systemtime</EM> both values are running totals of seconds since rrdtool was started. If an
-error occurs, a line of the form '<CODE>ERROR:</CODE>  <EM>Description of error</EM>' will be printed. <STRONG>rrdtool</STRONG>
-will not abort if possible, but follow the ERROR line with an OK line.
-
+<H2><A NAME="remote control">REMOTE CONTROL</A></H2>
+<P>When you start <STRONG>rrdtool</STRONG> with the command line option '<STRONG>-</STRONG>', it waits
+for input via standard in. With this feature you can improve
+performance by attaching <STRONG>rrdtool</STRONG> to another process (mrtg is one
+example) through a set of pipes. Over the pipes <STRONG>rrdtool</STRONG> accepts the
+same arguments as on the command line. When a command is completed, 
+rrdtool will print the string  '<CODE>OK</CODE>', followed by timing information of
+the form <STRONG>u:</STRONG><EM>usertime</EM> <STRONG>s:</STRONG><EM>systemtime</EM> both values are running
+totals of seconds since rrdtool was started. If an error occurs, a line 
+of the form '<CODE>ERROR:</CODE> <EM>Description of error</EM>' will be printed. <STRONG>rrdtool</STRONG>
+will not abort if possible, but follow the ERROR line with an OK line.</P>
 <P>
 <HR>
-<H1><A NAME="SEE_ALSO">SEE ALSO</A></H1>
-<P>
-rrdcreate, rrdupdate, rrdgraph, rrddump, rrdfetch, rrdtune, rrdlast
-
+<H1><A NAME="see also">SEE ALSO</A></H1>
+<P>rrdcreate, rrdupdate, rrdgraph, rrddump, rrdfetch, rrdtune, rrdlast</P>
 <P>
 <HR>
-<H1><A NAME="BUGS">BUGS</A></H1>
-<P>
-Bugs ? Features !
-
+<H1><A NAME="bugs">BUGS</A></H1>
+<P>Bugs ? Features !</P>
 <P>
 <HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-Tobias Oetiker &lt;<A
-HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;</P>
 
 </BODY>
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/cdeftutorial.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/cdeftutorial.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/cdeftutorial.html	Sat Jul 13 21:26:26 2002
@@ -1,332 +1,240 @@
 <HTML>
 <HEAD>
 <TITLE>cdeftutorial</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
 	<UL>
 
-		<LI><A HREF="#Why_this_tutorial_">Why this tutorial ?</A>
-		<LI><A HREF="#More_reading">More reading</A>
+		<LI><A HREF="#why this tutorial ">Why this tutorial ?</A></LI>
+		<LI><A HREF="#more reading">More reading</A></LI>
 	</UL>
 
-	<LI><A HREF="#What_are_CDEFs_">What are CDEFs ?</A>
-	<LI><A HREF="#Syntax">Syntax</A>
-	<LI><A HREF="#RPN_expressions">RPN-expressions</A>
-	<LI><A HREF="#Converting_your_wishes_to_RPN">Converting your wishes to RPN</A>
-	<LI><A HREF="#Some_special_numbers">Some special numbers</A>
+	<LI><A HREF="#what are cdefs ">What are CDEFs ?</A></LI>
+	<LI><A HREF="#syntax">Syntax</A></LI>
+	<LI><A HREF="#rpnexpressions">RPN-expressions</A></LI>
+	<LI><A HREF="#converting your wishes to rpn">Converting your wishes to RPN</A></LI>
+	<LI><A HREF="#some special numbers">Some special numbers</A></LI>
 	<UL>
 
-		<LI><A HREF="#The_unknown_value">The unknown value</A>
-		<LI><A HREF="#Working_with_unknown_data_in_you">Working with unknown data in your database</A>
-		<LI><A HREF="#Infinity">Infinity</A>
-		<LI><A HREF="#Working_with_unknown_data_and_in">Working with unknown data and infinity</A>
+		<LI><A HREF="#the unknown value">The unknown value</A></LI>
+		<LI><A HREF="#working with unknown data in your database">Working with unknown data in your database</A></LI>
+		<LI><A HREF="#infinity">Infinity</A></LI>
+		<LI><A HREF="#working with unknown data and infinity">Working with unknown data and infinity</A></LI>
 	</UL>
 
-	<LI><A HREF="#Some_examples">Some examples</A>
+	<LI><A HREF="#some examples">Some examples</A></LI>
 	<UL>
 
-		<LI><A HREF="#Example_using_a_recently_create">Example: using a recently created RRD</A>
-		<LI><A HREF="#Example_better_handling_of_unkn">Example: better handling of unknown data, by using time</A>
-		<LI><A HREF="#Example_Pretending_weird_data_i">Example: Pretending weird data isn't there</A>
-		<LI><A HREF="#Example_You_suspect_to_have_pro">Example: You suspect to have problems and want to see unknown data.</A>
-		<LI><A HREF="#Same_example_useful_with_STACKed">Same example useful with STACKed data:</A>
+		<LI><A HREF="#example: using a recently created rrd">Example: using a recently created RRD</A></LI>
+		<LI><A HREF="#example: better handling of unknown data, by using time">Example: better handling of unknown data, by using time</A></LI>
+		<LI><A HREF="#example: pretending weird data isn't there">Example: Pretending weird data isn't there</A></LI>
+		<LI><A HREF="#example: working on a certain time span">Example: working on a certain time span</A></LI>
+		<LI><A HREF="#example: you suspect to have problems and want to see unknown data.">Example: You suspect to have problems and want to see unknown data.</A></LI>
+		<LI><A HREF="#same example useful with stacked data:">Same example useful with STACKed data:</A></LI>
 	</UL>
 
-	<LI><A HREF="#The_examples_from_the_rrd_graph_">The examples from the rrd graph manual page</A>
+	<LI><A HREF="#the examples from the rrd graph manual page">The examples from the rrd graph manual page</A></LI>
 	<UL>
 
-		<LI><A HREF="#Degrees_Celcius_vs_Degrees_Fahr">Degrees Celcius vs. Degrees Fahrenheit</A>
-		<LI><A HREF="#Changing_unknown_into_zero">Changing unknown into zero</A>
-		<LI><A HREF="#Infinity_demo">Infinity demo</A>
+		<LI><A HREF="#degrees celcius vs. degrees fahrenheit">Degrees Celcius vs. Degrees Fahrenheit</A></LI>
+		<LI><A HREF="#changing unknown into zero">Changing unknown into zero</A></LI>
+		<LI><A HREF="#infinity demo">Infinity demo</A></LI>
 	</UL>
 
-	<LI><A HREF="#SEE_ALSO">SEE ALSO</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#see also">SEE ALSO</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-cdeftutorial - Alex van den Bogaerdt's CDEF tutorial
-
-<P>
-<HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-<STRONG>You provide a question and I will try to provide an answer in the next
-release</STRONG>. <STRONG>No feedback equals no changes!</STRONG>
-
-
-
-<P>
-<EM>Additions to this document are also welcome.</EM>
-
-
-
-<P>
-Alex van den Bogaerdt &lt;<A HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt;
-
-
-
-<P>
-<HR>
-<H2><A NAME="Why_this_tutorial_">Why this tutorial ?</A></H2>
-<P>
-One of the powerful parts of RRDtool is its ability to do all sorts of
-calculations on the data retrieved from it's databases. However RRDtool's
-many options and syntax make it difficult for the average user to
-understand. The manuals are good at explaining what these options do;
-however they do not (and should not) explain in detail why they are useful.
-As with my RRDtool tutorial: if you want a simple document in simple
-language you should read this tutorial. If you are happy with the official
-documentation, you may find this document too simple or even boring. If you
-do choose to read this tutorial, I also expect you to have read and fully
-understand my other tutorial. 
-
-<P>
-<HR>
-<H2><A NAME="More_reading">More reading</A></H2>
-<P>
-If you have difficulties with the way I try to explain them please read
-Steve Rader's <A HREF="././rpntutorial.html#">the rpntutorial manpage</A>. It may help you understand how this all works.
-
-<P>
-<HR>
-<H1><A NAME="What_are_CDEFs_">What are CDEFs ?</A></H1>
-<P>
-When retrieving data from an RRD, you are using a ``DEF'' to work with that
-data. Think of it as a variable that changes over time (where time is the
-x-axis). The value of this variable is what is found in the database at
-that particular time and you can't do any modifications on it. This is what
-CDEFs are for: they takes values from DEFs and perform calculations on
-them.
-
-<P>
-<HR>
-<H1><A NAME="Syntax">Syntax</A></H1>
-<P>
-<PRE>   DEF:var_name_1=some.rrd:ds_name:CF
-   CDEF:var_name_2=RPN_expression
-</PRE>
-<P>
-You first define ``var_name_1'' to be data collected from data source
-``ds_name'' found in RRD ``some.rrd'' with consolidation function ``CF''.
-
-<P>
-Assume the ifInOctets SNMP counter is saved in mrtg.rrd as the DS ``in''.
-Then the following DEF defines a variable for the average of that data
-source:
-
-<P>
-<PRE>   DEF:inbytes=mrtg.rrd:in:AVERAGE
-</PRE>
-<P>
-Say you want to display bits per second (instead of bytes per second as
-stored in the database.) You have to define a calculation (hence ``CDEF'')
-on variable ``inbytes'' and use that variable (inbits) instead of the
-original:
-
-<P>
-<PRE>   CDEF:inbits=inbytes,8,*
-</PRE>
-<P>
-It tells to multiply inbytes by eight to get inbits. I'll explain later how
-this works. In the graphing or printing functions, you can now use inbits
-where you would use inbytes otherwise.
-
-<P>
-Note that variable in the CDEF (inbits) must not be the same as the
-variable (inbytes) in the DEF!
-
-<P>
-<HR>
-<H1><A NAME="RPN_expressions">RPN-expressions</A></H1>
-<P>
-RPN is short-hand for Reverse Polish Notation. It works as follows. You put
-the variables or numbers on a stack. You also put operations (things-to-do)
-on the stack and this stack is then processed. The result will be placed on
-the stack. At the end, there should be exactly one number left: the outcome
-of the series of operations. If there is not exactly one number left,
-rrdtool will complain loudly.
-
-<P>
-Above multiplication by eight will look like:
-
+<H1><A NAME="name">NAME</A></H1>
+<P>cdeftutorial - Alex van den Bogaerdt's CDEF tutorial</P>
+<div align="right"><a href="cdeftutorial.pdf">PDF</a> version.</div><P>
+<HR>
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P><STRONG>You provide a question and I will try to provide an answer in the next
+release</STRONG>. <STRONG>No feedback equals no changes!</STRONG></P>
+<P><EM>Additions to this document are also welcome.</EM></P>
+<P>Alex van den Bogaerdt &lt;<A HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt;</P>
+<P>
+<H2><A NAME="why this tutorial ">Why this tutorial ?</A></H2>
+<P>One of the powerful parts of RRDtool is its ability to do all sorts
+of calculations on the data retrieved from it's databases. However
+RRDtool's many options and syntax make it difficult for the average
+user to understand. The manuals are good at explaining what these
+options do; however they do not (and should not) explain in detail
+why they are useful. As with my RRDtool tutorial: if you want a
+simple document in simple language you should read this tutorial.
+If you are happy with the official documentation, you may find this
+document too simple or even boring. If you do choose to read this
+tutorial, I also expect you to have read and fully understand my
+other tutorial.</P>
+<P>
+<H2><A NAME="more reading">More reading</A></H2>
+<P>If you have difficulties with the way I try to explain them please read
+Steve Rader's <A HREF="././rpntutorial.html">the rpntutorial manpage</A>. It may help you understand how this all works.</P>
+<P>
+<HR>
+<H1><A NAME="what are cdefs ">What are CDEFs ?</A></H1>
+<P>When retrieving data from an RRD, you are using a ``DEF'' to work with
+that data. Think of it as a variable that changes over time (where
+time is the x-axis). The value of this variable is what is found in
+the database at that particular time and you can't do any
+modifications on it. This is what CDEFs are for: they takes values
+from DEFs and perform calculations on them.</P>
+<P>
+<HR>
+<H1><A NAME="syntax">Syntax</A></H1>
+<PRE>
+   DEF:var_name_1=some.rrd:ds_name:CF
+   CDEF:var_name_2=RPN_expression</PRE>
+<P>You first define ``var_name_1'' to be data collected from data source
+``ds_name'' found in RRD ``some.rrd'' with consolidation function ``CF''.</P>
+<P>Assume the ifInOctets SNMP counter is saved in mrtg.rrd as the DS ``in''.
+Then the following DEF defines a variable for the average of that
+data source:</P>
+<PRE>
+   DEF:inbytes=mrtg.rrd:in:AVERAGE</PRE>
+<P>Say you want to display bits per second (instead of bytes per second
+as stored in the database.)  You have to define a calculation
+(hence ``CDEF'') on variable ``inbytes'' and use that variable (inbits)
+instead of the original:</P>
+<PRE>
+   CDEF:inbits=inbytes,8,*</PRE>
+<P>It tells to multiply inbytes by eight to get inbits. I'll explain later
+how this works. In the graphing or printing functions, you can now use
+inbits where you would use inbytes otherwise.</P>
+<P>Note that variable in the CDEF (inbits) must not be the same as the
+variable (inbytes) in the DEF!</P>
+<P>
+<HR>
+<H1><A NAME="rpnexpressions">RPN-expressions</A></H1>
+<P>RPN is short-hand for Reverse Polish Notation. It works as follows.
+You put the variables or numbers on a stack. You also put operations
+(things-to-do) on the stack and this stack is then processed. The result
+will be placed on the stack. At the end, there should be exactly one
+number left: the outcome of the series of operations. If there is not
+exactly one number left, rrdtool will complain loudly.</P>
+<P>Above multiplication by eight will look like:</P>
 <OL>
-<LI><STRONG><A NAME="item__">.</A></STRONG>
-<P>
+<LI>
 Start with an empty stack
-
-<LI><STRONG>.</STRONG>
-<P>
+<P></P>
+<LI>
 Put the content of variable inbytes on the stack
-
-<LI><STRONG>.</STRONG>
-<P>
+<P></P>
+<LI>
 Put the number eight on the stack
-
-<LI><STRONG>.</STRONG>
-<P>
+<P></P>
+<LI>
 Put the operation multiply on the stack
-
-<LI><STRONG>.</STRONG>
-<P>
+<P></P>
+<LI>
 Process the stack
-
-<LI><STRONG>.</STRONG>
-<P>
+<P></P>
+<LI>
 Retrieve the value from the stack and put it in variable inbits
-
-</OL>
-<P>
-We will now do an example with real numbers. Suppose the variable inbytes
-would have value 10, the stack would be:
-
+<P></P></OL>
+<P>We will now do an example with real numbers. Suppose the variable
+inbytes would have value 10, the stack would be:</P>
 <OL>
-<LI><STRONG>.</STRONG>
-<P>
+<LI>
 ||
-
-<LI><STRONG>.</STRONG>
-<P>
+<P></P>
+<LI>
 |10|
-
-<LI><STRONG>.</STRONG>
-<P>
+<P></P>
+<LI>
 |10|8|
-
-<LI><STRONG>.</STRONG>
-<P>
+<P></P>
+<LI>
 |10|8|*|
-
-<LI><STRONG>.</STRONG>
-<P>
+<P></P>
+<LI>
 |80|
-
-<LI><STRONG>.</STRONG>
-<P>
+<P></P>
+<LI>
 ||
-
-</OL>
-<P>
-Processing the stack (step 5) will retrieve one value from the stack (from
-the right at step 4). This is the operation multiply and this takes two
-values off the stack as input. The result is put back on the stack (the
-value 80 in this case). For multiplication the order doesn't matter but for
-other operations like subtraction and division it does. Generally speaking
-you have the following order:
-
-<P>
-<PRE>   y = A - B  --&gt;  y=minus(A,B)  --&gt;  CDEF:y=A,B,-
-</PRE>
-<P>
-This is not very intuitive (at least most people don't think so). For the
-function <CODE>f(A,B)</CODE> you reverse the position of ``f'' but you do
-not reverse the order of the variables. 
-
+<P></P></OL>
+<P>Processing the stack (step 5) will retrieve one value from the stack
+(from the right at step 4). This is the operation multiply and this
+takes two values off the stack as input. The result is put back on the
+stack (the value 80 in this case). For multiplication the order doesn't
+matter but for other operations like subtraction and division it does.
+Generally speaking you have the following order:</P>
+<PRE>
+   y = A - B  --&gt;  y=minus(A,B)  --&gt;  CDEF:y=A,B,-</PRE>
+<P>This is not very intuitive (at least most people don't think so). For
+the function <CODE>f(A,B)</CODE> you reverse the position of ``f'' but you do not
+reverse the order of the variables.</P>
 <P>
 <HR>
-<H1><A NAME="Converting_your_wishes_to_RPN">Converting your wishes to RPN</A></H1>
-<P>
-First, get a clear picture of what you want to do. Break down the problem
+<H1><A NAME="converting your wishes to rpn">Converting your wishes to RPN</A></H1>
+<P>First, get a clear picture of what you want to do. Break down the problem
 in smaller portions until they cannot be split anymore. Then it is rather
-simple to convert your ideas into RPN.
-
-<P>
-Suppose you have several RRDs and would like to add up some counters in
-them. These could be, for instance, the counters for every WAN link you are
-monitoring.
-
-<P>
-You have:
-
-<P>
-<PRE>   router1.rrd with link1in link2in
+simple to convert your ideas into RPN.</P>
+<P>Suppose you have several RRDs and would like to add up some counters in
+them. These could be, for instance, the counters for every WAN link you
+are monitoring.</P>
+<P>You have:</P>
+<PRE>
+   router1.rrd with link1in link2in
    router2.rrd with link1in link2in
-   router3.rrd with link1.in
-</PRE>
-<P>
-Suppose you would like to add up all these counters, except for link2in
-inside router2.rrd. You need to do:
-
-<P>
-(in this example, ``router1.rrd:link1in'' means the DS link1in inside the
-RRD router1.rrd)
-
-<P>
-<PRE>   router1.rrd:link1in
+   router3.rrd with link1in link2in</PRE>
+<P>Suppose you would like to add up all these counters, except for link2in
+inside router2.rrd. You need to do:</P>
+<P>(in this example, ``router1.rrd:link1in'' means the DS link1in inside the
+RRD router1.rrd)</P>
+<PRE>
+   router1.rrd:link1in
    router1.rrd:link2in
    router2.rrd:link1in
    router3.rrd:link1in
    router3.rrd:link2in 
    --------------------   +
-   (outcome of the sum)
-</PRE>
-<P>
-As a mathmatical function, this could be written:
-
-<P>
-<CODE>add(router1.rrd:link1in , router1.rrd:link2in , router2.rrd:link1in , router3.rrd:link1in , router3.rrd:link2.in)</CODE>
-
-
-
-<P>
-With RRDtool and RPN, first, define the inputs:
-
-<P>
-<PRE>   DEF:a=router1.rrd:link1in:AVERAGE
+   (outcome of the sum)</PRE>
+<P>As a mathmatical function, this could be written:</P>
+<P><CODE>add(router1.rrd:link1in , router1.rrd:link2in , router2.rrd:link1in , router3.rrd:link1in , router3.rrd:link2.in)</CODE></P>
+<P>With RRDtool and RPN, first, define the inputs:</P>
+<PRE>
+   DEF:a=router1.rrd:link1in:AVERAGE
    DEF:b=router1.rrd:link2in:AVERAGE
    DEF:c=router2.rrd:link1in:AVERAGE
    DEF:d=router3.rrd:link1in:AVERAGE
-   DEF:e=router3.rrd:link2in:AVERAGE
-</PRE>
-<P>
-Now, the mathematical function becomes: <CODE>add(a,b,c,d,e)</CODE>
-
-
-
-<P>
-In RPN, there's no operator that sums more than two values so you need to
-do several additions. You add a and b, add c to the result, add d to the
-result and add e to the result.
-
-<P>
-<PRE>   push a:         a     stack contains the value of a
+   DEF:e=router3.rrd:link2in:AVERAGE</PRE>
+<P>Now, the mathematical function becomes: <CODE>add(a,b,c,d,e)</CODE></P>
+<P>In RPN, there's no operator that sums more than two values so you need
+to do several additions. You add a and b, add c to the result, add d
+to the result and add e to the result.</P>
+<PRE>
+   push a:         a     stack contains the value of a
    push b and add: b,+   stack contains the result of a+b
    push c and add: c,+   stack contains the result of a+b+c
    push d and add: d,+   stack contains the result of a+b+c+d
-   push e and add: e,+   stack contains the result of a+b+c+d+e
-</PRE>
-<P>
-What was calculated here would be written down as:
-
-<P>
-<PRE>   ( ( ( (a+b) + c) + d) + e) &gt;
-</PRE>
-<P>
-This is in RPN:  <CODE>CDEF:result=a,b,+,c,+,d,+,e,+</CODE>
-
-
-
-<P>
-This is correct but it can be made more clear to humans. It does not matter
-if you add a to b and then add c to the result or first add b to c and then
-add a to the result. This makes it possible to rewrite the RPN into <CODE>CDEF:result=a,b,c,d,e,+,+,+,+</CODE> which is evaluatated differently: 
-
-<P>
-<PRE>   push value of variable a on the stack: a
+   push e and add: e,+   stack contains the result of a+b+c+d+e</PRE>
+<P>What was calculated here would be written down as:</P>
+<PRE>
+   ( ( ( (a+b) + c) + d) + e) &gt;</PRE>
+<P>This is in RPN:  <CODE>CDEF:result=a,b,+,c,+,d,+,e,+</CODE></P>
+<P>This is correct but it can be made more clear to humans. It does
+not matter if you add a to b and then add c to the result or first
+add b to c and then add a to the result. This makes it possible to
+rewrite the RPN into <CODE>CDEF:result=a,b,c,d,e,+,+,+,+</CODE> which is
+evaluatated differently:</P>
+<PRE>
+   push value of variable a on the stack: a
    push value of variable b on the stack: a b
    push value of variable c on the stack: a b c
    push value of variable d on the stack: a b c d
@@ -338,491 +246,365 @@
    push operator + on the stack:          a b Q +
    and process it:                        a R       (where R == b+Q)
    push operator + on the stack:          a R +
-   and process it:                        S         (where S == a+R)
-</PRE>
-<P>
-As you can see the RPN expression <CODE>a,b,c,d,e,+,+,+,+,+</CODE> will evaluate in
+   and process it:                        S         (where S == a+R)</PRE>
+<P>As you can see the RPN expression <CODE>a,b,c,d,e,+,+,+,+,+</CODE> will evaluate in
 <CODE>((((d+e)+c)+b)+a)</CODE> and it has the same outcome as <CODE>a,b,+,c,+,d,+,e,+</CODE> 
-According to Steve Rader this is called the commutative law of addition but
-you may forget this right away, as long as you remember what it represents.
-
-<P>
-Now look at an expression that contains a multiplication:
-
-<P>
-First in normal math: <CODE>let result = a+b*c</CODE>. In this case you can't choose the order yourself, you have to start with
-the multiplication and then add a to it. You may alter the position of b
-and c, you may not alter the position of a and b. 
-
-<P>
-You have to take this in consideration when converting this expression into
-RPN. Read it as: ``Add the outcome of b*c to a'' and then it is easy to
-write the RPN expression: <CODE>result=a,b,c,*,+</CODE>
-Another expression that would return the same: <CODE>result=b,c,*,a,+</CODE>
-
-
-
-<P>
-In normal math, you may encounter something like ``a*(b+c)'' and this can
-also be converted into RPN. The parenthesis just tell you to first add b
-and c, and then multiply a with the result. Again, now it is easy to write
-it in RPN: <CODE>result=a,b,c,+,*</CODE>. Note that this is very similar to one of the expressions in the previous
-paragraph, only the multiplication and the addition changed places.
-
-<P>
-When you have problems with RPN or when rrdtool is complaining, it's
-usually a Good Thing to write down the stack on a piece of paper and see
-what happens. Have the manual ready and pretend to be rrdtool. Just do all
-the math by hand to see what happens, I'm sure this will solve most, if not
-all, problems you encounter.
-
-<P>
-<HR>
-<H1><A NAME="Some_special_numbers">Some special numbers</A></H1>
-<P>
-<HR>
-<H2><A NAME="The_unknown_value">The unknown value</A></H2>
-<P>
-Sometimes collecting your data will fail. This can be very common,
-especially when querying over busy links. RRDtool can be configured to
-allow for one (or even more) unknown value and calculate the missing
+According to Steve Rader this is called the commutative law of addition
+but you may forget this right away, as long as you remember what it
+represents.</P>
+<P>Now look at an expression that contains a multiplication:</P>
+<P>First in normal math: <CODE>let result = a+b*c</CODE>. In this case you can't
+choose the order yourself, you have to start with the multiplication
+and then add a to it. You may alter the position of b and c, you may
+not alter the position of a and b.</P>
+<P>You have to take this in consideration when converting this expression
+into RPN. Read it as: ``Add the outcome of b*c to a'' and then it is
+easy to write the RPN expression: <CODE>result=a,b,c,*,+</CODE>
+Another expression that would return the same: <CODE>result=b,c,*,a,+</CODE></P>
+<P>In normal math, you may encounter something like ``a*(b+c)'' and this
+can also be converted into RPN. The parenthesis just tell you to first
+add b and c, and then multiply a with the result. Again, now it is
+easy to write it in RPN: <CODE>result=a,b,c,+,*</CODE>. Note that this is very
+similar to one of the expressions in the previous paragraph, only the
+multiplication and the addition changed places.</P>
+<P>When you have problems with RPN or when rrdtool is complaining, it's 
+usually a Good Thing to write down the stack on a piece of paper
+and see what happens. Have the manual ready and pretend to be rrdtool.
+Just do all the math by hand to see what happens, I'm sure this will
+solve most, if not all, problems you encounter.</P>
+<P>
+<HR>
+<H1><A NAME="some special numbers">Some special numbers</A></H1>
+<P>
+<H2><A NAME="the unknown value">The unknown value</A></H2>
+<P>Sometimes collecting your data will fail. This can be very common,
+especially when querying over busy links. RRDtool can be configured
+to allow for one (or even more) unknown value and calculate the missing
 update. You can, for instance, query your device every minute. This is
-creating one so called PDP or primary data point per minute. If you defined
-your RRD to contain an RRA that stores 5-minute values, you need five of
-those PDPs to create one CDP (consolidated data point). These PDPs can
-become unknown in two cases:
-
+creating one so called PDP or primary data point per minute. If you
+defined your RRD to contain an RRA that stores 5-minute values, you need
+five of those PDPs to create one CDP (consolidated data point).
+These PDPs can become unknown in two cases:</P>
 <OL>
-<LI><STRONG>.</STRONG>
-<P>
-The updates are too far apart. This is tuned using the ``heartbeat''
-setting
-
-<LI><STRONG>.</STRONG>
-<P>
+<LI>
+The updates are too far apart. This is tuned using the ``heartbeat'' setting
+<P></P>
+<LI>
 The update was set to unknown on purpose by inserting no value (using the
 template option) or by using ``U'' as the value to insert.
-
-</OL>
-<P>
-When a CDP is calculated, another mechanism determines if this CDP is valid
+<P></P></OL>
+<P>When a CDP is calculated, another mechanism determines if this CDP is valid
 or not. If there are too many PDPs unknown, the CDP is unknown as well.
 This is determined by the xff factor. Please note that one unknown counter
 update can result in two unknown PDPs! If you only allow for one unknown
-PDP per CDP, this makes the CDP go unknown!
-
-<P>
-Suppose the counter increments with one per second and you retrieve it
-every minute:
-
-<P>
-<PRE>   counter value    resulting rate
+PDP per CDP, this makes the CDP go unknown!</P>
+<P>Suppose the counter increments with one per second and you retrieve it
+every minute:</P>
+<PRE>
+   counter value    resulting rate
    10000
    10060            1; (10060-10000)/60 == 1
-   10120            1; (10060-10000)/60 == 1
+   10120            1; (10120-10060)/60 == 1
    unknown          unknown; you don't know the last value
    10240            unknown; you don't know the previous value
-   10300            1; (10300-10240)/60 == 1
-</PRE>
-<P>
-If the CDP was to be calculated from the last five updates, it would get
+   10300            1; (10300-10240)/60 == 1</PRE>
+<P>If the CDP was to be calculated from the last five updates, it would get
 two unknown PDPs and three known PDPs. If xff would have been set to 0.5
 which by the way is a commonly used factor, the CDP would have a known
-value of 1. If xff would have been set to 0.2 then the resulting CDP would
-be unknown.
-
-<P>
-You have to decide the proper values for heartbeat, number of PDPs per CDP
-and the xff factor. As you can see from the previous text they define the
-behavior of your RRA.
-
-<P>
-<HR>
-<H2><A NAME="Working_with_unknown_data_in_you">Working with unknown data in your database</A></H2>
-<P>
-As you have read in the previous chapter, entries in an RRA can be set to
-the unknown value. If you do calculations with this type of value, the
-result has to be unknown too. This means that an expression such as <CODE>result=a,b,+</CODE> will be unknown if either a or b is unknown. It would be wrong to just
-ignore the unknown value and return the value of the other parameter. By
-doing so, you would assume ``unknown'' means ``zero'' and this is not true.
-
-<P>
-There has been a case where somebody was collecting data for over a year. A
-new piece of equipment was installed, a new RRD was created and the scripts
-were changed to add a counter from the old database and a counter from the
-new database. The result was disappointing, a large part of the statistics
-seemed to have vanished mysteriously ... They of course didn't, values from
-the old database (known values) were added to values from the new database
-(unknown values) and the result was unknown.
-
-<P>
-In this case, it is fairly reasonable to use a CDEF that alters unknown
+value of 1. If xff would have been set to 0.2 then the resulting CDP
+would be unknown.</P>
+<P>You have to decide the proper values for heartbeat, number of PDPs per
+CDP and the xff factor. As you can see from the previous text they define
+the behavior of your RRA.</P>
+<P>
+<H2><A NAME="working with unknown data in your database">Working with unknown data in your database</A></H2>
+<P>As you have read in the previous chapter, entries in an RRA can be
+set to the unknown value. If you do calculations with this type of
+value, the result has to be unknown too. This means that an expression
+such as <CODE>result=a,b,+</CODE> will be unknown if either a or b is unknown.
+It would be wrong to just ignore the unknown value and return the value
+of the other parameter. By doing so, you would assume ``unknown'' means ``zero''
+and this is not true.</P>
+<P>There has been a case where somebody was collecting data for over a year.
+A new piece of equipment was installed, a new RRD was created and the
+scripts were changed to add a counter from the old database and a counter
+from the new database. The result was disappointing, a large part of
+the statistics seemed to have vanished mysteriously ...
+They of course didn't, values from the old database (known values) were
+added to values from the new database (unknown values) and the result was
+unknown.</P>
+<P>In this case, it is fairly reasonable to use a CDEF that alters unknown
 data into zero. The counters of the device were unknown (after all, it
 wasn't installed yet!) but you know that the data rate through the device
-had to be zero (because of the same reason: it was not installed).
-
-<P>
-There are some examples further on that make this change.
-
+had to be zero (because of the same reason: it was not installed).</P>
+<P>There are some examples further on that make this change.</P>
 <P>
-<HR>
-<H2><A NAME="Infinity">Infinity</A></H2>
-<P>
-Infinite data is another form of a special number. It cannot be graphed
+<H2><A NAME="infinity">Infinity</A></H2>
+<P>Infinite data is another form of a special number. It cannot be graphed
 because by definition you would never reach the infinite value. You could
 think of positive and negative infinity (I'm not sure if mathematicians
-will agree) depending on the position relative to zero.
-
-<P>
-RRDtool is capable of representing (-not- graphing!) infinity by stopping
+will agree) depending on the position relative to zero.</P>
+<P>RRDtool is capable of representing (-not- graphing!) infinity by stopping
 at its current maximum (for positive infinity) or minimum (for negative
-infinity) without knowing this maximum (minimum).
-
-<P>
-Infinity in rrdtool is mostly used to draw an AREA without knowing its
+infinity) without knowing this maximum (minimum).</P>
+<P>Infinity in rrdtool is mostly used to draw an AREA without knowing its
 vertical dimensions. You can think of it as drawing an AREA with an
-infinite height and displaying only the part that is visible in the current
-graph. This is probably a good way to approximate infinity and it sure
-allows for some neat tricks. See below for examples.
-
-<P>
-<HR>
-<H2><A NAME="Working_with_unknown_data_and_in">Working with unknown data and infinity</A></H2>
-<P>
-Sometimes you would like to discard unknown data and pretend it is zero (or
-any other value for that matter) and sometimes you would like to pretend
-that known data is unknown (to discard known-to-be-wrong data). This is why
-CDEFs have support for unknown data. There are also examples available that
-show unknown data by using infinity.
-
-<P>
-<HR>
-<H1><A NAME="Some_examples">Some examples</A></H1>
-<P>
-<HR>
-<H2><A NAME="Example_using_a_recently_create">Example: using a recently created RRD</A></H2>
-<P>
-You are keeping statistics on your router for over a year now. Recently you
-installed an extra router and you would like to show the combined
-throughput for these two devices.
-
-<P>
-If you just add up the counters from router.rrd and router2.rrd, you will
-add known data (from router.rrd) to unknown data (from router2.rrd) for the
-bigger part of your stats. You could solve this in a few ways:
-
+infinite height and displaying only the part that is visible in the
+current graph. This is probably a good way to approximate infinity
+and it sure allows for some neat tricks. See below for examples.</P>
+<P>
+<H2><A NAME="working with unknown data and infinity">Working with unknown data and infinity</A></H2>
+<P>Sometimes you would like to discard unknown data and pretend it is zero
+(or any other value for that matter) and sometimes you would like to
+pretend that known data is unknown (to discard known-to-be-wrong data).
+This is why CDEFs have support for unknown data. There are also examples
+available that show unknown data by using infinity.</P>
+<P>
+<HR>
+<H1><A NAME="some examples">Some examples</A></H1>
+<P>
+<H2><A NAME="example: using a recently created rrd">Example: using a recently created RRD</A></H2>
+<P>You are keeping statistics on your router for over a year now. Recently
+you installed an extra router and you would like to show the combined
+throughput for these two devices.</P>
+<P>If you just add up the counters from router.rrd and router2.rrd, you
+will add known data (from router.rrd) to unknown data (from router2.rrd) for
+the bigger part of your stats. You could solve this in a few ways:</P>
 <UL>
 <LI>
-<P>
 While creating the new database, fill it with zeros from the start to now.
 You have to make the database start at or before the least recent time in
 the other database.
-
+<P></P>
 <LI>
-<P>
 Alternately you could use CDEF and alter unknown data to zero.
-
-</UL>
-<P>
-Both methods have their pros and cons. The first method is troublesome and
+<P></P></UL>
+<P>Both methods have their pros and cons. The first method is troublesome and
 if you want to do that you have to figure it out yourself. It is not
-possible to create a database filled with zeros, you have to put them in on
-purpose. Implementing the second method is described next:
-
-<P>
-What we want is: ``if the value is unknown, replace it with zero''. This
-could be writte in pseudo-code as: if (value is unknown) then (zero) else
-(value). When reading the rrdgraph manual you notice the ``UN'' function
-that returns zero or one. You also notice the ``IF'' function that takes
-zero or one as input.
-
-<P>
-First look at the ``IF'' function. It takes three values from the stack,
-the first value is the decision point, the second value is returned to the
-stack if the evaluation is ``true'' and if not, the third value is returned
-to the stack. We want the ``UN'' function to decide what happens so we
-combine those two functions in one CDEF.
-
-<P>
-Lets write down the two possible paths for the ``IF'' function:
-
-<P>
-<PRE>   if true  return a
-   if false return b
-</PRE>
-<P>
-In RPN:  <CODE>result=x,a,b,IF</CODE> where ``x'' is either true or false.
-
-<P>
-Now we have to fill in ``x'', this should be the ``(value is unknown)''
-part and this is in RPN:  <CODE>result=value,UN</CODE>
-
-
-
-<P>
-We now combine them: <CODE>result=value,UN,a,b,IF</CODE> and when we fill in the appropriate things for ``a'' and ``b'' we're
-finished:
-
-<P>
-<CODE>CDEF:result=value,UN,0,value,IF</CODE>
-
-
-
-<P>
-You may want to read Steve Raders RPN guide if you have difficulties with
-the way I explained this last example.
-
-<P>
-If you want to check this RPN expression, just mimic rrdtools behavior:
-
-<P>
-<PRE>   For any known value, the expression evaluates as follows:
+possible to create a database filled with zeros, you have to put them in
+on purpose. Implementing the second method is described next:</P>
+<P>What we want is: ``if the value is unknown, replace it with zero''. This
+could be writte in pseudo-code as:  if (value is unknown) then (zero)
+else (value). When reading the rrdgraph manual you notice the ``UN''
+function that returns zero or one. You also notice the ``IF'' function
+that takes zero or one as input.</P>
+<P>First look at the ``IF'' function. It takes three values from the stack,
+the first value is the decision point, the second value is returned to
+the stack if the evaluation is ``true'' and if not, the third value is
+returned to the stack. We want the ``UN'' function to decide what happens
+so we combine those two functions in one CDEF.</P>
+<P>Lets write down the two possible paths for the ``IF'' function:</P>
+<PRE>
+   if true  return a
+   if false return b</PRE>
+<P>In RPN:  <CODE>result=x,a,b,IF</CODE> where ``x'' is either true or false.</P>
+<P>Now we have to fill in ``x'', this should be the ``(value is unknown)'' part
+and this is in RPN:  <CODE>result=value,UN</CODE></P>
+<P>We now combine them: <CODE>result=value,UN,a,b,IF</CODE> and when we fill in the
+appropriate things for ``a'' and ``b'' we're finished:</P>
+<P><CODE>CDEF:result=value,UN,0,value,IF</CODE></P>
+<P>You may want to read Steve Raders RPN guide if you have difficulties
+with the way I explained this last example.</P>
+<P>If you want to check this RPN expression, just mimic rrdtools behavior:</P>
+<PRE>
+   For any known value, the expression evaluates as follows:
    CDEF:result=value,UN,0,value,IF  (value,UN) is not true so it becomes 0
    CDEF:result=0,0,value,IF         &quot;IF&quot; will return the 3rd value
-   CDEF:result=value                The known value is returned
-</PRE>
-<P>
-<PRE>   For the unknown value, this happens:
+   CDEF:result=value                The known value is returned</PRE>
+<PRE>
+   For the unknown value, this happens:
    CDEF:result=value,UN,0,value,IF  (value,UN) is true so it becomes 1
    CDEF:result=1,0,value,IF         &quot;IF&quot; sees 1 and returns the 2nd value
-   CDEF:result=0                    Zero is returned
-</PRE>
-<P>
-Of course, if you would like to see another value instead of zero, you can
-use that other value.
-
-<P>
-Eventually, when all unknown data is removed from the RRD, you may want to
-remove this rule so that unknown data is properly displayed.
-
-<P>
-<HR>
-<H2><A NAME="Example_better_handling_of_unkn">Example: better handling of unknown data, by using time</A></H2>
-<P>
-Above example has one drawback. If you do log unknown data in your database
-after installing your new equipment, it will also be translated into zero
-and therefore you won't see that there was a problem. This is not good and
-what you really want to do is:
-
+   CDEF:result=0                    Zero is returned</PRE>
+<P>Of course, if you would like to see another value instead of zero, you
+can use that other value.</P>
+<P>Eventually, when all unknown data is removed from the RRD, you may want
+to remove this rule so that unknown data is properly displayed.</P>
+<P>
+<H2><A NAME="example: better handling of unknown data, by using time">Example: better handling of unknown data, by using time</A></H2>
+<P>Above example has one drawback. If you do log unknown data in
+your database after installing your new equipment, it will also be
+translated into zero and therefore you won't see that there was a
+problem. This is not good and what you really want to do is:</P>
 <UL>
 <LI>
-<P>
 If there is unknown data, look at the time that this sample was taken
-
+<P></P>
 <LI>
-<P>
 If the unknown value is before time xxx, make it zero
-
+<P></P>
 <LI>
-<P>
 If it is after time xxx, leave it as unknown data
-
-</UL>
-<P>
-This is doable: you can compare the time that the sample was taken to some
-known time. Assuming you started to monitor your device on Friday September
-17, 00:35:57 MET DST. Translate this time in seconds since 1970-01-01 and
-it becomes 937521357. If you process unknown values that were received
-after this time, you want to leave them unknown and if they were
-``received'' before this time, you want to translate them into zero (so you
-can effectively ignore them while adding them to your other routers
-counters).
-
-<P>
-Translating Friday September 17, 00:35:57 MET DST into 937521357 can be
-done by, for instance, using gnu date:
-
-<P>
-<PRE>   date -d &quot;19990917 00:35:57&quot; +%s
-</PRE>
-<P>
-You could also dump the database and see where the data starts to be known.
-There are several other ways of doing this, just pick one.
-
-<P>
-Now we have to create the magic that allows us to process unknown values
-different depending on the time that the sample was taken. This is a three
-step process:
-
+<P></P></UL>
+<P>This is doable: you can compare the time that the sample was taken
+to some known time. Assuming you started to monitor your device on
+Friday September 17, 00:35:57 MET DST. Translate this time in seconds
+since 1970-01-01 and it becomes 937521357. If you process unknown values
+that were received after this time, you want to leave them unknown and
+if they were ``received'' before this time, you want to translate them
+into zero (so you can effectively ignore them while adding them to your
+other routers counters).</P>
+<P>Translating Friday September 17, 00:35:57 MET DST into 937521357 can
+be done by, for instance, using gnu date:</P>
+<PRE>
+   date -d &quot;19990917 00:35:57&quot; +%s</PRE>
+<P>You could also dump the database and see where the data starts to be
+known. There are several other ways of doing this, just pick one.</P>
+<P>Now we have to create the magic that allows us to process unknown
+values different depending on the time that the sample was taken.
+This is a three step process:</P>
 <OL>
-<LI><STRONG>.</STRONG>
-<P>
+<LI>
 If the timestamp of the value is after 937521357, leave it as is
-
-<LI><STRONG>.</STRONG>
-<P>
+<P></P>
+<LI>
 If the value is a known value, leave it as is
-
-<LI><STRONG>.</STRONG>
-<P>
+<P></P>
+<LI>
 Change the unknown value into zero.
-
-</OL>
-<P>
-Lets look at part one:
-
-<P>
-<PRE>    if (true) return the original value
-</PRE>
-<P>
-We rewrite this:
-
-<P>
-<PRE>    if (true) return &quot;a&quot;
-    if (false) return &quot;b&quot;
-</PRE>
-<P>
-We need to calculate true or false from step 1. There is a function
-available that returns the timestamp for the current sample. It is called,
-how surprisingly, ``TIME''. This time has to be compared to a constant
-number, we need ``GT''. The output of ``GT'' is true or false and this is
-good input to ``IF''. We want ``if (time &gt; 937521357) then (return a)
-else (return b)''.
-
-<P>
-This process was already described toroughly in the previous chapter so
-lets do it quick:
-
-<P>
-<PRE>   if (x) then a else b
+<P></P></OL>
+<P>Lets look at part one:</P>
+<PRE>
+    if (true) return the original value</PRE>
+<P>We rewrite this:</P>
+<PRE>
+    if (true) return &quot;a&quot;
+    if (false) return &quot;b&quot;</PRE>
+<P>We need to calculate true or false from step 1. There is a function
+available that returns the timestamp for the current sample. It is
+called, how surprisingly, ``TIME''. This time has to be compared to
+a constant number, we need ``GT''. The output of ``GT'' is true or false
+and this is good input to ``IF''. We want ``if (time &gt; 937521357) then
+(return a) else (return b)''.</P>
+<P>This process was already described toroughly in the previous chapter
+so lets do it quick:</P>
+<PRE>
+   if (x) then a else b
       where x represents &quot;time&gt;937521357&quot;
       where a represents the original value
       where b represents the outcome of the previous example
-      
-   time&gt;937521357       --&gt; TIME,937521357,GT
 </PRE>
-<P>
-<PRE>   if (x) then a else b --&gt; x,a,b,IF
+<PRE>
+
+   time&gt;937521357       --&gt; TIME,937521357,GT</PRE>
+<PRE>
+   if (x) then a else b --&gt; x,a,b,IF
    substitute x         --&gt; TIME,937521357,GT,a,b,IF
    substitute a         --&gt; TIME,937521357,GT,value,b,IF
-   substitute b         --&gt; TIME,937521357,GT,value,value,UN,0,value,IF,IF
-</PRE>
-<P>
-We end up with:
-<CODE>CDEF:result=TIME,937521357,GT,value,value,UN,0,value,IF,IF</CODE>
-
-
-
-<P>
-This looks very complex however as you can see it was not too hard to come
-up with.
-
-<P>
-<HR>
-<H2><A NAME="Example_Pretending_weird_data_i">Example: Pretending weird data isn't there</A></H2>
-<P>
-Suppose you have a problem that shows up as huge spikes in your graph. You
-know this happens and why so you decide to work around the problem. Perhaps
-you're using your network to do a backup at night and by doing so you get
-almost 10mb/s while the rest of your network activity does not produce
-numbers higher than 100kb/s.
-
-<P>
-There are two options:
-
+   substitute b         --&gt; TIME,937521357,GT,value,value,UN,0,value,IF,IF</PRE>
+<P>We end up with:
+<CODE>CDEF:result=TIME,937521357,GT,value,value,UN,0,value,IF,IF</CODE></P>
+<P>This looks very complex however as you can see it was not too hard to
+come up with.</P>
+<P>
+<H2><A NAME="example: pretending weird data isn't there">Example: Pretending weird data isn't there</A></H2>
+<P>Suppose you have a problem that shows up as huge spikes in your graph.
+You know this happens and why so you decide to work around the problem.
+Perhaps you're using your network to do a backup at night and by doing
+so you get almost 10mb/s while the rest of your network activity does
+not produce numbers higher than 100kb/s.</P>
+<P>There are two options:</P>
 <OL>
-<LI><STRONG>.</STRONG>
-<P>
-If the number exceeds 100kb/s it is wrong and you want it masked out by
-changing it into unknown
-
-<LI><STRONG>.</STRONG>
-<P>
+<LI>
+If the number exceeds 100kb/s it is wrong and you want it masked out
+by changing it into unknown
+<P></P>
+<LI>
 You don't want the graph to show more than 100kb/s
-
-</OL>
-<P>
-Pseudo code: if (number &gt; 100) then unknown else number or Pseudo code:
-if (number &gt; 100) then 100 else number.
-
-<P>
-The second ``problem'' may also be solved by using the rigid option of
-rrdtool graph, however this has not the same result. In this example you
-can end up with a graph that does autoscaling. Also, if you use the numbers
-to display maxima they will be set to 100kb/s.
-
-<P>
-We use ``IF'' and ``GT'' again. ``if (x) then (y) else (z)'' is written
-down as ``CDEF:result=x,y,z,IF''; now fill in x, y and z. For x you fill in
-``number greater than 100kb/s'' becoming ``number,100000,GT'' (kilo is 1000
-and b/s is what we measure!). The ``z'' part is ``number'' in both cases
-and the ``y'' part is either ``UNKN'' for unknown or ``100000'' for
-100kb/s.
-
+<P></P></OL>
+<P>Pseudo code: if (number &gt; 100) then unknown else number
+or
+Pseudo code: if (number &gt; 100) then 100 else number.</P>
+<P>The second ``problem'' may also be solved by using the rigid option of
+rrdtool graph, however this has not the same result. In this example
+you can end up with a graph that does autoscaling. Also, if you use
+the numbers to display maxima they will be set to 100kb/s.</P>
+<P>We use ``IF'' and ``GT'' again. ``if (x) then (y) else (z)'' is written
+down as ``CDEF:result=x,y,z,IF''; now fill in x, y and z.
+For x you fill in ``number greater than 100kb/s'' becoming
+``number,100000,GT'' (kilo is 1000 and b/s is what we measure!).
+The ``z'' part is ``number'' in both cases and the ``y'' part is either
+``UNKN'' for unknown or ``100000'' for 100kb/s.</P>
+<P>The two CDEF expressions would be:</P>
+<PRE>
+    CDEF:result=number,100000,GT,UNKN,number,IF
+    CDEF:result=number,100000,GT,100000,number,IF</PRE>
+<P>
+<H2><A NAME="example: working on a certain time span">Example: working on a certain time span</A></H2>
+<P>If you want a graph that spans a few weeks, but would only want to
+see some routers data for one week, you need to ``hide'' the rest of
+the time frame. Don't ask me when this would be useful, it's just
+here for the example :)</P>
+<P>We need to compare the time stamp to a begin date and an end date.
+Comparing isn't difficult:</P>
+<PRE>
+        TIME,begintime,GE
+        TIME,endtime,LE</PRE>
+<P>These two parts of the CDEF produce either 0 for false or 1 for true.
+We can now check if they are both 0 (or 1) using a few IF statements
+but, as Wataru Satoh pointed out, we can use the ``*'' or ``+'' functions
+as locical AND and locical OR.</P>
+<P>For ``*'', the result will be zero (false) if either one of the two
+operators is zero.  For ``+'', the result will only be false (0) when
+two false (0) operators will be added.  Warning: *any* number not
+equal to 0 will be considered ``true''. This means that, for instance,
+``-1,1,+'' (which should be ``true or true'') will become FALSE ...
+In other words, use ``+'' only if you know for sure that you have positive
+numbers (or zero) only.</P>
+<P>Let's compile the complete CDEF:</P>
+<PRE>
+        DEF:ds0=router1.rrd:AVERAGE
+        CDEF:ds0modified=TIME,begintime,GE,TIME,endtime,LE,*,UNKN,ds0,IF</PRE>
+<P>This will return the value of ds0 if both comparisons return true. You
+could also do it the other way around:</P>
+<PRE>
+        DEF:ds0=router1.rrd:AVERAGE
+        CDEF:ds0modified=TIME,begintime,LT,TIME,endtime,GT,+,UNKN,ds0,IF</PRE>
+<P>This will return an UNKNOWN if either comparison returns true.</P>
 <P>
-The two CDEF expressions would be:
-
-<P>
-<PRE>    CDEF:result=number,100000,GT,UNKN,number,IF
-    CDEF:result=number,100000,GT,100000,number,IF
-</PRE>
-<P>
-<HR>
-<H2><A NAME="Example_You_suspect_to_have_pro">Example: You suspect to have problems and want to see unknown data.</A></H2>
-<P>
-Suppose you add up the number of active users on several terminal servers.
+<H2><A NAME="example: you suspect to have problems and want to see unknown data.">Example: You suspect to have problems and want to see unknown data.</A></H2>
+<P>Suppose you add up the number of active users on several terminal servers.
 If one of them doesn't give an answer (or an incorrect one) you get ``NaN''
-in the database (``Not a Number'') and NaN is evaluated as Unknown.
-
-<P>
-In this case, you would like to be alerted to it and the sum of the
-remaining values is of no value to you.
-
-<P>
-It would be something like:
-
-<P>
-<PRE>    DEF:users1=location1.rrd:onlineTS1:LAST
+in the database (``Not a Number'') and NaN is evaluated as Unknown.</P>
+<P>In this case, you would like to be alerted to it and the sum of the
+remaining values is of no value to you.</P>
+<P>It would be something like:</P>
+<PRE>
+    DEF:users1=location1.rrd:onlineTS1:LAST
     DEF:users2=location1.rrd:onlineTS2:LAST
     DEF:users3=location2.rrd:onlineTS1:LAST
     DEF:users4=location2.rrd:onlineTS2:LAST
-    CDEF:allusers=users1,users2,users3,users4,+,+,+
-</PRE>
-<P>
-If you now plot allusers, unknown data in one of users1..users4 will show
-up as a gap in your graph. You want to modify this to show a bright red
-line, not a gap.
-
-<P>
-Define an extra CDEF that is unknown if all is okay and is infinite if
-there is an unknown value:
-
-<P>
-<PRE>    CDEF:wrongdata=allusers,UN,INF,UNKN,IF
-</PRE>
-<P>
-``allusers,UN'' will evaluate to either true or false, it is the (x) part
-of the ``IF'' function and it checks if allusers is unknown. The (y) part
-of the ``IF'' function is set to ``INF'' (which means infinity) and the (z)
-part of the function returns ``UNKN''.
-
-<P>
-The logic is: if (allusers == unknown) then return INF else return UNKN.
-
-<P>
-You can now use AREA to display this ``wrongdata'' in bright red. If it is
-unknown (because allusers is known) then the red AREA won't show up. If the
-value is INF (because allusers is unknown) then the red AREA will be filled
-in on the graph at that particular time.
-
-<P>
-<PRE>   AREA:allusers#0000FF:combined user count
-   AREA:wrongdata#FF0000:unknown data
-</PRE>
-<P>
-<HR>
-<H2><A NAME="Same_example_useful_with_STACKed">Same example useful with STACKed data:</A></H2>
-<P>
-If you use stack in the previous example (as I would do) then you don't add
-up the values. Therefore, there is no relationship between the four values
-and you don't get a single value to test. Suppose users3 would be unknown
-at one point in time: users1 is plotted, users2 is stacked on top of
-users1, users3 is unknown and therefore nothing happens, users4 is stacked
-on top of users2. Add the extra CDEFs anyway and use them to overlay the
-``normal'' graph:
-
-<P>
-<PRE>   DEF:users1=location1.rrd:onlineTS1:LAST
+    CDEF:allusers=users1,users2,users3,users4,+,+,+</PRE>
+<P>If you now plot allusers, unknown data in one of users1..users4 will
+show up as a gap in your graph. You want to modify this to show a
+bright red line, not a gap.</P>
+<P>Define an extra CDEF that is unknown if all is okay and is infinite if
+there is an unknown value:</P>
+<PRE>
+    CDEF:wrongdata=allusers,UN,INF,UNKN,IF</PRE>
+<P>``allusers,UN'' will evaluate to either true or false, it is the (x) part
+of the ``IF'' function and it checks if allusers is unknown.
+The (y) part of the ``IF'' function is set to ``INF'' (which means infinity)
+and the (z) part of the function returns ``UNKN''.</P>
+<P>The logic is: if (allusers == unknown) then return INF else return UNKN.</P>
+<P>You can now use AREA to display this ``wrongdata'' in bright red. If it
+is unknown (because allusers is known) then the red AREA won't show up.
+If the value is INF (because allusers is unknown) then the red AREA will
+be filled in on the graph at that particular time.</P>
+<PRE>
+   AREA:allusers#0000FF:combined user count
+   AREA:wrongdata#FF0000:unknown data</PRE>
+<P>
+<H2><A NAME="same example useful with stacked data:">Same example useful with STACKed data:</A></H2>
+<P>If you use stack in the previous example (as I would do) then you don't
+add up the values. Therefore, there is no relationship between the
+four values and you don't get a single value to test.
+Suppose users3 would be unknown at one point in time: users1 is plotted,
+users2 is stacked on top of users1, users3 is unknown and therefore
+nothing happens, users4 is stacked on top of users2.
+Add the extra CDEFs anyway and use them to overlay the ``normal'' graph:</P>
+<PRE>
+   DEF:users1=location1.rrd:onlineTS1:LAST
    DEF:users2=location1.rrd:onlineTS2:LAST
    DEF:users3=location2.rrd:onlineTS1:LAST
    DEF:users4=location2.rrd:onlineTS2:LAST
@@ -832,81 +614,60 @@
    STACK:users2#00FF00:users at ts2
    STACK:users3#00FFFF:users at ts3
    STACK:users4#FFFF00:users at ts4
-   AREA:wrongdata#FF0000:unknown data
-</PRE>
-<P>
-If there is unknown data in one of users1..users4, the ``wrongdata'' AREA
+   AREA:wrongdata#FF0000:unknown data</PRE>
+<P>If there is unknown data in one of users1..users4, the ``wrongdata'' AREA
 will be drawn and because it starts at the X-axis and has infinite height
-it will effectively overwrite the STACKed parts.
-
-<P>
-You could combine the two CDEF lines into one (we don't use ``allusers'')
-if you like. But there are good reasons for writting two CDEFS:
-
+it will effectively overwrite the STACKed parts.</P>
+<P>You could combine the two CDEF lines into one (we don't use ``allusers'')
+if you like.  But there are good reasons for writting two CDEFS:</P>
 <UL>
 <LI>
-<P>
 It improves the readability of the script
-
+<P></P>
 <LI>
-<P>
 It can be used inside GPRINT to display the total number of users
-
-</UL>
-<P>
-If you choose to combine them, you can substitute the ``allusers'' in the
-second CDEF with the part after the equal sign from the first line:
-
-<P>
-<PRE>   CDEF:wrongdata=users1,users2,users3,users4,+,+,+,UN,INF,UNKN,IF
-</PRE>
-<P>
-If you do so, you won't be able to use these next GPRINTs:
-
-<P>
-<PRE>   COMMENT:&quot;Total number of users seen&quot;
+<P></P></UL>
+<P>If you choose to combine them, you can substitute the ``allusers'' in the
+second CDEF with the part after the equal sign from the first line:</P>
+<PRE>
+   CDEF:wrongdata=users1,users2,users3,users4,+,+,+,UN,INF,UNKN,IF</PRE>
+<P>If you do so, you won't be able to use these next GPRINTs:</P>
+<PRE>
+   COMMENT:&quot;Total number of users seen&quot;
    GPRINT:allusers:MAX:&quot;Maximum: %6.0lf&quot;
    GPRINT:allusers:MIN:&quot;Minimum: %6.0lf&quot;
    GPRINT:allusers:AVERAGE:&quot;Average: %6.0lf&quot;
-   GPRINT:allusers:LAST:&quot;Current: %6.0lf\n&quot;
-</PRE>
-<P>
-<HR>
-<H1><A NAME="The_examples_from_the_rrd_graph_">The examples from the rrd graph manual page</A></H1>
+   GPRINT:allusers:LAST:&quot;Current: %6.0lf\n&quot;</PRE>
 <P>
 <HR>
-<H2><A NAME="Degrees_Celcius_vs_Degrees_Fahr">Degrees Celcius vs. Degrees Fahrenheit</A></H2>
+<H1><A NAME="the examples from the rrd graph manual page">The examples from the rrd graph manual page</A></H1>
 <P>
-<PRE>   rrdtool graph demo.gif --title=&quot;Demo Graph&quot; \
+<H2><A NAME="degrees celcius vs. degrees fahrenheit">Degrees Celcius vs. Degrees Fahrenheit</A></H2>
+<PRE>
+   rrdtool graph demo.gif --title=&quot;Demo Graph&quot; \
       DEF:cel=demo.rrd:exhaust:AVERAGE \
       CDEF:far=cel,32,-,0.55555,* \
       LINE2:cel#00a000:&quot;D. Celsius&quot; \
-      LINE2:far#ff0000:&quot;D. Fahrenheit\c&quot;
-</PRE>
-<P>
-This example gets the DS called ``exhaust'' from database ``demo.rrd'' and
-puts the values in variable ``cel''. The CDEF used is evaluated as follows:
-
-<P>
-<PRE>   CDEF:far=cel,32,-,0.5555,*
+      LINE2:far#ff0000:&quot;D. Fahrenheit\c&quot;</PRE>
+<P>This example gets the DS called ``exhaust'' from database ``demo.rrd''
+and puts the values in variable ``cel''. The CDEF used is evaluated
+as follows:</P>
+<PRE>
+   CDEF:far=cel,32,-,0.5555,*
    1. push variable &quot;cel&quot;
    2. push 32
    3. push function &quot;minus&quot; and process it
       The stack now contains values that are 32 less than &quot;cel&quot;
    4. push 0.5555
    5. push function &quot;multiply&quot; and process it
-   6. the resulting value is now &quot;(cel-32)*0.55555&quot;
-</PRE>
-<P>
-Note that if you take the celcius to fahrenheit function you should be
-doing ``5/9*(cel-32)'' so 0.55555 is not exactly correct. It is close
-enough for this purpose and it saves a calculation.
-
-<P>
-<HR>
-<H2><A NAME="Changing_unknown_into_zero">Changing unknown into zero</A></H2>
-<P>
-<PRE>   rrdtool graph demo.gif --title=&quot;Demo Graph&quot; \
+   6. the resulting value is now &quot;(cel-32)*0.55555&quot;</PRE>
+<P>Note that if you take the celcius to fahrenheit function you should
+be doing ``5/9*(cel-32)'' so 0.55555 is not exactly correct. It is close
+enough for this purpose and it saves a calculation.</P>
+<P>
+<H2><A NAME="changing unknown into zero">Changing unknown into zero</A></H2>
+<PRE>
+   rrdtool graph demo.gif --title=&quot;Demo Graph&quot; \
       DEF:idat1=interface1.rrd:ds0:AVERAGE \
       DEF:idat2=interface2.rrd:ds0:AVERAGE \
       DEF:odat1=interface1.rrd:ds1:AVERAGE \
@@ -914,30 +675,28 @@
       CDEF:agginput=idat1,UN,0,idat1,IF,idat2,UN,0,idat2,IF,+,8,* \
       CDEF:aggoutput=odat1,UN,0,odat1,IF,odat2,UN,0,odat2,IF,+,8,* \
       AREA:agginput#00cc00:Input Aggregate \
-      LINE1:aggoutput#0000FF:Output Aggregate
-</PRE>
-<P>
-These two CDEFs are built from several functions. It helps to split them
-when viewing what they do. Starting with the first CDEF we would get:
-idat1,UN --&gt; a 0 --&gt; b idat1 --&gt; c if (a) then (b) else (c) The
-result is therefore ``0'' if it is true that ``idat1'' equals ``UN''. If
-not, the original value of ``idat1'' is put back on the stack. Lets call
-this answer ``d''. The process is repeated for the next five items on the
-stack, it is done the same and will return answer ``h''. The resulting
-stack is therefore ``d,h''. The expression has been simplified to
-``d,h,+,8,*'' and it will now be easy to see that we add ``d'' and ``h'',
-and multiply the result with eight.
-
-<P>
-The end result is that we have added ``idat1'' and ``idat2'' and in the
-process we effectively ignored unknown values. The result is multiplied by
-eight, most likely to convert bytes/s to bits/s.
-
-<P>
-<HR>
-<H2><A NAME="Infinity_demo">Infinity demo</A></H2>
-<P>
-<PRE>   rrdtool graph example.png --title=&quot;INF demo&quot; \
+      LINE1:aggoutput#0000FF:Output Aggregate</PRE>
+<P>These two CDEFs are built from several functions. It helps to
+split them when viewing what they do.
+Starting with the first CDEF we would get:
+      idat1,UN --&gt; a
+      0        --&gt; b
+      idat1    --&gt; c
+      if (a) then (b) else (c)
+The result is therefore ``0'' if it is true that ``idat1'' equals ``UN''.
+If not, the original value of ``idat1'' is put back on the stack.
+Lets call this answer ``d''. The process is repeated for the next
+five items on the stack, it is done the same and will return answer
+``h''. The resulting stack is therefore ``d,h''.
+The expression has been simplified to ``d,h,+,8,*'' and it will now be
+easy to see that we add ``d'' and ``h'', and multiply the result with eight.</P>
+<P>The end result is that we have added ``idat1'' and ``idat2'' and in the
+process we effectively ignored unknown values. The result is multiplied
+by eight, most likely to convert bytes/s to bits/s.</P>
+<P>
+<H2><A NAME="infinity demo">Infinity demo</A></H2>
+<PRE>
+   rrdtool graph example.png --title=&quot;INF demo&quot; \
       DEF:val1=some.rrd:ds0:AVERAGE \
       DEF:val2=some.rrd:ds1:AVERAGE \
       DEF:val3=some.rrd:ds2:AVERAGE \
@@ -949,83 +708,60 @@
       STACK:val2#00C000:Value2 \
       STACK:val3#FFFF00:Value3 \
       STACK:val4#FFC000:Value4 \
-      AREA:whipeout#FF0000:Unknown
-</PRE>
-<P>
-This demo demonstrates two ways to use infinity. It is a bit tricky to see
-what happens in the ``background'' CDEF.
-
-<P>
-<PRE>   &quot;val4,POP,TIME,7200,%,3600,LE,INF,UNKN,IF&quot;
-</PRE>
-<P>
-This RPN takes the value of ``val4'' as input and then immediately removes
-it from the stack using ``POP''. The stack is now empty but as a side
-result we now know the time that this sample was taken. This time is put on
-the stack by the ``TIME'' function.
-
-<P>
-``TIME,7200,%'' takes the modulo of time and 7200 (which is two hours). The
-resulting value on the stack will be a number in the range from 0 to 7199.
-
-<P>
-For people who don't know the modulo function: it is the remainder after an
-integer division. If you divide 16 by 3, the answer would be 5 and the
-remainder would be 1. So, ``16,3,%'' returns 1.
-
-<P>
-We have the result of ``TIME,7200,%'' on the stack, lets call this ``a''.
-The start of the RPN has become ``a,3600,LE'' and this checks if ``a'' is
-less or equal than ``3600''. It is true half of the time. We now have to
-process the rest of the RPN and this is only a simple ``IF'' function that
-returns either ``INF'' or ``UNKN'' depending on the time. This is returned
-to variable ``background''.
-
-<P>
-The second CDEF has been discussed earlyer in this document so we won't do
-that here.
-
-<P>
-Now you can draw the different layers. Start with the background that is
-either unknown (nothing to see) or infinite (the whole positive part of the
-graph gets filled). Next you draw the data on top of this background. It
-will overlay the background. Suppose one of val1..val4 would be unknown, in
-that case you end up with only three bars stacked on top of each other. You
-don't want to see this because the data is only valid when all four
-variables are valid. This is why you use the second CDEF, it will overlay
-the data with an AREA so the data cannot be seen anymore.
-
-<P>
-If your data can also have negative values you also need to overwrite the
-other half of your graph. This can be done in a relatively simple way: what
-you need is the ``wipeout'' variable and place a negative sign before it:
-``CDEF:wipeout2=wipeout,-1,*'' =head1 Out of ideas for now
-
-<P>
-This document was created from questions asked by either myself or by other
-people on the list. Please let me know if you find errors in it or if you
-have trouble understanding it. If you think there should be an addition,
-mail me: &lt;<A HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt;
-
-
-
-<P>
-Remember: <STRONG>No feedback equals no changes!</STRONG>
-
-
-
-<P>
-<HR>
-<H1><A NAME="SEE_ALSO">SEE ALSO</A></H1>
-<P>
-The RRDtool manpages
-
-<P>
-<HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-Alex van den Bogaerdt
-&lt;<A HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt;
+      AREA:whipeout#FF0000:Unknown</PRE>
+<P>This demo demonstrates two ways to use infinity. It is a bit tricky
+to see what happens in the ``background'' CDEF.</P>
+<PRE>
+   &quot;val4,POP,TIME,7200,%,3600,LE,INF,UNKN,IF&quot;</PRE>
+<P>This RPN takes the value of ``val4'' as input and then immediately
+removes it from the stack using ``POP''. The stack is now empty but
+as a side result we now know the time that this sample was taken.
+This time is put on the stack by the ``TIME'' function.</P>
+<P>``TIME,7200,%'' takes the modulo of time and 7200 (which is two hours).
+The resulting value on the stack will be a number in the range from
+0 to 7199.</P>
+<P>For people who don't know the modulo function: it is the remainder
+after an integer division. If you divide 16 by 3, the answer would
+be 5 and the remainder would be 1. So, ``16,3,%'' returns 1.</P>
+<P>We have the result of ``TIME,7200,%'' on the stack, lets call this
+``a''. The start of the RPN has become ``a,3600,LE'' and this checks
+if ``a'' is less or equal than ``3600''. It is true half of the time.
+We now have to process the rest of the RPN and this is only a simple
+``IF'' function that returns either ``INF'' or ``UNKN'' depending on the
+time. This is returned to variable ``background''.</P>
+<P>The second CDEF has been discussed earlyer in this document so we
+won't do that here.</P>
+<P>Now you can draw the different layers. Start with the background
+that is either unknown (nothing to see) or infinite (the whole
+positive part of the graph gets filled).
+Next you draw the data on top of this background. It will overlay
+the background. Suppose one of val1..val4 would be unknown, in that
+case you end up with only three bars stacked on top of each other.
+You don't want to see this because the data is only valid when all
+four variables are valid. This is why you use the second CDEF, it
+will overlay the data with an AREA so the data cannot be seen anymore.</P>
+<P>If your data can also have negative values you also need to overwrite
+the other half of your graph. This can be done in a relatively simple
+way: what you need is the ``wipeout'' variable and place a negative
+sign before it:  ``CDEF:wipeout2=wipeout,-1,*''
+</P>
+<PRE>
+
+=head1 Out of ideas for now</PRE>
+<P>This document was created from questions asked by either myself or
+by other people on the list. Please let me know if you find errors
+in it or if you have trouble understanding it. If you think there
+should be an addition, mail me: &lt;<A HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt;</P>
+<P>Remember: <STRONG>No feedback equals no changes!</STRONG></P>
+<P>
+<HR>
+<H1><A NAME="see also">SEE ALSO</A></H1>
+<P>The RRDtool manpages</P>
+<P>
+<HR>
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Alex van den Bogaerdt
+&lt;<A HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt;</P>
 
 </BODY>
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.txt	Sat Jul 13 21:26:26 2002
@@ -60,7 +60,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      1
+2001-02-22             Last change: 1.0.33                      1
 
 
 
@@ -126,7 +126,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      2
+2001-02-22             Last change: 1.0.33                      2
 
 
 
@@ -153,8 +153,8 @@
      important, some background information of how it works.
 
      You will need to know something about hexadecimal numbers.
-     If you don't then start with reading "bin_dec_hex" before
-     you continue here.
+     If you don't then start with reading the bin_dec_hex manpage
+     before you continue here.
 
      YYYYoooouuuurrrr ffffiiiirrrrsssstttt RRRRoooouuuunnnndddd RRRRoooobbbbiiiinnnn DDDDaaaattttaaaabbbbaaaasssseeee
 
@@ -192,7 +192,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      3
+2001-02-22             Last change: 1.0.33                      3
 
 
 
@@ -212,7 +212,7 @@
        bps = (counter_now - counter_before) / (time_now - time_before) * 8
 
      For some people it may help to translate this to a
-     automobile example:  Do not try this example, and if you do,
+     automobile example: Do not try this example, and if you do,
      don't blame me for the results.
 
      People who are not used to think in kilometers per hour can
@@ -258,7 +258,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      4
+2001-02-22             Last change: 1.0.33                      4
 
 
 
@@ -282,7 +282,8 @@
                  RRA:AVERAGE:0.5:1:24       \
                  RRA:AVERAGE:0.5:6:10
 
-     (So enter: rrdtool create test.rrd --start 920804400 DS ...)
+     (So enter: `rrdtool create test.rrd --start 920804400 DS
+     ...')
 
      WWWWhhhhaaaatttt hhhhaaaassss bbbbeeeeeeeennnn ccccrrrreeeeaaaatttteeeedddd ????
 
@@ -323,8 +324,7 @@
 
 
 
-
-24/Oct/1999            Last change: 1.0.13                      5
+2001-02-22             Last change: 1.0.33                      5
 
 
 
@@ -390,7 +390,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      6
+2001-02-22             Last change: 1.0.33                      6
 
 
 
@@ -456,7 +456,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      7
+2001-02-22             Last change: 1.0.33                      7
 
 
 
@@ -522,7 +522,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      8
+2001-02-22             Last change: 1.0.33                      8
 
 
 
@@ -588,7 +588,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      9
+2001-02-22             Last change: 1.0.33                      9
 
 
 
@@ -654,7 +654,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     10
+2001-02-22             Last change: 1.0.33                     10
 
 
 
@@ -720,7 +720,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     11
+2001-02-22             Last change: 1.0.33                     11
 
 
 
@@ -786,7 +786,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     12
+2001-02-22             Last change: 1.0.33                     12
 
 
 
@@ -852,7 +852,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     13
+2001-02-22             Last change: 1.0.33                     13
 
 
 
@@ -878,13 +878,13 @@
       24 samples averaged become one average on 2 hours
       288 samples averaged become one average on 1 day
 
-     Lets try to be compatible with MRTG:  MRTG stores about the
+     Lets try to be compatible with MRTG: MRTG stores about the
      following amount of data:
 
       600 5-minute samples:    2   days and 2 hours
       600 30-minute samples:  12.5 days
       600 2-hour samples:     50   days
-      600 1-day samples:     732   days
+      732 1-day samples:     732   days
 
      These ranges are appended so the total amount of data kept
      is approximately 797 days.  RRDtool stores the data
@@ -918,7 +918,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     14
+2001-02-22             Last change: 1.0.33                     14
 
 
 
@@ -984,7 +984,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     15
+2001-02-22             Last change: 1.0.33                     15
 
 
 
@@ -1050,7 +1050,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     16
+2001-02-22             Last change: 1.0.33                     16
 
 
 
@@ -1116,7 +1116,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     17
+2001-02-22             Last change: 1.0.33                     17
 
 
 
@@ -1145,7 +1145,7 @@
      counter is reset when it's read. That is: its delta is known
      without calculation by RRDtool whereas RRDtool needs to
      calculate it for the counter type.  Example: our first
-     example (12345, 12357, 12363, 12363) would read:  unknown,
+     example (12345, 12357, 12363, 12363) would read: unknown,
      12, 6, 0. The rest of the calculations stay the same.  The
      other one, derive, is like counter. Unlike counter, it can
      also decrease so it can have a negative delta. Again, the
@@ -1182,7 +1182,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     18
+2001-02-22             Last change: 1.0.33                     18
 
 
 
@@ -1225,8 +1225,8 @@
      If your GIF shows all this, you know you have typed the data
      correct, the RRDtool executable is working properly, your
      viewer doesn't fool you and you successfully entered the
-     year 2000 :)  You could try the same example four times,
-     each time with only one of the lines.
+     year 2000 :) You could try the same example four times, each
+     time with only one of the lines.
 
      Let's go over the data again:
 
@@ -1248,7 +1248,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     19
+2001-02-22             Last change: 1.0.33                     19
 
 
 
@@ -1276,7 +1276,7 @@
 
      There are a few more basics to show. Some important options
      are still to be covered and we haven't look at counter wraps
-     yet. First the counter wrap:  In our car we notice that our
+     yet. First the counter wrap: In our car we notice that our
      counter shows 999987. We travel 20 KM and the counter should
      go to 1000007. Unfortunately, there are only six digits on
      our counter so it really shows 000007. If we would plot that
@@ -1314,7 +1314,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     20
+2001-02-22             Last change: 1.0.33                     20
 
 
 
@@ -1380,7 +1380,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     21
+2001-02-22             Last change: 1.0.33                     21
 
 
 
@@ -1446,7 +1446,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     22
+2001-02-22             Last change: 1.0.33                     22
 
 
 
@@ -1512,7 +1512,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     23
+2001-02-22             Last change: 1.0.33                     23
 
 
 
@@ -1578,73 +1578,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     24
-
-
-
-
-
-
-rrdtool                                            RRDTUTORIAL(1)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-24/Oct/1999            Last change: 1.0.13                     25
-
-
-
+2001-02-22             Last change: 1.0.33                     24
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdlast.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdlast.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdlast.txt	Sat Jul 13 21:26:26 2002
@@ -60,7 +60,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      1
+2001-02-20             Last change: 1.0.33                      1
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdgraph.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdgraph.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdgraph.pod	Sat Jul 13 21:26:27 2002
@@ -2,6 +2,8 @@
 
 rrdtool graph - Create a graph based on data from one or several RRD
 
+=for html <div align="right"><a href="rrdgraph.pdf">PDF</a> version.</div> 
+
 =head1 SYNOPSIS
 
 B<rrdtool> B<graph> I<filename> 
@@ -11,6 +13,8 @@
 S<[B<-y>|B<--y-grid> I<y-axis grid and label>]>
 S<[B<--alt-y-grid>]>
 S<[B<--alt-autoscale>]>
+S<[B<--alt-autoscale-max>]>
+S<[B<--units-exponent>]> I<value>]>
 S<[B<-v>|B<--vertical-label> I<text>]>
 S<[B<-w>|B<--width> I<pixels>]>
 S<[B<-h>|B<--height> I<pixels>]> 
@@ -22,9 +26,9 @@
 S<[B<-u>|B<--upper-limit> I<value>]> 
 S<[B<-l>|B<--lower-limit> I<value>]>
 S<[B<-r>|B<--rigid>]>
+S<[B<--step> I<value>]>
 S<[B<-b>|B<--base> I<value>]>
 S<[B<-c>|B<--color> I<COLORTAG>B<#>I<rrggbb>]>
-
 S<[B<-t>|B<--title> I<title>]>
 S<[B<DEF:>I<vname>B<=>I<rrd>B<:>I<ds-name>B<:>I<CF>]>
 S<[B<CDEF:>I<vname>B<=>I<rpn-expression>]>
@@ -43,7 +47,7 @@
 representations of the data stored in one or several B<RRD>s. Apart
 from generating graphs, it can also extract numerical reports.
 
-=over 8
+=over
 
 =item I<filename> 
 
@@ -78,7 +82,9 @@
 very special needs, you can rely on the autoconfiguration to get this
 right.
 
-The x-axis label is configured, using the following format:
+If you want no x-grid at all, use the magic setting B<none>.
+
+The x-axis label and grid can be configured, using the following format:
 
 I<GTM>B<:>I<GST>B<:>I<MTM>B<:>I<MST>B<:>I<LTM>:I<LST>B<:>I<LPR>B<:>I<LFM>
 
@@ -113,6 +119,8 @@
 I<label factor> gridstep, a major grid line is printed, along with
 label showing the value of the grid line.
 
+If you want no y-grid at all set specify the magic word B<none>.
+
 =item B<--alt-y-grid>
 
 Place Y grid dynamically based on graph Y range. Algorithm ensures
@@ -132,6 +140,26 @@
 from slightly less the 260 - 0.001 to slightly more then 260 + 0.001
 and periodic behavior will be seen.   (contributed by Sasha Mikheev)
 
+=item B<--alt-autoscale-max>
+
+Where --alt-autoscale will modify both the absolute maximum AND minimum
+values, this option will only affect the maximum value. The minimum 
+value, if not defined on the command line, will be 0. This option can
+be useful when graphing router traffic when the WAN line uses compression,
+and thus the throughput may be higher than the WAN line speed.
+
+=item B<--units-exponent> I<value> (default autoconfigure)
+
+This sets the 10**exponent scaling of the y-axis values.  Normally
+values will be scaled to the appropriate units (k, M, etc.).  However
+you may wish to display units always in k (Kilo, 10e3) even if the data
+is in the M (Mega, 10e6) range for instance.  Value should be an
+integer which is a multiple of 3 between -18 and 18 inclusive.  It is
+the exponent on the units you which to use.  For example, use 3 to
+display the y-axis values in k (Kilo, 10e3, thousands), use -6 to
+display the y-axis values in u (Micro, 10e-6, millionths).  Use a value
+of 0 to prevent any scaling of the y-axis values.
+
 =item B<-v>|B<--vertical-label> I<text>
 
 vertical label on the left side of the graph. This is normally used to
@@ -178,15 +206,12 @@
 
 =item B<-u>|B<--upper-limit> I<value> (default autoconfigure)
 
-This is not the upper limit of a graph!  But rather, this is the
-minimum upper bound of a graph.  Use this to expand graphs up.
-For example, the value 100 will result in graphs that have a upper
-bound of 100 or more.  Setting the upper limit to the maximum value
-for some DS will result in disabling RRDtool's autoscaling down (ie
-it will "expand" graphs up.)  To disable RRDtool's autoscaling up
-(to the max value for the DSs graphed), use a nifty CDEF like so:
-CDEF:mcpu=cpu,100,GT,100,cpu,IF.  If this CDEF is applied to all DSs
-in a graph, then the graph will have an upper limit of 100.
+Defines the value normally located at the upper border of the
+graph. If the graph contains higher values, the upper border will
+move upwards to accomodate these values as well.
+
+If you want to define an upper-limit which will not move in any
+event you have to set the B<--rigid> option as well.
 
 =item B<-l>|B<--lower-limit> I<value> (default autoconfigure)
 
@@ -219,10 +244,22 @@
 major grid, B<FONT>, B<FRAME> and axis of the graph or B<ARROW>. This option
 can be called multiple times to set several colors.
 
+=item B<-g>|B<--no-legend>
+
+Suppress generation of legend; only render the graph.
+
 =item B<-t>|B<--title> I<text> (default no title)
 
 Define a title to be written into the graph
 
+=item B<--step> I<value> (default automatic)
+
+By default rrdgraph calculates the width of one pixle in the time domain and
+tries to get data at that resolution from the RRD. With this switch you can
+override this behaviour. If you want rrdgraph to get data at 1 hour
+resolution from the RRD, then you can set the step to 3600 seconds. Note,
+that a step smaller than 1 pixle will be silently ignored.
+
 =item B<DEF:>I<vname>B<=>I<rrd>B<:>I<ds-name>B<:>I<CF>
 
 Define virtual name for a data source. This name can then be used
@@ -260,7 +297,7 @@
 as well as I<vname> variables. The following operators can be used on these
 values: 
 
-=over 8
+=over
 
 =item +, -, *, /, %
 
@@ -268,7 +305,7 @@
 the result back onto the stack. The % operator stands for the modulo
 operation.
 
-=item SIN, COS, LOG, EXP
+=item SIN, COS, LOG, EXP, FLOOR, CEIL
 
 pops one value from the stack, applies the selected function and pushes
 the result back onto the stack.
@@ -290,6 +327,17 @@
 look at C and if it is not 0 it will push D back onto the stack, otherwise
 E will be sent back to the stack.
 
+=item MIN, MAX
+
+selects the lesser or larger of the two top stack values respectively
+
+=item LIMIT
+
+replaces the value with I<*UNKNOWN*> if it is outside the limits specified
+by the two values above it on the stack.
+
+ CDEF:a=alpha,0,100,LIMIT
+
 =item DUP, EXC, POP
 
 These manipulate the stack directly.  DUP will duplicate the top of the
@@ -325,7 +373,20 @@
 
 =item TIME
 
-Push the time the current sample was taken onto the stack.
+Push the time the current sample was taken onto the stack. This is the
+number of non-skip seconds since 0:00:00 January 1, 1970.
+
+=item LTIME
+
+This is like TIME B<+ current timezone offset in seconds>. The current
+offset takes daylight saving time into account, given your OS supports
+this. If you were looking at a sample, in Zurich, in summer, the
+offset would be 2*3600 seconds, as Zurich at that time of year is 2
+hours ahead of UTC.
+
+Note that the timezone offset is always calculated for the time the
+current sample was taken at. It has nuthing todo with the time you are
+doing the calculation.
 
 =back
 
@@ -355,10 +416,25 @@
 unit and a SI magnitude unit will only be calculated when the next '%s' is
 seen or the next '%S' for a non-zero value.
 
+If you want to put a '%' into your PRINT string, use '%%' instead.
+
 =item B<GPRINT:>I<vname>B<:>I<CF>B<:>I<format>
 
 Same as B<PRINT> but the result is printed into the graph below the legend.
 
+=back
+
+B<Caveat:> When using the B<PRINT> and B<GRPRINT> functions to
+calculate data summaries over time periods bounded by the current
+time, it is important to note that the last sample will almost always
+yield a value of UNKNOWN as it lies after the last update time.  This
+can result in slight data skewing, particularly with the B<AVERAGE>
+function.  In order to avoid this, make sure that your end time is at
+least one heartbeat prior to the current time.
+
+=over
+
+
 =item B<COMMENT:>I<text>
 
 Like B<GPRINT> but the I<text> is simply printed into the graph.
@@ -398,7 +474,7 @@
 any graphics ... *UNKNOWN* is not zero ... if you want it to zero
 then you might want to use a CDEF argument with IF and UN functions to
 turn *UNKNOWN* into zero ...
- 
+
 =back
 
 =head1 NOTES on legend arguments
@@ -428,7 +504,7 @@
 in connection with B<%s> to supress empty unit strings.
 
  GPRINT:a:MAX:%lf%s\g
- 
+
 A special case is COMMENT:B<\s> this inserts some additional vertical space
 before placing the next row of legends.
 
@@ -441,7 +517,7 @@
 
   rrdtool graph demo.gif --title="Demo Graph" \
           DEF:cel=demo.rrd:exhaust:AVERAGE \
-          "CDEF:far=cel,32,-,0.55555,*" \
+          "CDEF:far=cel,1.8,*,32,+"" \
           LINE2:cel#00a000:"D. Celsius" \
           LINE2:far#ff0000:"D. Fahrenheit\c"
 
@@ -490,7 +566,7 @@
          STACK:val2#00C000:Value2 \
          STACK:val3#FFFF00:Value3 \
          STACK:val4#FFC000:Value4 \
-         AREA:whipeout#FF0000:Unknown
+         AREA:wipeout#FF0000:Unknown
 
 The first CDEF uses val4 as a dummy value. It's value is removed immediately
 from the stack. Then a decision is made based on the time that a sample was
@@ -506,7 +582,7 @@
 not least, overlay everything with eye-hurting red
 to signal any unknown data.
 
-Note that this example assumesthat your data is in the positive half of the y-axis
+Note that this example assumes that your data is in the positive half of the y-axis
 otherwhise you would would have to add NEGINF in order to extend the coverage
 of the rea to whole graph.
 
@@ -517,5 +593,3 @@
 =head1 REFERENCES
 
 [1] http://www.dotpoint.com/xnumber/rpn_or_adl.htm
-
-

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrddump.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrddump.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrddump.txt	Sat Jul 13 21:26:27 2002
@@ -9,7 +9,7 @@
      rrdtool dump - dump the contents of an RRRRRRRRDDDD to XML format
 
 SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
-     rrrrrrrrddddttttoooooooollll dddduuuummmmpppp _f_i_l_e_n_a_m_e._r_r_d > _f_i_l_e_n_a_m_e._x_m_l
+     rrrrrrrrddddttttoooooooollll dddduuuummmmpppp _f_i_l_e_n_a_m_e_._r_r_d > _f_i_l_e_n_a_m_e_._x_m_l
 
 DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
      The dddduuuummmmpppp function prints the contents of an RRRRRRRRDDDD in human
@@ -19,7 +19,7 @@
      contents of an RRRRRRRRDDDD file in a somewhat more convenient
      manner.
 
-     _f_i_l_e_n_a_m_e._r_r_d
+     _f_i_l_e_n_a_m_e_._r_r_d
              The name of the RRRRRRRRDDDD you want to dump.
 
 AAAAUUUUTTTTHHHHOOOORRRR
@@ -60,7 +60,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      1
+2001-02-20             Last change: 1.0.33                      1
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdcgi.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdcgi.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdcgi.pod	Sat Jul 13 21:26:28 2002
@@ -2,6 +2,8 @@
 
 rrdcgi - create web pages containing RRD graphs based on templates
 
+=for html <div align="right"><a href="rrdcgi.pdf">PDF</a> version.</div>
+
 =head1 SYNOPSIS
 
 #!/path/to/B<rrdcgi> 
@@ -56,6 +58,15 @@
 sure that no problematic pathnames can be introduced through the 
 CGI interface.
 
+=item RRD::GETENV I<variable>
+
+Get the value of an environment variable.
+
+ <RRD::GETENV REMOTE_USER>
+
+might give you the name of the remote user given you are using
+some sort of access control on the directory
+
 =back
 
 =head2 Pass 2

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdtutorial.pod	Sat Jul 13 21:26:28 2002
@@ -2,6 +2,10 @@
 
 rrdtutorial - Alex van den Bogaerdt's RRDtool tutorial
 
+=for html <div align="right">Go <a href="rrdtutorial.es.html">Spanish</a></div> 
+
+=for html <div align="right"><a href="rrdtutorial.pdf">PDF</a> version.</div> 
+
 =head1 DESCRIPTION
 
 RRDtool is written by Tobias Oetiker <oetiker at ee.ethz.ch> with
@@ -106,7 +110,7 @@
 more important, some background information of how it works.
 
 You will need to know something about hexadecimal numbers. If you don't
-then start with reading "bin_dec_hex" before you continue here.
+then start with reading L<bin_dec_hex> before you continue here.
 
 =head2 Your first Round Robin Database
 
@@ -619,7 +623,7 @@
  600 5-minute samples:    2   days and 2 hours
  600 30-minute samples:  12.5 days
  600 2-hour samples:     50   days
- 600 1-day samples:     732   days
+ 732 1-day samples:     732   days
 
 These ranges are appended so the total amount of data kept is approximately
 797 days.  RRDtool stores the data differently, it doesn't start the "weekly"

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdlast.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdlast.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdlast.pod	Sat Jul 13 21:26:28 2002
@@ -2,6 +2,8 @@
 
 rrdtool last - Return the date of the last data sample in an B<RRD>
 
+=for html <div align="right"><a href="rrdlast.pdf">PDF</a> version.</div>
+
 =head1 SYNOPSIS
 
 B<rrdtool> B<last> I<filename>

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdrestore.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdrestore.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdrestore.html	Sat Jul 13 21:26:29 2002
@@ -1,67 +1,57 @@
 <HTML>
 <HEAD>
 <TITLE>rrdrestore</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-rrdtool restore - restore the contents of an <STRONG>RRD</STRONG> from its XML dump format
-
-<P>
+<H1><A NAME="name">NAME</A></H1>
+<P>rrdtool restore - restore the contents of an <STRONG>RRD</STRONG> from its XML dump format</P>
+<div align="right"><a href="rrdrestore.pdf">PDF</a> version.</div><P>
 <HR>
-<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
-<P>
-<STRONG>rrdtool</STRONG>  <STRONG>restore</STRONG>  <EM>filename.xml</EM>  <EM>filename.rrd</EM>
-
-[<STRONG>--range-check</STRONG>|<STRONG>-r</STRONG>]
-
-
-
+<H1><A NAME="synopsis">SYNOPSIS</A></H1>
+<P><STRONG>rrdtool</STRONG> <STRONG>restore</STRONG> <EM>filename.xml</EM> <EM>filename.rrd</EM>
+[<STRONG>--range-check</STRONG>|<STRONG>-r</STRONG>]</P>
 <P>
 <HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-The <STRONG>restore</STRONG> function reads the XML representation of an RRD and converts it into the
-native <STRONG>RRD</STRONG> format.
-
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>The <STRONG>restore</STRONG> function reads the XML representation of an RRD and converts
+it into the native <STRONG>RRD</STRONG> format.</P>
 <DL>
-<DT><STRONG><A NAME="item_filename">filename.xml</A></STRONG><DD>
-<P>
+<DT><STRONG><A NAME="item_filename%2Exml"><EM>filename.xml</EM></A></STRONG><BR>
+<DD>
 The name of the <STRONG>XML</STRONG> you want to restore.
-
-<DT><STRONG><A NAME="item_filename">filename.rrd</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_filename%2Errd"><EM>filename.rrd</EM></A></STRONG><BR>
+<DD>
 The name of the <STRONG>RRD</STRONG> to restore.
-
-<DT><STRONG><A NAME="item__range_check_r">--range-check|-r</A></STRONG><DD>
-<P>
-Make sure the values in the RRAs do not exceed the limits defined for the
-different datasources.
-
-</DL>
+<P></P>
+<DT><STRONG><A NAME="item_%2D%2Drange%2Dcheck%7C%2Dr"><STRONG>--range-check</STRONG>|<STRONG>-r</STRONG></A></STRONG><BR>
+<DD>
+Make sure the values in the RRAs do not exceed the limits defined for
+the different datasources.
+<P></P></DL>
 <P>
 <HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-Tobias Oetiker &lt;<A
-HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;</P>
+
 </BODY>
 
 </HTML>

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrddump.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrddump.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrddump.pod	Sat Jul 13 21:26:29 2002
@@ -2,6 +2,8 @@
 
 rrdtool dump - dump the contents of an B<RRD> to XML format
 
+=for html <div align="right"><a href="rrddump.pdf">PDF</a> version.</div>
+
 =head1 SYNOPSIS
 
 B<rrdtool> B<dump> I<filename.rrd> E<gt> I<filename.xml> 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rpntutorial.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rpntutorial.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rpntutorial.txt	Sat Jul 13 21:26:29 2002
@@ -60,7 +60,7 @@
 
 
 
-24/Nov/1999            Last change: 1.0.13                      1
+2001-02-20             Last change: 1.0.33                      1
 
 
 
@@ -77,8 +77,8 @@
      While compound expressions can look overly complex, they can
      be considered elegantly simple.  To quickly comprehend RPN
      expressions, you must know the the algorithm for evaluating
-     RPN expressions:  iterate searches from the left to the
-     right looking for an operator, when it's found, apply that
+     RPN expressions: iterate searches from the left to the right
+     looking for an operator, when it's found, apply that
      operator by popping the operator and some number of values
      (and by definition, not operators) off the stack.
 
@@ -126,7 +126,7 @@
 
 
 
-24/Nov/1999            Last change: 1.0.13                      2
+2001-02-20             Last change: 1.0.33                      2
 
 
 
@@ -192,7 +192,7 @@
 
 
 
-24/Nov/1999            Last change: 1.0.13                      3
+2001-02-20             Last change: 1.0.33                      3
 
 
 
@@ -258,7 +258,7 @@
 
 
 
-24/Nov/1999            Last change: 1.0.13                      4
+2001-02-20             Last change: 1.0.33                      4
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdtool.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdtool.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdtool.txt	Sat Jul 13 21:26:30 2002
@@ -32,7 +32,7 @@
      man page.
 
      For an introduction to the usage of rrdtool make sure you
-     check the _r_r_d_t_u_t_o_r_i_a_l manpage.
+     check the rrdtutorial manpage.
 
      FFFFUUUUNNNNCCCCTTTTIIIIOOOONNNNSSSS
 
@@ -41,26 +41,26 @@
      that the rrrrrrrrddddttttoooooooollll can be 'remote controlled' through a set of
      pipes. This saves a considerable amount of startup time when
      you plan to make rrrrrrrrddddttttoooooooollll do a lot of things quickly. Check
-     the section on the section on _R_e_m_o_t_e _C_o_n_t_r_o_l further down.
+     the section on the section on "Remote Control" further down.
+     There is also a number of language bindings for rrdtool
+     which allow you to use it directly from perl, python, tcl,
+     php, ...
 
      ccccrrrreeeeaaaatttteeee  Set up a new Round Robin Database (RRD). Check the
-             _r_r_d_c_r_e_a_t_e manpage.
+             rrdcreate manpage.
 
      uuuuppppddddaaaatttteeee  Store new data values into an RRD. Check the
-             _r_r_d_u_p_d_a_t_e manpage.
+             rrdupdate manpage.
 
      ggggrrrraaaapppphhhh   Create a graph from data stored in one or several
              RRD. Apart from generating graphs, data can also be
-             extracted to stdout. Check the _r_r_d_g_r_a_p_h manpage.
+             extracted to stdout. Check the rrdgraph manpage.
 
-     dddduuuummmmpppp    Dump the contents of an RRD in plain ASCII. In
-             connection with restore you can use it to transport
-             an rrd from one architecture to another.  Check the
-             _r_r_d_d_u_m_p manpage.
 
 
 
-24/Oct/1999            Last change: 1.0.13                      1
+
+2001-02-20             Last change: 1.0.33                      1
 
 
 
@@ -71,24 +71,29 @@
 
 
 
+     dddduuuummmmpppp    Dump the contents of an RRD in plain ASCII. In
+             connection with restore you can use it to transport
+             an rrd from one architecture to another.  Check the
+             rrddump manpage.
+
      rrrreeeessssttttoooorrrreeee Restore an RRD in XML format to a binary rrd ...
-             Check the _r_r_d_r_e_s_t_o_r_e manpage
+             Check the rrdrestore manpage
 
      ffffeeeettttcccchhhh   Get data for a certain time period from a RRD. The
              graph function uses fetch to retrieve its data from
-             an rrd. Check the _r_r_d_f_e_t_c_h manpage.
+             an rrd. Check the rrdfetch manpage.
 
-     ttttuuuunnnneeee    Alter setup of an RRD. Check the _r_r_d_t_u_n_e manpage.
+     ttttuuuunnnneeee    Alter setup of an RRD. Check the rrdtune manpage.
 
-     llllaaaasssstttt    Find last update time of an RRD. Check the _r_r_d_l_a_s_t
+     llllaaaasssstttt    Find last update time of an RRD. Check the rrdlast
              manpage.
 
      rrrrrrrrddddrrrreeeessssiiiizzzzeeee
              Change the size of individual RRAs ... Dangerous!
-             Check the _r_r_d_r_e_s_i_z_e manpage.
+             Check the rrdresize manpage.
 
      rrrrrrrrddddccccggggiiii  This is a standalone tool for producing rrd graphs
-             on the fly. Check the _r_r_d_c_g_i manpage.
+             on the fly. Check the rrdcgi manpage.
 
      HHHHOOOOWWWW DDDDOOOOEEEESSSS RRRRRRRRDDDDTTTTOOOOOOOOLLLL WWWWOOOORRRRKKKK????
 
@@ -118,15 +123,10 @@
              setting up an Round Robin Database (RRRRRRRRDDDD), you can
              define at which interval this consolidation should
              occur, and what consolidation function (CCCCFFFF)
-             (average, minimum, maximum, total, last) should be
-             used to build the consolidated values (see
-             rrdcreate). You can define any number of different
-             consolidation setups within one RRRRRRRRDDDD. They will all
-             be maintained on the fly when new data is loaded
 
 
 
-24/Oct/1999            Last change: 1.0.13                      2
+2001-02-20             Last change: 1.0.33                      2
 
 
 
@@ -137,6 +137,11 @@
 
 
 
+             (average, minimum, maximum, total, last) should be
+             used to build the consolidated values (see
+             rrdcreate). You can define any number of different
+             consolidation setups within one RRRRRRRRDDDD. They will all
+             be maintained on the fly when new data is loaded
              into the RRRRRRRRDDDD.
 
      Round Robin Archives
@@ -177,22 +182,17 @@
              data is available when a value has to be written to
              the RRRRRRRRDDDD. Data acquisition may not be possible for
              one reason or an other. The rrrrrrrrddddttttoooooooollll handles these
-             situations by storing an *_U_N_K_N_O_W_N* value into the
-             database. The value '*_U_N_K_N_O_W_N*' is supported through
+             situations by storing an _*_U_N_K_N_O_W_N_* value into the
+             database. The value '_*_U_N_K_N_O_W_N_*' is supported through
              all the functions of the database. When
-             consolidating the amount of *_U_N_K_N_O_W_N* data is
+             consolidating the amount of _*_U_N_K_N_O_W_N_* data is
              accumulated and when a new consolidated value is
              ready to be written to its Round Robin Archive (RRRRRRRRAAAA)
              a validity check is performed to make sure that the
-             percentage of unknown data in the new value is below
-             a configurable level. If so, an *_U_N_K_N_O_W_N* value will
-             be written to the RRRRRRRRAAAA.
-
 
 
 
-
-24/Oct/1999            Last change: 1.0.13                      3
+2001-02-20             Last change: 1.0.33                      3
 
 
 
@@ -203,12 +203,16 @@
 
 
 
+             percentage of unknown data in the new value is below
+             a configurable level. If so, an _*_U_N_K_N_O_W_N_* value will
+             be written to the RRRRRRRRAAAA.
+
      Graphing
              The rrrrrrrrddddttttoooooooollll also allows one to generate reports in
              numerical and graphical form based on the data
              stored in one or several RRRRRRRRDDDDs. The graphing feature
              is fully configurable. Size, color and contents of
-             the graph can be defined freely. Check the _r_r_d_g_r_a_p_h
+             the graph can be defined freely. Check the rrdgraph
              manpage for more information on this.
 
      RRRREEEEMMMMOOOOTTTTEEEE CCCCOOOONNNNTTTTRRRROOOOLLLL
@@ -219,12 +223,12 @@
      (mrtg is one example) through a set of pipes. Over the pipes
      rrrrrrrrddddttttoooooooollll accepts the same arguments as on the command line.
      When a command is completed, rrdtool will print the string
-     'OK', followed by timing information of the form uuuu::::_u_s_e_r_t_i_m_e
-     ssss::::_s_y_s_t_e_m_t_i_m_e both values are running totals of seconds since
-     rrdtool was started. If an error occurs, a line of the form
-     'ERROR: _D_e_s_c_r_i_p_t_i_o_n _o_f _e_r_r_o_r' will be printed. rrrrrrrrddddttttoooooooollll will
-     not abort if possible, but follow the ERROR line with an OK
-     line.
+     '`OK'', followed by timing information of the form
+     uuuu::::_u_s_e_r_t_i_m_e ssss::::_s_y_s_t_e_m_t_i_m_e both values are running totals of
+     seconds since rrdtool was started. If an error occurs, a
+     line of the form '`ERROR:' _D_e_s_c_r_i_p_t_i_o_n _o_f _e_r_r_o_r' will be
+     printed. rrrrrrrrddddttttoooooooollll will not abort if possible, but follow the
+     ERROR line with an OK line.
 
 SSSSEEEEEEEE AAAALLLLSSSSOOOO
      rrdcreate, rrdupdate, rrdgraph, rrddump, rrdfetch, rrdtune,
@@ -254,77 +258,7 @@
 
 
 
-
-
-
-
-24/Oct/1999            Last change: 1.0.13                      4
-
-
-
-
-
-
-rrdtool                                                RRDTOOL(1)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-24/Oct/1999            Last change: 1.0.13                      5
-
-
-
+2001-02-20             Last change: 1.0.33                      4
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/cdeftutorial.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/cdeftutorial.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/cdeftutorial.txt	Sat Jul 13 21:26:30 2002
@@ -12,7 +12,7 @@
      YYYYoooouuuu pppprrrroooovvvviiiiddddeeee aaaa qqqquuuueeeessssttttiiiioooonnnn aaaannnndddd IIII wwwwiiiillllllll ttttrrrryyyy ttttoooo pppprrrroooovvvviiiiddddeeee aaaannnn aaaannnnsssswwwweeeerrrr
      iiiinnnn tttthhhheeee nnnneeeexxxxtttt rrrreeeelllleeeeaaaasssseeee. NNNNoooo ffffeeeeeeeeddddbbbbaaaacccckkkk eeeeqqqquuuuaaaallllssss nnnnoooo cccchhhhaaaannnnggggeeeessss!!!!
 
-     _A_d_d_i_t_i_o_n_s _t_o _t_h_i_s _d_o_c_u_m_e_n_t _a_r_e _a_l_s_o _w_e_l_c_o_m_e.
+     _A_d_d_i_t_i_o_n_s _t_o _t_h_i_s _d_o_c_u_m_e_n_t _a_r_e _a_l_s_o _w_e_l_c_o_m_e_.
 
      Alex van den Bogaerdt <alex at ergens.op.het.net>
 
@@ -34,7 +34,7 @@
      MMMMoooorrrreeee rrrreeeeaaaaddddiiiinnnngggg
 
      If you have difficulties with the way I try to explain them
-     please read Steve Rader's the _r_p_n_t_u_t_o_r_i_a_l manpage. It may
+     please read Steve Rader's the rpntutorial manpage. It may
      help you understand how this all works.
 
 WWWWhhhhaaaatttt aaaarrrreeee CCCCDDDDEEEEFFFFssss ????
@@ -60,7 +60,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      1
+2001-02-20             Last change: 1.0.33                      1
 
 
 
@@ -88,7 +88,7 @@
      Note that variable in the CDEF (inbits) must not be the same
      as the variable (inbytes) in the DEF!
 
-RRRRPPPPNNNN-eeeexxxxpppprrrreeeessssssssiiiioooonnnnssss
+RRRRPPPPNNNN----eeeexxxxpppprrrreeeessssssssiiiioooonnnnssss
      RPN is short-hand for Reverse Polish Notation. It works as
      follows.  You put the variables or numbers on a stack. You
      also put operations (things-to-do) on the stack and this
@@ -126,7 +126,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      2
+2001-02-20             Last change: 1.0.33                      2
 
 
 
@@ -152,7 +152,7 @@
         y = A - B  -->  y=minus(A,B)  -->  CDEF:y=A,B,-
 
      This is not very intuitive (at least most people don't think
-     so). For the function _f(A,B) you reverse the position of "f"
+     so). For the function f(A,B) you reverse the position of "f"
      but you do not reverse the order of the variables.
 
 CCCCoooonnnnvvvveeeerrrrttttiiiinnnngggg yyyyoooouuuurrrr wwwwiiiisssshhhheeeessss ttttoooo RRRRPPPPNNNN
@@ -169,7 +169,7 @@
 
         router1.rrd with link1in link2in
         router2.rrd with link1in link2in
-        router3.rrd with link1.in
+        router3.rrd with link1in link2in
 
      Suppose you would like to add up all these counters, except
      for link2in inside router2.rrd. You need to do:
@@ -187,12 +187,12 @@
 
      As a mathmatical function, this could be written:
 
-     add(router1.rrd:link1in , router1.rrd:link2in ,
+     `add(router1.rrd:link1in , router1.rrd:link2in ,
      router2.rrd:link1in , router3.rrd:link1in ,
 
 
 
-24/Oct/1999            Last change: 1.0.13                      3
+2001-02-20             Last change: 1.0.33                      3
 
 
 
@@ -203,7 +203,7 @@
 
 
 
-     router3.rrd:link2.in)
+     router3.rrd:link2.in)'
 
      With RRDtool and RPN, first, define the inputs:
 
@@ -213,7 +213,7 @@
         DEF:d=router3.rrd:link1in:AVERAGE
         DEF:e=router3.rrd:link2in:AVERAGE
 
-     Now, the mathematical function becomes: add(a,b,c,d,e)
+     Now, the mathematical function becomes: `add(a,b,c,d,e)'
 
      In RPN, there's no operator that sums more than two values
      so you need to do several additions. You add a and b, add c
@@ -229,13 +229,13 @@
 
         ( ( ( (a+b) + c) + d) + e) >
 
-     This is in RPN:  CDEF:result=a,b,+,c,+,d,+,e,+
+     This is in RPN:  `CDEF:result=a,b,+,c,+,d,+,e,+'
 
      This is correct but it can be made more clear to humans. It
      does not matter if you add a to b and then add c to the
      result or first add b to c and then add a to the result.
      This makes it possible to rewrite the RPN into
-     CDEF:result=a,b,c,d,e,+,+,+,+ which is evaluatated
+     `CDEF:result=a,b,c,d,e,+,+,+,+' which is evaluatated
      differently:
 
         push value of variable a on the stack: a
@@ -252,13 +252,13 @@
         push operator + on the stack:          a R +
         and process it:                        S         (where S == a+R)
 
-     As you can see the RPN expression a,b,c,d,e,+,+,+,+,+ will
-     evaluate in ((((d+e)+c)+b)+a) and it has the same outcome as
-     a,b,+,c,+,d,+,e,+ According to Steve Rader this is called
+     As you can see the RPN expression `a,b,c,d,e,+,+,+,+,+' will
+     evaluate in `((((d+e)+c)+b)+a)' and it has the same outcome
+     as `a,b,+,c,+,d,+,e,+' According to Steve Rader this is
 
 
 
-24/Oct/1999            Last change: 1.0.13                      4
+2001-02-20             Last change: 1.0.33                      4
 
 
 
@@ -269,12 +269,12 @@
 
 
 
-     the commutative law of addition but you may forget this
-     right away, as long as you remember what it represents.
+     called the commutative law of addition but you may forget
+     this right away, as long as you remember what it represents.
 
      Now look at an expression that contains a multiplication:
 
-     First in normal math: let result = a+b*c. In this case you
+     First in normal math: `let result = a+b*c'. In this case you
      can't choose the order yourself, you have to start with the
      multiplication and then add a to it. You may alter the
      position of b and c, you may not alter the position of a and
@@ -283,14 +283,14 @@
      You have to take this in consideration when converting this
      expression into RPN. Read it as: "Add the outcome of b*c to
      a" and then it is easy to write the RPN expression:
-     result=a,b,c,*,+ Another expression that would return the
-     same: result=b,c,*,a,+
+     `result=a,b,c,*,+' Another expression that would return the
+     same: `result=b,c,*,a,+'
 
      In normal math, you may encounter something like "a*(b+c)"
      and this can also be converted into RPN. The parenthesis
      just tell you to first add b and c, and then multiply a with
      the result. Again, now it is easy to write it in RPN:
-     result=a,b,c,+,*. Note that this is very similar to one of
+     `result=a,b,c,+,*'. Note that this is very similar to one of
      the expressions in the previous paragraph, only the
      multiplication and the addition changed places.
 
@@ -324,7 +324,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      5
+2001-02-20             Last change: 1.0.33                      5
 
 
 
@@ -348,7 +348,7 @@
         counter value    resulting rate
         10000
         10060            1; (10060-10000)/60 == 1
-        10120            1; (10060-10000)/60 == 1
+        10120            1; (10120-10060)/60 == 1
         unknown          unknown; you don't know the last value
         10240            unknown; you don't know the previous value
         10300            1; (10300-10240)/60 == 1
@@ -369,7 +369,7 @@
      As you have read in the previous chapter, entries in an RRA
      can be set to the unknown value. If you do calculations with
      this type of value, the result has to be unknown too. This
-     means that an expression such as result=a,b,+ will be
+     means that an expression such as `result=a,b,+' will be
      unknown if either a or b is unknown.  It would be wrong to
      just ignore the unknown value and return the value of the
      other parameter. By doing so, you would assume "unknown"
@@ -390,7 +390,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      6
+2001-02-20             Last change: 1.0.33                      6
 
 
 
@@ -456,7 +456,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      7
+2001-02-20             Last change: 1.0.33                      7
 
 
 
@@ -496,15 +496,17 @@
         if true  return a
         if false return b
 
-     In RPN:  result=x,a,b,IF where "x" is either true or false.
+     In RPN:  `result=x,a,b,IF' where "x" is either true or
+     false.
 
      Now we have to fill in "x", this should be the "(value is
-     unknown)" part and this is in RPN:  result=value,UN
+     unknown)" part and this is in RPN:  `result=value,UN'
 
-     We now combine them: result=value,UN,a,b,IF and when we fill
-     in the appropriate things for "a" and "b" we're finished:
+     We now combine them: `result=value,UN,a,b,IF' and when we
+     fill in the appropriate things for "a" and "b" we're
+     finished:
 
-     CDEF:result=value,UN,0,value,IF
+     `CDEF:result=value,UN,0,value,IF'
 
      You may want to read Steve Raders RPN guide if you have
      difficulties with the way I explained this last example.
@@ -520,9 +522,7 @@
 
 
 
-
-
-24/Oct/1999            Last change: 1.0.13                      8
+2001-02-20             Last change: 1.0.33                      8
 
 
 
@@ -588,7 +588,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      9
+2001-02-20             Last change: 1.0.33                      9
 
 
 
@@ -636,7 +636,7 @@
         substitute b         --> TIME,937521357,GT,value,value,UN,0,value,IF,IF
 
      We end up with:
-     CDEF:result=TIME,937521357,GT,value,value,UN,0,value,IF,IF
+     `CDEF:result=TIME,937521357,GT,value,value,UN,0,value,IF,IF'
 
      This looks very complex however as you can see it was not
      too hard to come up with.
@@ -654,7 +654,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                     10
+2001-02-20             Last change: 1.0.33                     10
 
 
 
@@ -695,6 +695,61 @@
          CDEF:result=number,100000,GT,100000,number,IF
 
 
+     EEEExxxxaaaammmmpppplllleeee:::: wwwwoooorrrrkkkkiiiinnnngggg oooonnnn aaaa cccceeeerrrrttttaaaaiiiinnnn ttttiiiimmmmeeee ssssppppaaaannnn
+
+     If you want a graph that spans a few weeks, but would only
+     want to see some routers data for one week, you need to
+     "hide" the rest of the time frame. Don't ask me when this
+     would be useful, it's just here for the example :)
+
+     We need to compare the time stamp to a begin date and an end
+     date.  Comparing isn't difficult:
+
+             TIME,begintime,GE
+             TIME,endtime,LE
+
+     These two parts of the CDEF produce either 0 for false or 1
+     for true.  We can now check if they are both 0 (or 1) using
+     a few IF statements but, as Wataru Satoh pointed out, we can
+     use the "*" or "+" functions as locical AND and locical OR.
+
+     For "*", the result will be zero (false) if either one of
+     the two operators is zero.  For "+", the result will only be
+     false (0) when two false (0) operators will be added.
+     Warning: *any* number not equal to 0 will be considered
+
+
+
+2001-02-20             Last change: 1.0.33                     11
+
+
+
+
+
+
+rrdtool                                           CDEFTUTORIAL(1)
+
+
+
+     "true". This means that, for instance, "-1,1,+" (which
+     should be "true or true") will become FALSE ...  In other
+     words, use "+" only if you know for sure that you have
+     positive numbers (or zero) only.
+
+     Let's compile the complete CDEF:
+
+             DEF:ds0=router1.rrd:AVERAGE
+             CDEF:ds0modified=TIME,begintime,GE,TIME,endtime,LE,*,UNKN,ds0,IF
+
+     This will return the value of ds0 if both comparisons return
+     true. You could also do it the other way around:
+
+             DEF:ds0=router1.rrd:AVERAGE
+             CDEF:ds0modified=TIME,begintime,LT,TIME,endtime,GT,+,UNKN,ds0,IF
+
+     This will return an UNKNOWN if either comparison returns
+     true.
+
      EEEExxxxaaaammmmpppplllleeee:::: YYYYoooouuuu ssssuuuussssppppeeeecccctttt ttttoooo hhhhaaaavvvveeee pppprrrroooobbbblllleeeemmmmssss aaaannnndddd wwwwaaaannnntttt ttttoooo sssseeeeeeee
      uuuunnnnkkkknnnnoooowwwwnnnn ddddaaaattttaaaa....
 
@@ -718,29 +773,29 @@
      users1..users4 will show up as a gap in your graph. You want
      to modify this to show a bright red line, not a gap.
 
+     Define an extra CDEF that is unknown if all is okay and is
+     infinite if there is an unknown value:
 
+         CDEF:wrongdata=allusers,UN,INF,UNKN,IF
 
-24/Oct/1999            Last change: 1.0.13                     11
+     "allusers,UN" will evaluate to either true or false, it is
+     the (x) part of the "IF" function and it checks if allusers
+     is unknown.  The (y) part of the "IF" function is set to
+     "INF" (which means infinity) and the (z) part of the
+     function returns "UNKN".
 
 
 
+2001-02-20             Last change: 1.0.33                     12
 
 
 
-rrdtool                                           CDEFTUTORIAL(1)
 
 
 
-     Define an extra CDEF that is unknown if all is okay and is
-     infinite if there is an unknown value:
+rrdtool                                           CDEFTUTORIAL(1)
 
-         CDEF:wrongdata=allusers,UN,INF,UNKN,IF
 
-     "allusers,UN" will evaluate to either true or false, it is
-     the (x) part of the "IF" function and it checks if allusers
-     is unknown.  The (y) part of the "IF" function is set to
-     "INF" (which means infinity) and the (z) part of the
-     function returns "UNKN".
 
      The logic is: if (allusers == unknown) then return INF else
      return UNKN.
@@ -783,31 +838,31 @@
      X-axis and has infinite height it will effectively overwrite
      the STACKed parts.
 
+     You could combine the two CDEF lines into one (we don't use
+     "allusers") if you like.  But there are good reasons for
+     writting two CDEFS:
 
+     +o   It improves the readability of the script
 
+     +o   It can be used inside GPRINT to display the total number
+         of users
 
-24/Oct/1999            Last change: 1.0.13                     12
+     If you choose to combine them, you can substitute the
+     "allusers" in the second CDEF with the part after the equal
 
 
 
+2001-02-20             Last change: 1.0.33                     13
 
 
 
-rrdtool                                           CDEFTUTORIAL(1)
 
 
 
-     You could combine the two CDEF lines into one (we don't use
-     "allusers") if you like.  But there are good reasons for
-     writting two CDEFS:
+rrdtool                                           CDEFTUTORIAL(1)
 
-     +o   It improves the readability of the script
 
-     +o   It can be used inside GPRINT to display the total number
-         of users
 
-     If you choose to combine them, you can substitute the
-     "allusers" in the second CDEF with the part after the equal
      sign from the first line:
 
         CDEF:wrongdata=users1,users2,users3,users4,+,+,+,UN,INF,UNKN,IF
@@ -848,32 +903,31 @@
      correct. It is close enough for this purpose and it saves a
      calculation.
 
+     CCCChhhhaaaannnnggggiiiinnnngggg uuuunnnnkkkknnnnoooowwwwnnnn iiiinnnnttttoooo zzzzeeeerrrroooo
 
+        rrdtool graph demo.gif --title="Demo Graph" \
+           DEF:idat1=interface1.rrd:ds0:AVERAGE \
+           DEF:idat2=interface2.rrd:ds0:AVERAGE \
+           DEF:odat1=interface1.rrd:ds1:AVERAGE \
+           DEF:odat2=interface2.rrd:ds1:AVERAGE \
+           CDEF:agginput=idat1,UN,0,idat1,IF,idat2,UN,0,idat2,IF,+,8,* \
+           CDEF:aggoutput=odat1,UN,0,odat1,IF,odat2,UN,0,odat2,IF,+,8,* \
+           AREA:agginput#00cc00:Input Aggregate \
+           LINE1:aggoutput#0000FF:Output Aggregate
 
 
 
-24/Oct/1999            Last change: 1.0.13                     13
-
 
+2001-02-20             Last change: 1.0.33                     14
 
 
 
 
-rrdtool                                           CDEFTUTORIAL(1)
 
 
+rrdtool                                           CDEFTUTORIAL(1)
 
-     CCCChhhhaaaannnnggggiiiinnnngggg uuuunnnnkkkknnnnoooowwwwnnnn iiiinnnnttttoooo zzzzeeeerrrroooo
 
-        rrdtool graph demo.gif --title="Demo Graph" \
-           DEF:idat1=interface1.rrd:ds0:AVERAGE \
-           DEF:idat2=interface2.rrd:ds0:AVERAGE \
-           DEF:odat1=interface1.rrd:ds1:AVERAGE \
-           DEF:odat2=interface2.rrd:ds1:AVERAGE \
-           CDEF:agginput=idat1,UN,0,idat1,IF,idat2,UN,0,idat2,IF,+,8,* \
-           CDEF:aggoutput=odat1,UN,0,odat1,IF,odat2,UN,0,odat2,IF,+,8,* \
-           AREA:agginput#00cc00:Input Aggregate \
-           LINE1:aggoutput#0000FF:Output Aggregate
 
      These two CDEFs are built from several functions. It helps
      to split them when viewing what they do.  Starting with the
@@ -915,31 +969,31 @@
      This demo demonstrates two ways to use infinity. It is a bit
      tricky to see what happens in the "background" CDEF.
 
+        "val4,POP,TIME,7200,%,3600,LE,INF,UNKN,IF"
 
+     This RPN takes the value of "val4" as input and then
+     immediately removes it from the stack using "POP". The stack
+     is now empty but as a side result we now know the time that
+     this sample was taken.  This time is put on the stack by the
+     "TIME" function.
 
+     "TIME,7200,%" takes the modulo of time and 7200 (which is
+     two hours).  The resulting value on the stack will be a
+     number in the range from 0 to 7199.
 
-24/Oct/1999            Last change: 1.0.13                     14
 
 
 
+2001-02-20             Last change: 1.0.33                     15
 
 
 
-rrdtool                                           CDEFTUTORIAL(1)
 
 
 
-        "val4,POP,TIME,7200,%,3600,LE,INF,UNKN,IF"
+rrdtool                                           CDEFTUTORIAL(1)
 
-     This RPN takes the value of "val4" as input and then
-     immediately removes it from the stack using "POP". The stack
-     is now empty but as a side result we now know the time that
-     this sample was taken.  This time is put on the stack by the
-     "TIME" function.
 
-     "TIME,7200,%" takes the modulo of time and 7200 (which is
-     two hours).  The resulting value on the stack will be a
-     number in the range from 0 to 7199.
 
      For people who don't know the modulo function: it is the
      remainder after an integer division. If you divide 16 by 3,
@@ -974,27 +1028,13 @@
      variable and place a negative sign before it:
      "CDEF:wipeout2=wipeout,-1,*"
 
-     =head1 Out of ideas for now
-
+OOOOuuuutttt ooooffff iiiiddddeeeeaaaassss ffffoooorrrr nnnnoooowwww
      This document was created from questions asked by either
      myself or by other people on the list. Please let me know if
      you find errors in it or if you have trouble understanding
      it. If you think there should be an addition, mail me:
      <alex at ergens.op.het.net>
 
-
-
-24/Oct/1999            Last change: 1.0.13                     15
-
-
-
-
-
-
-rrdtool                                           CDEFTUTORIAL(1)
-
-
-
      Remember: NNNNoooo ffffeeeeeeeeddddbbbbaaaacccckkkk eeeeqqqquuuuaaaallllssss nnnnoooo cccchhhhaaaannnnggggeeeessss!!!!
 
 SSSSEEEEEEEE AAAALLLLSSSSOOOO
@@ -1010,113 +1050,7 @@
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-24/Oct/1999            Last change: 1.0.13                     16
-
-
-
-
-
-
-rrdtool                                           CDEFTUTORIAL(1)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-24/Oct/1999            Last change: 1.0.13                     17
-
-
-
+2001-02-20             Last change: 1.0.33                     16
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rpntutorial.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rpntutorial.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rpntutorial.pod	Sat Jul 13 21:26:30 2002
@@ -2,6 +2,8 @@
 
 rpntutorial - Reading RRDTtool RPN Expressions by Steve Rader
 
+=for html <div align="right"><a href="rpntutorial.pdf">PDF</a> version.</div>
+
 =head1 DESCRIPTION
 
 This tutorial should help you get to grips with rrdtool RPN expressions

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/cdeftutorial.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/cdeftutorial.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/cdeftutorial.pod	Sat Jul 13 21:26:31 2002
@@ -2,6 +2,8 @@
 
 cdeftutorial - Alex van den Bogaerdt's CDEF tutorial
 
+=for html <div align="right"><a href="cdeftutorial.pdf">PDF</a> version.</div> 
+
 =head1 DESCRIPTION
 
 B<You provide a question and I will try to provide an answer in the next
@@ -164,7 +166,7 @@
 
    router1.rrd with link1in link2in
    router2.rrd with link1in link2in
-   router3.rrd with link1.in
+   router3.rrd with link1in link2in
 
 Suppose you would like to add up all these counters, except for link2in
 inside router2.rrd. You need to do:
@@ -299,7 +301,7 @@
    counter value    resulting rate
    10000
    10060            1; (10060-10000)/60 == 1
-   10120            1; (10060-10000)/60 == 1
+   10120            1; (10120-10060)/60 == 1
    unknown          unknown; you don't know the last value
    10240            unknown; you don't know the previous value
    10300            1; (10300-10240)/60 == 1
@@ -585,6 +587,45 @@
     CDEF:result=number,100000,GT,UNKN,number,IF
     CDEF:result=number,100000,GT,100000,number,IF
 
+=head2 Example: working on a certain time span
+
+If you want a graph that spans a few weeks, but would only want to
+see some routers data for one week, you need to "hide" the rest of
+the time frame. Don't ask me when this would be useful, it's just
+here for the example :)
+
+We need to compare the time stamp to a begin date and an end date.
+Comparing isn't difficult:
+
+	TIME,begintime,GE
+	TIME,endtime,LE
+
+These two parts of the CDEF produce either 0 for false or 1 for true.
+We can now check if they are both 0 (or 1) using a few IF statements
+but, as Wataru Satoh pointed out, we can use the "*" or "+" functions
+as locical AND and locical OR.
+
+For "*", the result will be zero (false) if either one of the two
+operators is zero.  For "+", the result will only be false (0) when
+two false (0) operators will be added.  Warning: *any* number not
+equal to 0 will be considered "true". This means that, for instance,
+"-1,1,+" (which should be "true or true") will become FALSE ...
+In other words, use "+" only if you know for sure that you have positive
+numbers (or zero) only.
+
+Let's compile the complete CDEF:
+
+	DEF:ds0=router1.rrd:AVERAGE
+	CDEF:ds0modified=TIME,begintime,GE,TIME,endtime,LE,*,UNKN,ds0,IF
+
+This will return the value of ds0 if both comparisons return true. You
+could also do it the other way around:
+
+	DEF:ds0=router1.rrd:AVERAGE
+	CDEF:ds0modified=TIME,begintime,LT,TIME,endtime,GT,+,UNKN,ds0,IF
+
+This will return an UNKNOWN if either comparison returns true.
+
 =head2 Example: You suspect to have problems and want to see unknown data.
 
 Suppose you add up the number of active users on several terminal servers.

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdtool.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdtool.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdtool.pod	Sat Jul 13 21:26:31 2002
@@ -2,6 +2,8 @@
 
 rrdtool - round robin database tool
 
+=for html <div align="right"><a href="rrdtool.pdf">PDF</a> version.</div>
+
 =head1 SYNOPSIS
 
 B<rrdtool> B<-> | I<function>
@@ -29,11 +31,14 @@
 
 =head2 FUNCTIONS
 
-While the man pages talk of command line switches you have to set in order to
-make B<rrdtool> work it is important to note that the B<rrdtool> can be
-'remote controlled' through a set of pipes. This saves a considerable
-amount of startup time when you plan to make B<rrdtool> do a lot of
-things quickly. Check the section on L<"Remote Control"> further down.
+While the man pages talk of command line switches you have to set in
+order to make B<rrdtool> work it is important to note that the
+B<rrdtool> can be 'remote controlled' through a set of pipes. This
+saves a considerable amount of startup time when you plan to make
+B<rrdtool> do a lot of things quickly. Check the section on L<"Remote
+Control"> further down. There is also a number of language bindings
+for rrdtool which allow you to use it directly from perl, python, tcl,
+php, ...
 
 =over 8
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdupdate.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdupdate.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdupdate.txt	Sat Jul 13 21:26:32 2002
@@ -9,7 +9,7 @@
      rrdtool update - Store a new set of values into the rrd
 
 SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
-     rrrrrrrrddddttttoooooooollll uuuuppppddddaaaatttteeee _f_i_l_e_n_a_m_e [--------tttteeeemmmmppppllllaaaatttteeee|----tttt _d_s-_n_a_m_e[::::_d_s-_n_a_m_e]...]
+     rrrrrrrrddddttttoooooooollll uuuuppppddddaaaatttteeee _f_i_l_e_n_a_m_e [--------tttteeeemmmmppppllllaaaatttteeee|----tttt _d_s_-_n_a_m_e[::::_d_s_-_n_a_m_e]...]
      NNNN|_t_i_m_e_s_t_a_m_p::::_v_a_l_u_e[::::_v_a_l_u_e...]
      [_t_i_m_e_s_t_a_m_p::::_v_a_l_u_e[::::_v_a_l_u_e...] ...]
 
@@ -21,7 +21,7 @@
      _f_i_l_e_n_a_m_e
              The name of the RRRRRRRRDDDD you want to update.
 
-     --------tttteeeemmmmppppllllaaaatttteeee|-tttt _d_s-_n_a_m_e[::::_d_s-_n_a_m_e]...
+     --------tttteeeemmmmppppllllaaaatttteeee|----tttt _d_s_-_n_a_m_e[::::_d_s_-_n_a_m_e]...
              by default, the update function expects the data
              input in the order, the data sources are defined in
              the RRD. This is not very error resistant, as you
@@ -40,8 +40,8 @@
              the update time is set to be the current time.
              Negative time values are subtracted from the current
              time.  Getting the timing right to the second is
-             especially important when you are working with
-             data-sources of type CCCCOOOOUUUUNNNNTTTTEEEERRRR, DDDDEEEERRRRIIIIVVVVEEEE or AAAABBBBSSSSOOOOLLLLUUUUTTTTEEEE.
+             especially important when you are working with data-
+             sources of type CCCCOOOOUUUUNNNNTTTTEEEERRRR, DDDDEEEERRRRIIIIVVVVEEEE or AAAABBBBSSSSOOOOLLLLUUUUTTTTEEEE.
 
              The remaining elements of the argument are DS
              updates. The order of this list is the same as the
@@ -60,7 +60,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      1
+2001-02-20             Last change: 1.0.33                      1
 
 
 
@@ -72,16 +72,16 @@
 
 
 EEEEXXXXAAAAMMMMPPPPLLLLEEEE
-     rrdtool update demo1.rrd N:3.44:3.15:U:23
+     `rrdtool update demo1.rrd N:3.44:3.15:U:23'
 
      Update the database file demo1.rrd with 3 known and one
-     *_U_N_K_N_O_W_N* value. Use the current time as the update time.
+     _*_U_N_K_N_O_W_N_* value. Use the current time as the update time.
 
-     rrdtool update demo2.rrd 887457267:U 887457521:22
-     88745790:2.7
+     `rrdtool update demo2.rrd 887457267:U 887457521:22
+     88745790:2.7'
 
      Update the database file demo2.rrd which expects data from a
-     single data-source, three times. First with an *_U_N_K_N_O_W_N*
+     single data-source, three times. First with an _*_U_N_K_N_O_W_N_*
      value then with two normal readings. The update interval
      seems to be around 300 seconds.
 
@@ -126,7 +126,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      2
+2001-02-20             Last change: 1.0.33                      2
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdrestore.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdrestore.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdrestore.txt	Sat Jul 13 21:26:32 2002
@@ -10,19 +10,19 @@
      XML dump format
 
 SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
-     rrrrrrrrddddttttoooooooollll rrrreeeessssttttoooorrrreeee _f_i_l_e_n_a_m_e._x_m_l _f_i_l_e_n_a_m_e._r_r_d [--------rrrraaaannnnggggeeee----cccchhhheeeecccckkkk|----rrrr]
+     rrrrrrrrddddttttoooooooollll rrrreeeessssttttoooorrrreeee _f_i_l_e_n_a_m_e_._x_m_l _f_i_l_e_n_a_m_e_._r_r_d [--------rrrraaaannnnggggeeee----cccchhhheeeecccckkkk|----rrrr]
 
 DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
      The rrrreeeessssttttoooorrrreeee function reads the XML representation of an RRD
      and converts it into the native RRRRRRRRDDDD format.
 
-     _f_i_l_e_n_a_m_e._x_m_l
+     _f_i_l_e_n_a_m_e_._x_m_l
              The name of the XXXXMMMMLLLL you want to restore.
 
-     _f_i_l_e_n_a_m_e._r_r_d
+     _f_i_l_e_n_a_m_e_._r_r_d
              The name of the RRRRRRRRDDDD to restore.
 
-     --------rrrraaaannnnggggeeee----cccchhhheeeecccckkkk|-rrrr
+     --------rrrraaaannnnggggeeee----cccchhhheeeecccckkkk|----rrrr
              Make sure the values in the RRAs do not exceed the
              limits defined for the different datasources.
 
@@ -60,7 +60,7 @@
 
 
 
-24/Oct/1999            Last change: 1.0.13                      1
+2001-02-20             Last change: 1.0.33                      1
 
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/Makefile.am
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/Makefile.am	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/Makefile.am	Sat Jul 13 21:26:32 2002
@@ -1,23 +1,24 @@
 ## Process this file with automake to produce Makefile.in
 
-SUFFIXES = .pod .1 .man .html .txt .pm
+SUFFIXES = .pod .1 .man .html .txt .pm .pdf
 
 #AUTOMAKE_OPTIONS        =  foreign
 
 #ACLOCAL_M4 = $(top_srcdir)/config/aclocal.m4
 
-CLEANFILES = *.1 *.html *.txt *-dircache *.pm
+CLEANFILES = *.1 *.html *.txt *-dircache *.pm *.pdf *~ core *itemcache *.rej *.orig
 
-POD = rrdtool.pod rrdlast.pod rrdcreate.pod rrdupdate.pod \
+POD = rrdtool.pod rrdlast.pod rrdcreate.pod rrdupdate.pod  rrdtutorial.es.pod \
 	cdeftutorial.pod rpntutorial.pod rrdgraph.pod  bin_dec_hex.pod \
 	rrdfetch.pod rrdrestore.pod rrddump.pod rrdtune.pod rrdresize.pod \
-	rrdcgi.pod rrdtutorial.pod
+	rrdcgi.pod rrdtutorial.pod rrdinfo.pod
 
 PMP = RRDs.pm RRDp.pm
 
 MAN = $(POD:.pod=.1) $(PMP:.pm=.1) 
 TXT = $(MAN:.1=.txt)
 HTML = $(POD:.pod=.html) $(PMP:.pm=.html) 
+PDF = $(MAN:.1=.pdf)
 
 # what should go into the distribution
 EXTRA_DIST= $(POD) $(HTML) $(TXT)
@@ -36,7 +37,10 @@
 	pod2man --release=$(VERSION) --center=rrdtool $<  > $@
 
 .1.txt:
-	nroff -man -Tlp $< > $@
+	@NROFF@ -man -Tlp $< > $@
+
+.1.pdf:
+	@TROFF@ -man $< | ps2pdf - $@
 
 .pm.html .pod.html .pl.html:
 	pod2html --infile=$< --outfile=$@ --noindex --htmlroot=. --podpath=. --title=$*
@@ -54,3 +58,6 @@
 html: $(HTML)
 
 txt: $(TXT)
+
+pdf: $(PDF)
+

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdupdate.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdupdate.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdupdate.pod	Sat Jul 13 21:26:33 2002
@@ -2,6 +2,8 @@
 
 rrdtool update - Store a new set of values into the rrd
 
+=for html <div align="right"><a href="rrdupdate.pdf">PDF</a> version.</div>
+
 =head1 SYNOPSIS
 
 B<rrdtool> B<update> I<filename> 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdresize.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdresize.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdresize.html	Sat Jul 13 21:26:33 2002
@@ -1,83 +1,72 @@
 <HTML>
 <HEAD>
 <TITLE>rrdresize</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
-	<LI><A HREF="#NOTES">NOTES</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
+	<LI><A HREF="#notes">NOTES</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-rrdtool resize - alters the size of an RRA.
-
-<P>
+<H1><A NAME="name">NAME</A></H1>
+<P>rrdtool resize - alters the size of an RRA.</P>
+<div align="right"><a href="rrdresize.pdf">PDF</a> version.</div><P>
 <HR>
-<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
-<P>
-<STRONG>rrdtool</STRONG>  <STRONG>resize</STRONG>  <EM>filename</EM>  <EM>rra-num</EM>    <STRONG>GROW</STRONG><EM>|</EM><STRONG>SHRINK</STRONG>  <EM>rows</EM>
-
-
-
+<H1><A NAME="synopsis">SYNOPSIS</A></H1>
+<P><STRONG>rrdtool</STRONG> <STRONG>resize</STRONG> <EM>filename</EM> <EM>rra-num</EM>  <STRONG>GROW</STRONG><EM>|</EM><STRONG>SHRINK</STRONG> <EM>rows</EM></P>
 <P>
 <HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-The <STRONG>resize</STRONG> function is used to modify the number of rows in an <STRONG>RRA</STRONG>.
-
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>The <STRONG>resize</STRONG> function is used to modify the number of rows in
+an <STRONG>RRA</STRONG>.</P>
 <DL>
-<DT><STRONG><A NAME="item_filename">filename</A></STRONG><DD>
-<P>
+<DT><STRONG><A NAME="item_filename"><EM>filename</EM></A></STRONG><BR>
+<DD>
 the name of the <STRONG>RRD</STRONG> you want to alter.
-
-<DT><STRONG><A NAME="item_rra">rra-num</A></STRONG><DD>
-<P>
-the <STRONG>RRA</STRONG> you want to alter. You can find the number using <STRONG>rrdtool dump</STRONG>.
-
-<DT><STRONG><A NAME="item_GROW">GROW</A></STRONG><DD>
-<P>
-used if you want to add extra rows to an RRA. The extra rows will be
-inserted as the rows that are oldest.
-
-<DT><STRONG><A NAME="item_SHRINK">SHRINK</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_rra%2Dnum"><EM>rra-num</EM></A></STRONG><BR>
+<DD>
+the <STRONG>RRA</STRONG> you want to alter. You can find the number using <STRONG>rrdtool info</STRONG>.
+<P></P>
+<DT><STRONG><A NAME="item_GROW"><STRONG>GROW</STRONG></A></STRONG><BR>
+<DD>
+used if you want to add extra rows to an RRA. The extra rows will be inserted
+as the rows that are oldest.
+<P></P>
+<DT><STRONG><A NAME="item_SHRINK"><STRONG>SHRINK</STRONG></A></STRONG><BR>
+<DD>
 used if you want to remove rows from an RRA. The rows that will be removed
 are the oldest rows.
-
-<DT><STRONG><A NAME="item_rows">rows</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_rows"><EM>rows</EM></A></STRONG><BR>
+<DD>
 the number of rows you want to add or remove.
-
-</DL>
+<P></P></DL>
 <P>
 <HR>
-<H1><A NAME="NOTES">NOTES</A></H1>
-<P>
-It is possible to abuse this tool and get strange results by first removing
-some rows and then reinsert the same amount (effectively clearing them to
-be Unknown). You may thus end up with unknown data in one RRA while at the
-same timestamp this data is available in another RRA.
-
+<H1><A NAME="notes">NOTES</A></H1>
+<P>It is possible to abuse this tool and get strange results
+by first removing some rows and then reinsert the same amount (effectively
+clearing them to be Unknown). You may thus end up with unknown data in one
+RRA while at the same timestamp this data is available in another RRA.</P>
 <P>
 <HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-Alex van den Bogaerdt &lt;<A
-HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt;
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Alex van den Bogaerdt &lt;<A HREF="mailto:alex at ergens.op.het.net">alex at ergens.op.het.net</A>&gt;</P>
 
 </BODY>
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdrestore.pod
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdrestore.pod	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdrestore.pod	Sat Jul 13 21:26:33 2002
@@ -2,6 +2,8 @@
 
 rrdtool restore - restore the contents of an B<RRD> from its XML dump format
 
+=for html <div align="right"><a href="rrdrestore.pdf">PDF</a> version.</div>
+
 =head1 SYNOPSIS
 
 B<rrdtool> B<restore> I<filename.xml> I<filename.rrd>

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/RRDs.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/RRDs.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/RRDs.html	Sat Jul 13 21:26:34 2002
@@ -1,118 +1,103 @@
 <HTML>
 <HEAD>
 <TITLE>RRDs</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
 	<UL>
 
-		<LI><A HREF="#Calling_Sequence">Calling Sequence</A>
-		<LI><A HREF="#Error_Handling">Error Handling</A>
-		<LI><A HREF="#Return_Values">Return Values</A>
+		<LI><A HREF="#calling sequence">Calling Sequence</A></LI>
+		<LI><A HREF="#error handling">Error Handling</A></LI>
+		<LI><A HREF="#return values">Return Values</A></LI>
 	</UL>
 
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-RRDs - Access rrdtool as a shared module
-
+<H1><A NAME="name">NAME</A></H1>
+<P>RRDs - Access rrdtool as a shared module</P>
 <P>
 <HR>
-<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
-<P>
-<PRE>  use RRDs;
+<H1><A NAME="synopsis">SYNOPSIS</A></H1>
+<PRE>
+  use RRDs;
   RRDs::error
   RRDs::last ...
+  RRDs::info ...
   RRDs::create ...
   RRDs::update ...
   RRDs::graph ...
   RRDs::fetch ...
-  RRDs::tune ...
-</PRE>
-<P>
-<HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-<HR>
-<H2><A NAME="Calling_Sequence">Calling Sequence</A></H2>
-<P>
-This module accesses rrdtool functionality directly from within perl. The
-arguments to the functions listed in the SYNOPSIS are explained in the
-regular rrdtool documentation. The commandline call
-
-<P>
-<PRE> rrdtool update mydemo.rrd N:12:13
-</PRE>
-<P>
-gets turned into
-
-<P>
-<PRE> RRDs::update (&quot;mydemo.rrd&quot;, &quot;N:12:13&quot;);
-</PRE>
+  RRDs::tune ...</PRE>
 <P>
 <HR>
-<H2><A NAME="Error_Handling">Error Handling</A></H2>
-<P>
-The RRD functions will not abort your program even when they can not make
-sense out of the arguments you fed them. There are two ways to determine if
-an error has occured.
-
-<P>
-First the every function will return the value -1 if an error occured.
-Second, the function RRDs::error can be called to get the error message
-from the last function call. If RRDs::error does not return an error then
-the previous function has completed its task succesfully.
-
+<H1><A NAME="description">DESCRIPTION</A></H1>
 <P>
-<PRE> use RRDs;
+<H2><A NAME="calling sequence">Calling Sequence</A></H2>
+<P>This module accesses rrdtool functionality directly from within perl. The
+arguments to the functions listed in the SYNOPSIS are explained in the regular
+rrdtool documentation. The commandline call</P>
+<PRE>
+ rrdtool update mydemo.rrd --template in:out N:12:13</PRE>
+<P>gets turned into</P>
+<PRE>
+ RRDs::update (&quot;mydemo.rrd&quot;, &quot;--template&quot;, &quot;in:out&quot;, &quot;N:12:13&quot;);</PRE>
+<P>Note that</P>
+<PRE>
+ --template=in:out</PRE>
+<P>is also valid.</P>
+<P>
+<H2><A NAME="error handling">Error Handling</A></H2>
+<P>The RRD functions will not abort your program even when they can not make
+sense out of the arguments you fed them.</P>
+<P>The function RRDs::error should be called to get the error status
+after each function call. If RRDs::error does not return anything
+then the previous function has completed its task successfully.</P>
+<PRE>
+ use RRDs;
  RRDs::update (&quot;mydemo.rrd&quot;,&quot;N:12:13&quot;);
  my $ERR=RRDs::error;
- die &quot;ERROR while updating mydemo.rrd: $ERR\n&quot; if $ERR;
-</PRE>
-<P>
-<HR>
-<H2><A NAME="Return_Values">Return Values</A></H2>
-<P>
-The functions RRDs::last, RRDs::graph and RRDs::fetch return their
-findings.
-
-<P>
-RRDs::last returns a single INTEGER representing the last update time.
-
-<P>
-<PRE> $lastupdate = RRDs::last ...
-</PRE>
+ die &quot;ERROR while updating mydemo.rrd: $ERR\n&quot; if $ERR;</PRE>
 <P>
-RRDs::graph returns an pointer to an ARRAY containing the x-size and y-size
-of the created gif and results of the PRINT arguments.
-
-<P>
-<PRE> ($averages,$xsize,$ysize) = RRDs::graph ...
+<H2><A NAME="return values">Return Values</A></H2>
+<P>The functions RRDs::last, RRDs::graph, RRDs::info and RRDs::fetch return their
+findings.</P>
+<P><STRONG>RRDs::last</STRONG> returns a single INTEGER representing the last update time.</P>
+<PRE>
+ $lastupdate = RRDs::last ...</PRE>
+<P><STRONG>RRDs::graph</STRONG> returns an pointer to an ARRAY containing the x-size and y-size of the
+created gif and results of the PRINT arguments.</P>
+<PRE>
+ ($averages,$xsize,$ysize) = RRDs::graph ...
  print &quot;Gifsize: ${xsize}x${ysize}\n&quot;;
- print &quot;Averages: &quot;, (join &quot;, &quot;, @$averages);
-</PRE>
-<P>
-RRDs::fetch is the most complex of the pack regarding return values. There
-are 4 values. Two normal integers, a pointer to an array and a pointer to a
-array of pointers.
-
-<P>
-<PRE>  my ($start,$step,$names,$data) = RRDs::fetch ... 
+ print &quot;Averages: &quot;, (join &quot;, &quot;, @$averages);</PRE>
+<P><STRONG>RRDs::info</STRONG> returns a pointer to a hash. The keys of the hash
+represent the property names of the rrd and the values of the hash are
+the values of the properties.</P>
+<PRE>
+ $hash = RRDs::info &quot;example.rrd&quot;;
+ foreach my $key (keys %$hash){
+   print &quot;$key = $$hash{$key}\n&quot;;
+ }</PRE>
+<P><STRONG>RRDs::fetch</STRONG> is the most complex of
+the pack regarding return values. There are 4 values. Two normal
+integers, a pointer to an array and a pointer to a array of pointers.</P>
+<PRE>
+  my ($start,$step,$names,$data) = RRDs::fetch ... 
   print &quot;Start:       &quot;, scalar localtime($start), &quot; ($start)\n&quot;;
   print &quot;Step size:   $step seconds\n&quot;;
   print &quot;DS names:    &quot;, join (&quot;, &quot;, @$names).&quot;\n&quot;;
@@ -125,17 +110,12 @@
       printf &quot;%12.1f &quot;, $val;
     }
     print &quot;\n&quot;;
-  }
-</PRE>
-<P>
-See the examples directory for more ways to use this extension.
-
+  }</PRE>
+<P>See the examples directory for more ways to use this extension.</P>
 <P>
 <HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-Tobias Oetiker &lt;<A
-HREF="mailto:oeitker at ee.ethy.ch">oeitker at ee.ethy.ch</A>&gt;
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;</P>
 
 </BODY>
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdcgi.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdcgi.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdcgi.html	Sat Jul 13 21:26:34 2002
@@ -1,175 +1,157 @@
 <HTML>
 <HEAD>
 <TITLE>rrdcgi</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
 	<UL>
 
-		<LI><A HREF="#Pass_1">Pass 1</A>
-		<LI><A HREF="#Pass_2">Pass 2</A>
-		<LI><A HREF="#Pass_3">Pass 3</A>
+		<LI><A HREF="#pass 1">Pass 1</A></LI>
+		<LI><A HREF="#pass 2">Pass 2</A></LI>
+		<LI><A HREF="#pass 3">Pass 3</A></LI>
 	</UL>
 
-	<LI><A HREF="#EXAMPLE_1">EXAMPLE 1</A>
-	<LI><A HREF="#EXAMPLE_2">EXAMPLE 2</A>
-	<LI><A HREF="#EXAMPLE_3">EXAMPLE 3</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#example 1">EXAMPLE 1</A></LI>
+	<LI><A HREF="#example 2">EXAMPLE 2</A></LI>
+	<LI><A HREF="#example 3">EXAMPLE 3</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-rrdcgi - create web pages containing RRD graphs based on templates
-
-<P>
+<H1><A NAME="name">NAME</A></H1>
+<P>rrdcgi - create web pages containing RRD graphs based on templates</P>
+<div align="right"><a href="rrdcgi.pdf">PDF</a> version.</div><P>
 <HR>
-<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
-<P>
-#!/path/to/<STRONG>rrdcgi</STRONG> 
- 
+<H1><A NAME="synopsis">SYNOPSIS</A></H1>
+<P>#!/path/to/<STRONG>rrdcgi</STRONG> 
 [<STRONG>--goodfor</STRONG>|<STRONG>-g</STRONG>&nbsp;<EM>seconds</EM>]
-
 [<STRONG>--filter</STRONG>]
-
-[<STRONG>--refresh</STRONG>|<STRONG>-r</STRONG>]
-
-
-
+[<STRONG>--refresh</STRONG>|<STRONG>-r</STRONG>]</P>
 <P>
 <HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-<STRONG>rrdcgi</STRONG> is a sort of very limited script interpreter. Its purpose is to run as a
-cgi-program and parse a web page template containing special
-&lt;RRD:: tags. <STRONG>rrdcgi</STRONG> will interpret and act according to these tags. In the end it will printout
-a web page including the necessary CGI headers.
-
-<P>
-<STRONG>rrdcgi</STRONG> parses the contents of the template in 2 steps. In each step it looks only
-for a subset of tags. This allows to nest tags. 
-
-<P>
-The argument parser uses the same semantics as you are used from your c
-shell.
-
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P><STRONG>rrdcgi</STRONG> is a sort of very limited script interpreter. Its purpose
+is to run as a cgi-program and parse a web page template containing special
+&lt;RRD:: tags. <STRONG>rrdcgi</STRONG> will interpret and act according to these tags.
+In the end it will printout a web page including the necessary CGI headers.</P>
+<P><STRONG>rrdcgi</STRONG> parses the contents of the template in 2 steps. In each step it looks
+only for a subset of tags. This allows to nest tags.</P>
+<P>The argument parser uses the same semantics as you are used from your c shell.</P>
 <DL>
-<DT><STRONG><A NAME="item__filter">--filter</A></STRONG><DD>
-<P>
+<DT><STRONG><A NAME="item_%2D%2Dfilter"><STRONG>--filter</STRONG></A></STRONG><BR>
+<DD>
 Assume that rrdcgi is being run as a filter and not as a cgi.
-
-<DT><STRONG><A NAME="item__refresh_r">--refresh|-r</A></STRONG><DD>
-<P>
-If the <STRONG>--goodfor</STRONG> flag is specified, then <STRONG>--refresh</STRONG> will cause rrdcgi to output a Refresh header with the value of the <STRONG>--goodfor</STRONG> value.
-
-</DL>
+<P></P>
+<DT><STRONG><A NAME="item_%2D%2Drefresh%7C%2Dr"><STRONG>--refresh</STRONG>|<STRONG>-r</STRONG></A></STRONG><BR>
+<DD>
+If the <STRONG>--goodfor</STRONG> flag is specified, then <STRONG>--refresh</STRONG> will cause rrdcgi
+to output a Refresh header with the value of the <STRONG>--goodfor</STRONG> value.
+<P></P></DL>
 <P>
-<HR>
-<H2><A NAME="Pass_1">Pass 1</A></H2>
+<H2><A NAME="pass 1">Pass 1</A></H2>
 <DL>
-<DT><STRONG><A NAME="item_RRD">RRD::CV name</A></STRONG><DD>
-<P>
+<DT><STRONG><A NAME="item_RRD%3A%3ACV_name">RRD::CV <EM>name</EM></A></STRONG><BR>
+<DD>
 Inserts the CGI variable of the given name.
-
-<DT><STRONG><A NAME="item_RRD">RRD::CV::QUOTE name</A></STRONG><DD>
-<P>
-Inserts the CGI variable of the given name but quotes it, ready for use as
-an argument in another RRD:: tag. So even when there are spaces in the
+<P></P>
+<DT><STRONG><A NAME="item_RRD%3A%3ACV%3A%3AQUOTE_name">RRD::CV::QUOTE <EM>name</EM></A></STRONG><BR>
+<DD>
+Inserts the CGI variable of the given name but quotes it, ready for
+use as an argument in another RRD:: tag. So even when there are spaces in the
 value of the CGI variable it will still be considered as one argument.
-
-<DT><STRONG><A NAME="item_RRD">RRD::CV::PATH name</A></STRONG><DD>
-<P>
-Inserts the CGI variable of the given name, quotes it and makes sure the it
-starts neither with a '/' nor contains '..'. This is to make sure that no
-problematic pathnames can be introduced through the CGI interface.
-
-</DL>
+<P></P>
+<DT><STRONG><A NAME="item_RRD%3A%3ACV%3A%3APATH_name">RRD::CV::PATH <EM>name</EM></A></STRONG><BR>
+<DD>
+Inserts the CGI variable of the given name, quotes it and makes sure
+the it starts neither with a '/' nor contains '..'. This is to make
+sure that no problematic pathnames can be introduced through the 
+CGI interface.
+<P></P>
+<DT><STRONG><A NAME="item_RRD%3A%3AGETENV_variable">RRD::GETENV <EM>variable</EM></A></STRONG><BR>
+<DD>
+Get the value of an environment variable.
+<PRE>
+ &lt;RRD::GETENV REMOTE_USER&gt;</PRE>
+<P>might give you the name of the remote user given you are using
+some sort of access control on the directory</P>
+<P></P></DL>
 <P>
-<HR>
-<H2><A NAME="Pass_2">Pass 2</A></H2>
+<H2><A NAME="pass 2">Pass 2</A></H2>
 <DL>
-<DT><STRONG><A NAME="item_RRD">RRD::GOODFOR seconds</A></STRONG><DD>
-<P>
-Specify the number of seconds this page should remain valid. This will
-prompt the rrdcgi to output a Last-Modified, an Expire and if the number of
+<DT><STRONG><A NAME="item_RRD%3A%3AGOODFOR_seconds">RRD::GOODFOR <EM>seconds</EM></A></STRONG><BR>
+<DD>
+Specify the number of seconds this page should remain valid. This will prompt
+the rrdcgi to output a Last-Modified, an Expire and if the number of
 seconds is <EM>negative</EM> a Refresh headers.
-
-<DT><STRONG><A NAME="item_RRD">RRD::INCLUDE filename</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_RRD%3A%3AINCLUDE_filename">RRD::INCLUDE <EM>filename</EM></A></STRONG><BR>
+<DD>
 Include the contents of the given file into the page returned from the cgi
-
-<DT><STRONG><A NAME="item_RRD">RRD::SETENV variable value</A></STRONG><DD>
-<P>
+<P></P>
+<DT><STRONG><A NAME="item_RRD%3A%3ASETENV_variable_value">RRD::SETENV <EM>variable</EM> <EM>value</EM></A></STRONG><BR>
+<DD>
 If you want to present your graphs in another time zone than your own, you
 could use
-
-<P>
-<PRE> &lt;RRD::SETENV TZ UTC&gt;
-</PRE>
-<P>
-to make sure everything is presented in Universal Time. Note that the
-values permitted to TZ depend on your OS.
-
-<DT><STRONG><A NAME="item_RRD">RRD::TIME::LAST rrd-file strftime-format</A></STRONG><DD>
-<P>
+<PRE>
+ &lt;RRD::SETENV TZ UTC&gt;</PRE>
+<P>to make sure everything is presented in Universal Time. Note that the
+values permitted to TZ depend on your OS.</P>
+<P></P>
+<DT><STRONG><A NAME="item_RRD%3A%3ATIME%3A%3ALAST_rrd%2Dfile_strftime%2Dform">RRD::TIME::LAST <EM>rrd-file</EM> <EM>strftime-format</EM></A></STRONG><BR>
+<DD>
 This gets replaced by the last modification time of the selected RRD. The
 time is <EM>strftime</EM>-formated with the string specified in the second argument.
-
-<DT><STRONG><A NAME="item_RRD">RRD::TIME::NOW strftime-format</A></STRONG><DD>
+<P></P>
+<DT><STRONG><A NAME="item_RRD%3A%3ATIME%3A%3ANOW_strftime%2Dformat">RRD::TIME::NOW <EM>strftime-format</EM></A></STRONG><BR>
+<DD>
+This gets replaced by the current time of day. The
+time is <EM>strftime</EM>-formated with the string specified in the argument.
+<P></P></DL>
 <P>
-This gets replaced by the current time of day. The time is <EM>strftime</EM>-formated with the string specified in the argument.
-
-</DL>
-<P>
-<HR>
-<H2><A NAME="Pass_3">Pass 3</A></H2>
+<H2><A NAME="pass 3">Pass 3</A></H2>
 <DL>
-<DT><STRONG><A NAME="item_RRD">RRD::GRAPH rrdgraph arguments</A></STRONG><DD>
-<P>
+<DT><STRONG><A NAME="item_RRD%3A%3AGRAPH_rrdgraph_arguments">RRD::GRAPH <EM>rrdgraph arguments</EM></A></STRONG><BR>
+<DD>
 This tag creates the RRD graph defined in its argument and then gets
-replaced by an appropriate &lt;IMG&gt; tag referring to the graph. The <STRONG>--lazy</STRONG> option in RRD graph can be used to make sure that graphs are only
-regenerated when they are out of date. The arguments to the <STRONG>RRD::GRAPH</STRONG> tag work as described in the <STRONG>rrdgraph</STRONG> manual page.
-
-<P>
-Use the <STRONG>--lazy</STRONG> option in your RRD::GRAPH tags, to reduce the load on your server. This
-option makes sure that graphs are only regenerated when the old ones are
-out of date.
-
-<P>
-If you do not specify your own <STRONG>--imginfo</STRONG> format, the following will be used:
-
-<P>
-<PRE> &lt;IMG SRC=&quot;%s&quot; WIDTH=&quot;%lu&quot; HEIGHT=&quot;%lu&quot;&gt;
-</PRE>
-<P>
-Note that <CODE>%s</CODE> stands for the filename part of the graph
-generated, all directories given in the GIF file argument will get dropped.
-
-<DT><STRONG><A NAME="item_RRD">RRD::PRINT number</A></STRONG><DD>
-<P>
-If the preceding  <STRONG>RRD::GRAPH</STRONG> tag contained and <STRONG>PRINT</STRONG> arguments, then you can access their output with this tag. The <EM>number</EM> argument refers to the number of the <STRONG>PRINT</STRONG> argument. This first <STRONG>PRINT</STRONG> has <EM>number</EM> 0.
-
-</DL>
-<P>
-<HR>
-<H1><A NAME="EXAMPLE_1">EXAMPLE 1</A></H1>
-<P>
-The example below creates a web pages with a single RRD graph.
-
-<P>
-<PRE> #!/usr/local/bin/rrdcgi
+replaced by an appropriate &lt;IMG&gt; tag referring to the graph.
+The <STRONG>--lazy</STRONG> option in RRD graph can be used to make sure that graphs
+are only regenerated when they are out of date. The arguments
+to the <STRONG>RRD::GRAPH</STRONG> tag work as described in the <STRONG>rrdgraph</STRONG> manual page.
+<P>Use the <STRONG>--lazy</STRONG> option in your RRD::GRAPH tags, to reduce the load
+on your server. This option makes sure that graphs are only regenerated when
+the old ones are out of date.</P>
+<P>If you do not specify your own <STRONG>--imginfo</STRONG> format, the following will
+be used:</P>
+<PRE>
+ &lt;IMG SRC=&quot;%s&quot; WIDTH=&quot;%lu&quot; HEIGHT=&quot;%lu&quot;&gt;</PRE>
+<P>Note that %s stands for the filename part of the graph generated, all
+directories given in the GIF file argument will get dropped.</P>
+<P></P>
+<DT><STRONG><A NAME="item_RRD%3A%3APRINT_number">RRD::PRINT <EM>number</EM></A></STRONG><BR>
+<DD>
+If the preceding  <STRONG>RRD::GRAPH</STRONG> tag contained and <STRONG>PRINT</STRONG> arguments,
+then you can access their output with this tag. The <EM>number</EM> argument refers to the
+number of the <STRONG>PRINT</STRONG> argument. This first <STRONG>PRINT</STRONG> has <EM>number</EM> 0.
+<P></P></DL>
+<P>
+<HR>
+<H1><A NAME="example 1">EXAMPLE 1</A></H1>
+<P>The example below creates a web pages with a single RRD graph.</P>
+<PRE>
+ #!/usr/local/bin/rrdcgi
  &lt;HTML&gt;
  &lt;HEAD&gt;&lt;TITLE&gt;RRDCGI Demo&lt;/TITLE&gt;&lt;/HEAD&gt;
  &lt;BODY&gt;
@@ -177,23 +159,19 @@
  &lt;P&gt;
  &lt;RRD::GRAPH demo.gif --lazy --title=&quot;Temperatures&quot;
           DEF:cel=demo.rrd:exhaust:AVERAGE
-          LINE2:cel#00a000:&quot;D. Celsius&quot;&gt;
-</PRE>
-<P>
-<PRE> &lt;/P&gt;
+          LINE2:cel#00a000:&quot;D. Celsius&quot;&gt;</PRE>
+<PRE>
+ &lt;/P&gt;
  &lt;/BODY&gt;
- &lt;/HTML&gt;
-</PRE>
+ &lt;/HTML&gt;</PRE>
 <P>
 <HR>
-<H1><A NAME="EXAMPLE_2">EXAMPLE 2</A></H1>
-<P>
-This script is slightly more elaborate, it allows you to run it from a form
-which sets RRD_NAME. RRD_NAME is then used to select which RRD you want to
-use a source for your graph.
-
-<P>
-<PRE> #!/usr/local/bin/rrdcgi
+<H1><A NAME="example 2">EXAMPLE 2</A></H1>
+<P>This script is slightly more elaborate, it allows you to run it from 
+a form which sets RRD_NAME. RRD_NAME is then used to select which RRD
+you want to use a source for your graph.</P>
+<PRE>
+ #!/usr/local/bin/rrdcgi
  &lt;HTML&gt;
  &lt;HEAD&gt;&lt;TITLE&gt;RRDCGI Demo&lt;/TITLE&gt;&lt;/HEAD&gt;
  &lt;BODY&gt;
@@ -207,22 +185,18 @@
  &lt;RRD::GRAPH &lt;RRD::CV::PATH RRD_NAME&gt;.gif --lazy 
           --title &quot;Temperatures for &quot;&lt;RRD::CV::QUOTE RRD_NAME&gt;
           DEF:cel=&lt;RRD::CV::PATH RRD_NAME&gt;.rrd:exhaust:AVERAGE
-          LINE2:cel#00a000:&quot;D. Celsius&quot;&gt;
-</PRE>
-<P>
-<PRE> &lt;/P&gt;
+          LINE2:cel#00a000:&quot;D. Celsius&quot;&gt;</PRE>
+<PRE>
+ &lt;/P&gt;
  &lt;/BODY&gt;
- &lt;/HTML&gt;
-</PRE>
+ &lt;/HTML&gt;</PRE>
 <P>
 <HR>
-<H1><A NAME="EXAMPLE_3">EXAMPLE 3</A></H1>
-<P>
-This example shows how to handle the case where the RRD, graphs and
-cgi-bins are seperate directories
-
-<P>
-<PRE> #!/.../bin/rrdcgi
+<H1><A NAME="example 3">EXAMPLE 3</A></H1>
+<P>This example shows how to handle the case where the RRD, graphs and
+cgi-bins are seperate directories</P>
+<PRE>
+ #!/.../bin/rrdcgi
  &lt;HTML&gt;
  &lt;HEAD&gt;&lt;TITLE&gt;RRDCGI Demo&lt;/TITLE&gt;&lt;/HEAD&gt;
  &lt;BODY&gt;
@@ -235,22 +209,14 @@
   AREA:http_src#00ff00:http_src
  &gt;
  &lt;/BODY&gt;
- &lt;/HTML&gt;
-</PRE>
-<P>
-Note 1: Replace /.../ with the relevant directories
-
-<P>
-Note 2: The SRC=/.../gifs should be paths from the view of the
-webserver/browser
-
+ &lt;/HTML&gt;</PRE>
+<P>Note 1: Replace /.../ with the relevant directories</P>
+<P>Note 2: The SRC=/.../gifs should be paths from the view of the
+webserver/browser</P>
 <P>
 <HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;
-
-
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;</P>
 
 </BODY>
 

Modified: trunk/orca/packages/rrdtool-1.0.33/doc/rrdcreate.html
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/doc/rrdcreate.html	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/doc/rrdcreate.html	Sat Jul 13 21:26:34 2002
@@ -1,182 +1,233 @@
 <HTML>
 <HEAD>
 <TITLE>rrdcreate</TITLE>
-<LINK REV="made" HREF="mailto:karrer at zinal.ee.ethz.ch">
+<LINK REV="made" HREF="mailto:karrer at iis.ee.ethz.ch">
 </HEAD>
 
 <BODY>
 
+<A NAME="__index__"></A>
 <!-- INDEX BEGIN -->
 <!--
 
 <UL>
 
-	<LI><A HREF="#NAME">NAME</A>
-	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
-	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
-	<LI><A HREF="#EXAMPLE">EXAMPLE</A>
-	<LI><A HREF="#AUTHOR">AUTHOR</A>
+	<LI><A HREF="#name">NAME</A></LI>
+	<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
+	<LI><A HREF="#description">DESCRIPTION</A></LI>
+	<LI><A HREF="#the heartbeat and the step">The HEARTBEAT and the STEP</A></LI>
+	<LI><A HREF="#how to measure">HOW TO MEASURE</A></LI>
+	<LI><A HREF="#example">EXAMPLE</A></LI>
+	<LI><A HREF="#author">AUTHOR</A></LI>
 </UL>
 -->
 <!-- INDEX END -->
 
 <P>
-<H1><A NAME="NAME">NAME</A></H1>
-<P>
-rrdtool create - Set up a new Round Robin Database
-
-<P>
+<H1><A NAME="name">NAME</A></H1>
+<P>rrdtool create - Set up a new Round Robin Database</P>
+<div align="right"><a href="rrdcreate.pdf">PDF</a> version.</div><P>
 <HR>
-<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
-<P>
-<STRONG>rrdtool</STRONG>  <STRONG>create</STRONG>  <EM>filename</EM> 
- 
+<H1><A NAME="synopsis">SYNOPSIS</A></H1>
+<P><STRONG>rrdtool</STRONG> <STRONG>create</STRONG> <EM>filename</EM> 
 [<STRONG>--start</STRONG>|<STRONG>-b</STRONG>&nbsp;<EM>start&nbsp;time</EM>] 
- 
 [<STRONG>--step</STRONG>|<STRONG>-s</STRONG>&nbsp;<EM>step</EM>] 
- 
 [<STRONG>DS:</STRONG><EM>ds-name</EM><STRONG>:</STRONG><EM>DST</EM><STRONG>:</STRONG><EM>heartbeat</EM><STRONG>:</STRONG><EM>min</EM><STRONG>:</STRONG><EM>max</EM>]
-
-[<STRONG>RRA:</STRONG><EM>CF</EM><STRONG>:</STRONG><EM>xff</EM><STRONG>:</STRONG><EM>steps</EM><STRONG>:</STRONG><EM>rows</EM>]
-
-
-
+[<STRONG>RRA:</STRONG><EM>CF</EM><STRONG>:</STRONG><EM>xff</EM><STRONG>:</STRONG><EM>steps</EM><STRONG>:</STRONG><EM>rows</EM>]</P>
 <P>
 <HR>
-<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
-<P>
-The create function of the RRDtool lets you set up new Round Robin Database
-(<STRONG>RRD</STRONG>) files. The file is created at its final, full size and filled with <EM>*UNKNOWN*</EM> data.
-
+<H1><A NAME="description">DESCRIPTION</A></H1>
+<P>The create function of the RRDtool lets you set up new
+Round Robin Database (<STRONG>RRD</STRONG>) files. 
+The file is created at its final, full size and filled
+with <EM>*UNKNOWN*</EM> data.</P>
 <DL>
-<DT><STRONG><A NAME="item_filename">filename</A></STRONG><DD>
-<P>
-The name of the <STRONG>RRD</STRONG> you want to create. <STRONG>RRD</STRONG> files should end with the extension <EM>.rrd</EM>. However, <STRONG>rrdtool</STRONG> will accept any filename.
-
-<DT><STRONG><A NAME="item__start_b">--start|-b start time (default: now - 10s)</A></STRONG><DD>
-<P>
-Specifies the time in seconds since 1970-01-01 UTC when the first value
-should be added to the <STRONG>RRD</STRONG>. <STRONG>rrdtool</STRONG> will not accept any data timed before or at the time specified.
-
-<P>
-See also AT-STYLE TIME SPECIFICATION section in the
-<EM>rrdfetch</EM> documentation for more ways to specify time.
-
-<DT><STRONG><A NAME="item__step_s">--step|-s step (default: 300 seconds)</A></STRONG><DD>
-<P>
-Specifies the base interval in seconds with which data will be fed into the <STRONG>RRD</STRONG>.
-
-<DT><STRONG><A NAME="item_DS">DS:ds-name:DST:heartbeat:min:max</A></STRONG><DD>
-<P>
-A single <STRONG>RRD</STRONG> can accept input from several data sources (<STRONG>DS</STRONG>). (e.g. Incoming and Outgoing traffic on a specific communication line).
-With the <STRONG>DS</STRONG> configuration option you must define some basic properties of each data
-source you want to use to feed the <STRONG>RRD</STRONG>.
-
-<P>
-<EM>ds-name</EM> is the name you will use to reference this particular data source from an <STRONG>RRD</STRONG>. A <EM>ds-name</EM> must be 1 to 19 characters long in the characters [a-zA-Z0-9_].
-
-<P>
-<EM>DST</EM> defines the Data Source Type. It can be one of the following:
-
+<DT><STRONG><A NAME="item_filename"><EM>filename</EM></A></STRONG><BR>
+<DD>
+The name of the <STRONG>RRD</STRONG> you want to create. <STRONG>RRD</STRONG> files should end
+with the extension <EM>.rrd</EM>. However, <STRONG>rrdtool</STRONG> will accept any
+filename.
+<P></P>
+<DT><STRONG><A NAME="item_time"><STRONG>--start</STRONG>|<STRONG>-b</STRONG> <EM>start time</EM> (default: now - 10s)</A></STRONG><BR>
+<DD>
+Specifies the time in seconds since 1970-01-01 UTC when the first
+value should be added to the <STRONG>RRD</STRONG>. <STRONG>rrdtool</STRONG> will not accept
+any data timed before or at the time specified.
+<P>See also AT-STYLE TIME SPECIFICATION section in the
+<EM>rrdfetch</EM> documentation for more ways to specify time.</P>
+<P></P>
+<DT><STRONG><A NAME="item_step"><STRONG>--step</STRONG>|<STRONG>-s</STRONG> <EM>step</EM> (default: 300 seconds)</A></STRONG><BR>
+<DD>
+Specifies the base interval in seconds with which data will be fed
+into the <STRONG>RRD</STRONG>.
+<P></P>
+<DT><STRONG><A NAME="item_DS%3Ads%2Dname%3ADST%3Aheartbeat%3Amin%3Amax"><STRONG>DS:</STRONG><EM>ds-name</EM><STRONG>:</STRONG><EM>DST</EM><STRONG>:</STRONG><EM>heartbeat</EM><STRONG>:</STRONG><EM>min</EM><STRONG>:</STRONG><EM>max</EM></A></STRONG><BR>
+<DD>
+A single <STRONG>RRD</STRONG> can accept input from several data sources (<STRONG>DS</STRONG>).
+(e.g. Incoming and Outgoing traffic on a specific communication
+line). With the <STRONG>DS</STRONG> configuration option you must define some basic
+properties of each data source you want to use to feed the <STRONG>RRD</STRONG>.
+<P><EM>ds-name</EM> is the name you will use to reference this particular data
+source from an <STRONG>RRD</STRONG>. A <EM>ds-name</EM> must be 1 to 19 characters long in
+the characters [a-zA-Z0-9_].</P>
+<P><EM>DST</EM> defines the Data Source Type. See the section on ``How to Measure'' below for further insight.
+The Datasource Type must be onw of the following:</P>
 <DL>
-<DT><STRONG><A NAME="item_GAUGE">GAUGE</A></STRONG><DD>
-<P>
-is for things like temperatures or number of people in a room or value of a
-RedHat share.
-
-<DT><STRONG><A NAME="item_COUNTER">COUNTER</A></STRONG><DD>
-<P>
-is for continuous incrementing counters like the InOctets counter in a
-router. The <STRONG>COUNTER</STRONG> data source assumes that the counter never decreases, except when a counter
-overflows. The update function takes the overflow into account. The counter
-is stored as a per-second rate. When the counter overflows, RRDtool checks
-if the overflow happened at the 32bit or 64bit border and acts accordingly
-by adding an appropriate value to the result.
-
-<DT><STRONG><A NAME="item_DERIVE">DERIVE</A></STRONG><DD>
-<P>
-will store the the derivative of the line going from the last to the
+<DT><STRONG><A NAME="item_GAUGE"><STRONG>GAUGE</STRONG></A></STRONG><BR>
+<DD>
+is for things like temperatures or number of people in a
+room or value of a RedHat share.
+<P></P>
+<DT><STRONG><A NAME="item_COUNTER"><STRONG>COUNTER</STRONG></A></STRONG><BR>
+<DD>
+is for continuous incrementing counters like the
+InOctets counter in a router. The <STRONG>COUNTER</STRONG> data source assumes that
+the counter never decreases, except when a counter overflows.  The update
+function takes the overflow into account.  The counter is stored as a
+per-second rate. When the counter overflows, RRDtool checks if the overflow happened at
+the 32bit or 64bit border and acts accordingly by adding an appropriate value to the result.
+<P></P>
+<DT><STRONG><A NAME="item_DERIVE"><STRONG>DERIVE</STRONG></A></STRONG><BR>
+<DD>
+will store the derivative of the line going from the last to the
 current value of the data source. This can be useful for gauges, for
-example, to measure the rate of people entering or leaving a room.
-Internally, derive works exaclty like COUNTER but without overflow checks.
-So if your counter does not reset at 32 or 64 bit you might want to use
-DERIVE and combine it with a MIN value of 0.
-
-<DT><STRONG><A NAME="item_ABSOLUTE">ABSOLUTE</A></STRONG><DD>
-<P>
-is for counters which get reset upon reading. This is used for fast
-counters which tend to overflow. So instead of reading them normally you
-reset them after every read to make sure you have a maximal time available
-before the next overflow.
-
-</DL>
-<P>
-<EM>heartbeat</EM> defines the maximum number of seconds that may pass between two updates of
-this data source before the value of the data source is assumed to be <EM>*UNKNOWN*</EM>.
-
-<P>
-<EM>min</EM> and <EM>max</EM> are optional entries defining the expected range of the data supplied by
-this data source. If <EM>min</EM> and/or <EM>max</EM> are defined, any value outside the defined range will be regarded as
-<EM>*UNKNOWN*</EM>. If you do not know or care about min and max, set them to U for unknown.
-Note that min and max always refer to the processed values of the DS. For a
-traffic-<STRONG>COUNTER</STRONG> type DS this would be the max and min data-rate expected from the device.
-
-<P>
-<EM>If information on minimal/maximal expected values is available,
+example, to measure the rate of people entering or leaving a
+room. Internally, derive works exaclty like COUNTER but without
+overflow checks. So if your counter does not reset at 32 or 64 bit you
+might want to use DERIVE and combine it with a MIN value of 0.
+<P></P>
+<DT><STRONG><A NAME="item_ABSOLUTE"><STRONG>ABSOLUTE</STRONG></A></STRONG><BR>
+<DD>
+is for counters which get reset upon reading. This is used for fast counters
+which tend to overflow. So instead of reading them normally you reset them
+after every read to make sure you have a maximal time available before the
+next overflow. Another usage is for things you count like number of messages
+since the last update.
+<P></P></DL>
+<P><EM>heartbeat</EM> defines the maximum number of seconds that may pass
+between two updates of this data source before the value of the 
+data source is assumed to be <EM>*UNKNOWN*</EM>.</P>
+<P><EM>min</EM> and <EM>max</EM> are optional entries defining the expected range of
+the data supplied by this data source. If <EM>min</EM> and/or <EM>max</EM> are
+defined, any value outside the defined range will be regarded as
+<EM>*UNKNOWN*</EM>. If you do not know or care about min and max, set them
+to U for unknown. Note that min and max always refer to the processed values
+of the DS. For a traffic-<STRONG>COUNTER</STRONG> type DS this would be the max and min
+data-rate expected from the device.</P>
+<P><EM>If information on minimal/maximal expected values is available,
 always set the min and/or max properties. This will help RRDtool in
-doing a simple sanity check on the data supplied when running update.</EM>
-
-
-
-<DT><STRONG><A NAME="item_RRA">RRA:CF:xff:steps:rows</A></STRONG><DD>
-<P>
-The purpose of an <STRONG>RRD</STRONG> is to store data in the round robin archives (<STRONG>RRA</STRONG>). An archive consists of a number of data values from all the defined
-data-sources (<STRONG>DS</STRONG>) and is defined with an <STRONG>RRA</STRONG> line.
-
-<P>
-When data is entered into an <STRONG>RRD</STRONG>, it is first fit into time slots of the length defined with the <STRONG>-s</STRONG> option becoming a <EM>primary data point</EM>.
-
-<P>
-The data is also consolidated with the consolidation function (<EM>CF</EM>) of the archive. The following consolidation functions are defined:
-<STRONG>AVERAGE</STRONG>, <STRONG>MIN</STRONG>, <STRONG>MAX</STRONG>, <STRONG>LAST</STRONG>.
-
+doing a simple sanity check on the data supplied when running update.</EM></P>
+<DT><STRONG><A NAME="item_RRA%3ACF%3Axff%3Asteps%3Arows"><STRONG>RRA:</STRONG><EM>CF</EM><STRONG>:</STRONG><EM>xff</EM><STRONG>:</STRONG><EM>steps</EM><STRONG>:</STRONG><EM>rows</EM></A></STRONG><BR>
+<DD>
+The purpose of an <STRONG>RRD</STRONG> is to store data in the round robin archives
+(<STRONG>RRA</STRONG>). An archive consists of a number of data values from all the
+defined data-sources (<STRONG>DS</STRONG>) and is defined with an <STRONG>RRA</STRONG> line.
+<P>When data is entered into an <STRONG>RRD</STRONG>, it is first fit into time slots of
+the length defined with the <STRONG>-s</STRONG> option becoming a <EM>primary data point</EM>.</P>
+<P>The data is also consolidated with the consolidation function (<EM>CF</EM>)
+of the archive. The following consolidation functions are defined:
+<STRONG>AVERAGE</STRONG>, <STRONG>MIN</STRONG>, <STRONG>MAX</STRONG>, <STRONG>LAST</STRONG>.</P>
+<P><EM>xff</EM> The xfiles factor defines what part of a consolidation interval may
+be made up from <EM>*UNKNOWN*</EM> data while the consolidated value is still
+regarded as known.</P>
+<P><EM>steps</EM> defines how many of these <EM>primary data points</EM> are used to
+build a <EM>consolidated data point</EM> which then goes into the archive.</P>
+<P><EM>rows</EM> defines how many generations of data values are kept in an <STRONG>RRA</STRONG>.</P>
+<P></P></DL>
 <P>
-<EM>xff</EM> The xfiles factor defines what part of a consolidation interval may be made
-up from <EM>*UNKNOWN*</EM> data while the consolidated value is still regarded as known.
-
-<P>
-<EM>steps</EM> defines how many of these <EM>primary data points</EM> are used to build a <EM>consolidated data point</EM> which then goes into the archive.
-
-<P>
-<EM>rows</EM> defines how many generations of data values are kept in an <STRONG>RRA</STRONG>.
-
-</DL>
+<HR>
+<H1><A NAME="the heartbeat and the step">The HEARTBEAT and the STEP</A></H1>
+<P>Here is an explanation by Don Baarda on the inner workings of rrdtool.
+It may help you to sort out why all this *UNKNOWN* data is popping
+up in your databases:</P>
+<P>RRD gets fed samples at arbitrary times. From these it builds Primary
+Data Points (PDPs) at exact times every ``step'' interval. The PDPs are
+then accumulated into RRAs.</P>
+<P>The ``heartbeat'' defines the maximum acceptable interval between
+samples. If the interval between samples is less than ``heartbeat'',
+then an average rate is calculated and applied for that interval. If
+the interval between samples is longer than ``heartbeat'', then that
+entire interval is considered ``unknown''. Note that there are other
+things that can make a sample interval ``unknown'', such as the rate
+exceeding limits, or even an ``unknown'' input sample.</P>
+<P>The known rates during a PDP's ``step'' interval are used to calculate
+an average rate for that PDP. Also, if the total ``unknown'' time during
+the ``step'' interval exceeds the ``heartbeat'', the entire PDP is marked
+as ``unknown''. This means that a mixture of known and ``unknown'' sample
+time in a single PDP ``step'' may or may not add up to enough ``unknown''
+time to exceed ``heartbeat'' and hence mark the whole PDP ``unknown''. So
+``heartbeat'' is not only the maximum acceptable interval between
+samples, but also the maximum acceptable amount of ``unknown'' time per
+PDP (obviously this is only significant if you have ``heartbeat'' less
+than ``step'').</P>
+<P>The ``heartbeat'' can be short (unusual) or long (typical) relative to
+the ``step'' interval between PDPs. A short ``heartbeat'' means you
+require multiple samples per PDP, and if you don't get them mark the
+PDP unknown. A long heartbeat can span multiple ``steps'', which means
+it is acceptable to have multiple PDPs calculated from a single
+sample. An extreme example of this might be a ``step'' of 5mins and a
+``heartbeat'' of one day, in which case a single sample every day will
+result in all the PDPs for that entire day period being set to the
+same average rate. <EM>-- Don Baarda &lt;<A HREF="mailto:don.baarda at baesystems.com">don.baarda at baesystems.com</A>&gt;</EM></P>
 <P>
 <HR>
-<H1><A NAME="EXAMPLE">EXAMPLE</A></H1>
+<H1><A NAME="how to measure">HOW TO MEASURE</A></H1>
+<P>Here are a few hints on how to measure:</P>
+<DL>
+<DT><STRONG><A NAME="item_Temperature">Temperature</A></STRONG><BR>
+<DD>
+Normally you have some type of meter you can read to get the temperature.
+The temperature is not realy connected with a time. The only connection is
+that the temperature reading happened at a certain time. You can use the
+<STRONG>GAUGE</STRONG> data source type for this. RRRtool will the record your reading
+together with the time.
+<P></P>
+<DT><STRONG><A NAME="item_Mail_Messages">Mail Messages</A></STRONG><BR>
+<DD>
+Assume you have a methode to count the number of messages transported by
+your mailserver in a certain amount of time, this give you data like '5
+messages in the last 65 seconds'. If you look at the count of 5 like and
+<STRONG>ABSOLUTE</STRONG> datatype you can simply update the rrd with the number 5 and the
+end time of your monitoring period. RRDtool will then record the number of
+messages per second. If at some later stage you want to know the number of
+messages transported in a day, you can get the average messages per second
+from RRDtool for the day in question and multiply this number with the
+number of seconds in a day. Because all math is run with Doubles, the
+precision should be acceptable.
+<P></P>
+<DT><STRONG><A NAME="item_It%27s_always_a_Rate">It's always a Rate</A></STRONG><BR>
+<DD>
+RRDtool stores rates in amount/second for COUNTER, DERIVE and ABSOLUTE data.
+When you plot the data, you will get on the y axis amount/second which you
+might be tempted to convert to absolute amount volume by multiplying by the
+delta-time between the points. RRDtool plots continuous data, and as such is
+not appropriate for plotting absolute volumes as for example ``total bytes''
+sent and received in a router. What you probably want is plot rates that you
+can scale to for example bytes/hour or plot volumes with another tool that
+draws bar-plots, where the delta-time is clear on the plot for each point
+(such that when you read the graph you see for example GB on the y axis,
+days on the x axis and one bar for each day).
+<P></P></DL>
 <P>
-<CODE>rrdtool create temperature.rrd --step 300 DS:temp:GAUGE:600:-273:5000
+<HR>
+<H1><A NAME="example">EXAMPLE</A></H1>
+<P><CODE>rrdtool create temperature.rrd --step 300 DS:temp:GAUGE:600:-273:5000
 RRA:AVERAGE:0.5:1:1200 RRA:MIN:0.5:12:2400 RRA:MAX:0.5:12:2400
-RRA:AVERAGE:0.5:12:2400</CODE>
-
-
-
-<P>
-This sets up an <STRONG>RRD</STRONG> called <EM>temperature.rrd</EM> which accepts one temperature value every 300 seconds. If no new data is
-supplied for more than 600 seconds, the temperature becomes <EM>*UNKNOWN*</EM>. The minimum acceptable value is -273 and the maximum is 5000.
-
-<P>
-A few archives areas are also defined. The first stores the temperatures
-supplied for 100 hours (1200 * 300 seconds = 100 hours). The second RRA
-stores the minimum temperature recorded over every hour (12 * 300 seconds =
-1 hour), for 100 days (2400 hours). The third and the fourth RRA's do the
-same with the for the maximum and average temperature, respectively.
-
+RRA:AVERAGE:0.5:12:2400</CODE></P>
+<P>This sets up an <STRONG>RRD</STRONG> called <EM>temperature.rrd</EM> which accepts one
+temperature value every 300 seconds. If no new data is supplied for
+more than 600 seconds, the temperature becomes <EM>*UNKNOWN*</EM>.  The
+minimum acceptable value is -273 and the maximum is 5000.</P>
+<P>A few archives areas are also defined. The first stores the
+temperatures supplied for 100 hours (1200 * 300 seconds = 100
+hours). The second RRA stores the minimum temperature recorded over
+every hour (12 * 300 seconds = 1 hour), for 100 days (2400 hours). The
+third and the fourth RRA's do the same with the for the maximum and
+average temperature, respectively.</P>
 <P>
 <HR>
-<H1><A NAME="AUTHOR">AUTHOR</A></H1>
-<P>
-Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;
+<H1><A NAME="author">AUTHOR</A></H1>
+<P>Tobias Oetiker &lt;<A HREF="mailto:oetiker at ee.ethz.ch">oetiker at ee.ethz.ch</A>&gt;</P>
 
 </BODY>
 

Modified: trunk/orca/packages/rrdtool-1.0.33/perl-shared/t/base.t
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/perl-shared/t/base.t	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/perl-shared/t/base.t	Sat Jul 13 21:26:35 2002
@@ -1,6 +1,6 @@
 #! /usr/bin/perl 
 
-BEGIN { $| = 1; print "1..5\n"; }
+BEGIN { $| = 1; print "1..7\n"; }
 END {
   print "not ok 1\n" unless $loaded;
   unlink "demo.rrd";
@@ -48,7 +48,7 @@
 RRDs::create $RRD1, @options;
 
 my $ERROR = RRDs::error;
-ok("create", !$ERROR);							#  2
+ok("create 1", !$ERROR);							#  2
 if ($ERROR) {
   die "$0: unable to create `$RRD1': $ERROR\n";
 }
@@ -57,7 +57,7 @@
 RRDs::create $RRD2, @options;
 
 $ERROR= RRDs::error;
-ok("creat",!$ERROR);							#  3
+ok("create 2",!$ERROR);							#  3
 if ($ERROR) {
   die "$0: unable to create `$RRD2': $ERROR\n";
 }
@@ -66,7 +66,7 @@
 if ($ERROR = RRDs::error) {
   die "$0: unable to get last `$RRD1': $ERROR\n";
 }
-ok("last", $last == $START);						#  4
+ok("last 1", $last == $START);						#  4
 
 $last = RRDs::last $RRD2;
 if ($ERROR = RRDs::error) {
@@ -93,12 +93,16 @@
   push(@options, "$t:$data");
   RRDs::update $RRD1, "$t:$data";
   if ($ERROR = RRDs::error) {
-    die "$0: unable to update `$RRD1': $ERROR\n";
+    warn "$0: unable to update `$RRD1': $ERROR\n";
   }
 }
 
+ok("update 1",!$ERROR);							#  3
+
 RRDs::update $RRD2, @options;
 
+ok("update 2",!$ERROR);							#  3
+
 if ($ERROR = RRDs::error) {
   die "$0: unable to update `$RRD2': $ERROR\n";
 }

Modified: trunk/orca/packages/rrdtool-1.0.33/perl-shared/RRDs.xs
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/perl-shared/RRDs.xs	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/perl-shared/RRDs.xs	Sat Jul 13 21:26:35 2002
@@ -11,14 +11,18 @@
 #endif
 
 #include "../src/rrd_tool.h"
-#ifndef PL_na
-#define PL_na na
+
+/* perl 5.004 compatibility */
+#if PERLPATCHLEVEL < 5
+#define PL_sv_undef sv_undef
 #endif
+
 #define rrdcode(name) \
 		argv = (char **) malloc((items+1)*sizeof(char *));\
 		argv[0] = "dummy";\
 		for (i = 0; i < items; i++) { \
-		    char *handle=argv[i+1] = (char *) SvPV(ST(i),PL_na);\
+		    STRLEN len; \
+		    char *handle= SvPV(ST(i),len);\
 		    /* actually copy the data to make sure possible modifications \
 		       on the argv data does not backfire into perl */ \
 		    argv[i+1] = (char *) malloc((strlen(handle)+1)*sizeof(char)); \
@@ -32,7 +36,7 @@
 		} \
 		free(argv);\
 		\
-		if (rrd_get_error() != NULL) XSRETURN_UNDEF;
+		if (rrd_test_error()) XSRETURN_UNDEF;
 
 
 #ifdef WIN32
@@ -125,7 +129,8 @@
 		argv = (char **) malloc((items+1)*sizeof(char *));
 		argv[0] = "dummy";
 		for (i = 0; i < items; i++) { 
-		    char *handle=argv[i+1] = (char *) SvPV(ST(i),PL_na);
+		    STRLEN len;
+		    char *handle = SvPV(ST(i),len);
 		    /* actually copy the data to make sure possible modifications
 		       on the argv data does not backfire into perl */ 
 		    argv[i+1] = (char *) malloc((strlen(handle)+1)*sizeof(char));
@@ -172,7 +177,8 @@
 		argv = (char **) malloc((items+1)*sizeof(char *));
 		argv[0] = "dummy";
 		for (i = 0; i < items; i++) { 
-		    char *handle=argv[i+1] = (char *) SvPV(ST(i),PL_na);
+		    STRLEN len;
+		    char *handle= SvPV(ST(i),len);
 		    /* actually copy the data to make sure possible modifications
 		       on the argv data does not backfire into perl */ 
 		    argv[i+1] = (char *) malloc((strlen(handle)+1)*sizeof(char));
@@ -181,12 +187,12 @@
 		optind=0; opterr=0; 
 		rrd_clear_error();
 		rrd_fetch(items+1,argv,&start,&end,&step,&ds_cnt,&ds_namv,&data); 
-		if (rrd_test_error()) XSRETURN_UNDEF;
 		for (i=0; i < items; i++) {
 		    free(argv[i+1]);
 		}
 		free(argv);
-		/* convert the ds_namv into perl format */
+		if (rrd_test_error()) XSRETURN_UNDEF;
+                /* convert the ds_namv into perl format */
 		names=newAV();
 		for (ii = 0; ii < ds_cnt; ii++){
 		    av_push(names,newSVpv(ds_namv[ii],0));
@@ -198,8 +204,10 @@
 		retar=newAV();
 		for (i = start; i <= end; i += step){
 			line = newAV();
-			for (ii = 0; ii < ds_cnt; ii++)
-				av_push(line,newSVnv(*(datai++)));
+			for (ii = 0; ii < ds_cnt; ii++){
+ 			  av_push(line,(isnan(*datai) ? &PL_sv_undef : newSVnv(*datai)));
+			  datai++;
+			}
 			av_push(retar,newRV_noinc((SV*)line));
 		}
 		free(data);
@@ -210,5 +218,63 @@
 		PUSHs(sv_2mortal(newRV_noinc((SV*)retar)));
 
 
+SV*
+rrd_info(...)
+	PROTOTYPE: @	
+	PREINIT:
+		info_t *data,*save;
+                int i;
+                char **argv;
+		HV *hash;
+	CODE:
+		/* prepare argument list */
+		argv = (char **) malloc((items+1)*sizeof(char *));
+		argv[0] = "dummy";
+		for (i = 0; i < items; i++) { 
+		    STRLEN len;
+		    char *handle= SvPV(ST(i),len);
+		    /* actually copy the data to make sure possible modifications
+		       on the argv data does not backfire into perl */ 
+		    argv[i+1] = (char *) malloc((strlen(handle)+1)*sizeof(char));
+		    strcpy(argv[i+1],handle);
+ 	        }
+		optind=0; opterr=0; 
+                rrd_clear_error();
+                data=rrd_info(items+1, argv);
+                for (i=0; i < items; i++) {
+		    free(argv[i+1]);
+		}
+		free(argv);
+                if (rrd_test_error()) XSRETURN_UNDEF;
+                hash = newHV();
+                while (data) {
+		    save=data;
+		/* the newSV will get copied by hv so we create it as a mortal to make sure
+                   it does not keep hanging round after the fact */
+#define hvs(VAL) hv_store_ent(hash, sv_2mortal(newSVpv(data->key,0)),VAL,0)		    
+		    switch (data->type) {
+		    case RD_I_VAL:
+			if (isnan(data->value.u_val))
+			    hvs(&PL_sv_undef);
+			else
+			    hvs(newSVnv(data->value.u_val));
+			break;
+		    case RD_I_CNT:
+			hvs(newSViv(data->value.u_cnt));
+			break;
+		    case RD_I_STR:
+			hvs(newSVpv(data->value.u_str,0));
+			free(data->value.u_str);
+			break;
+		    }
+#undefine hvs
+		    free(data->key);
+		    data = data->next;		    
+		    free(save);
+		}
+                free(data);
+                RETVAL = newRV_noinc((SV*)hash);
+       OUTPUT:
+		RETVAL
 
 

Modified: trunk/orca/packages/rrdtool-1.0.33/perl-shared/RRDs.pm
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/perl-shared/RRDs.pm	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/perl-shared/RRDs.pm	Sat Jul 13 21:26:36 2002
@@ -7,7 +7,7 @@
 
 require DynaLoader;
 
-$VERSION = 1.000131;
+$VERSION = 1.000331;
 
 bootstrap RRDs $VERSION;
 
@@ -23,6 +23,7 @@
   use RRDs;
   RRDs::error
   RRDs::last ...
+  RRDs::info ...
   RRDs::create ...
   RRDs::update ...
   RRDs::graph ...
@@ -37,22 +38,27 @@
 arguments to the functions listed in the SYNOPSIS are explained in the regular
 rrdtool documentation. The commandline call
 
- rrdtool update mydemo.rrd N:12:13
+ rrdtool update mydemo.rrd --template in:out N:12:13
 
 gets turned into
 
- RRDs::update ("mydemo.rrd", "N:12:13");
+ RRDs::update ("mydemo.rrd", "--template", "in:out", "N:12:13");
+
+Note that
+
+ --template=in:out
+
+is also valid.
+
 
 =head2 Error Handling
 
 The RRD functions will not abort your program even when they can not make
-sense out of the arguments you fed them. There are two ways to determine if
-an error has occured.
+sense out of the arguments you fed them.
 
-First the every function will return the value -1 if an error occured.
-Second, the function RRDs::error can be called to get the error message
-from the last function call. If RRDs::error does not return an error
-then the previous function has completed its task succesfully.
+The function RRDs::error should be called to get the error status
+after each function call. If RRDs::error does not return anything
+then the previous function has completed its task successfully.
 
  use RRDs;
  RRDs::update ("mydemo.rrd","N:12:13");
@@ -61,23 +67,32 @@
 
 =head2 Return Values
 
-The functions RRDs::last, RRDs::graph and RRDs::fetch return their
+The functions RRDs::last, RRDs::graph, RRDs::info and RRDs::fetch return their
 findings.
 
-RRDs::last returns a single INTEGER representing the last update time.
+B<RRDs::last> returns a single INTEGER representing the last update time.
 
  $lastupdate = RRDs::last ...
 
-RRDs::graph returns an pointer to an ARRAY containing the x-size and y-size of the
+B<RRDs::graph> returns an pointer to an ARRAY containing the x-size and y-size of the
 created gif and results of the PRINT arguments.
 
  ($averages,$xsize,$ysize) = RRDs::graph ...
  print "Gifsize: ${xsize}x${ysize}\n";
  print "Averages: ", (join ", ", @$averages);
 
-RRDs::fetch is the most complex of the pack regarding return values. There are
-4 values. Two normal integers, a pointer to an array and a pointer to a
-array of pointers.
+B<RRDs::info> returns a pointer to a hash. The keys of the hash
+represent the property names of the rrd and the values of the hash are
+the values of the properties.  
+
+ $hash = RRDs::info "example.rrd";
+ foreach my $key (keys %$hash){
+   print "$key = $$hash{$key}\n";
+ }
+
+B<RRDs::fetch> is the most complex of
+the pack regarding return values. There are 4 values. Two normal
+integers, a pointer to an array and a pointer to a array of pointers.
 
   my ($start,$step,$names,$data) = RRDs::fetch ... 
   print "Start:       ", scalar localtime($start), " ($start)\n";
@@ -98,6 +113,6 @@
 
 =head1 AUTHOR
 
-Tobias Oetiker <oeitker at ee.ethy.ch>
+Tobias Oetiker E<lt>oetiker at ee.ethz.chE<gt>
 
 =cut

Modified: trunk/orca/packages/rrdtool-1.0.33/perl-shared/Makefile.PL
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/perl-shared/Makefile.PL	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/perl-shared/Makefile.PL	Sat Jul 13 21:26:36 2002
@@ -1,18 +1,19 @@
 use ExtUtils::MakeMaker;
+use Config;
 # See lib/ExtUtils/MakeMaker.pm for details of how to influence
 # the contents of the Makefile that is written.
 
 # Specify the location of the archive containing PIC compiled object files.
-my $librrd = -f "../src/.libs/librrd_private.a" ? '../src/.libs/librrd_private.a' : '../src/.libs/librrd_private.al'  ;
+my $librrd = "-L../src/.libs/ -lrrd_private"  ;
 
 WriteMakefile(
     'NAME'         => 'RRDs',
     'VERSION_FROM' => 'RRDs.pm', # finds $VERSION
-    'OPTIMIZE'     => '-g',
+    'DEFINE'	   => "-DPERLPATCHLEVEL=$Config{PATCHLEVEL}",
     'INC'          => '-I../src -I../gd1.3',
     # where to look for the necessary libraries 
     # Perl will figure out which one is valid
-    'depend'	   => {'RRDs.c' => $librrd},
+    'depend'	   => {'RRDs.c' => "../src/.libs/librrd_private.a"},
     'dynamic_lib'  => {'OTHERLDFLAGS' => "$librrd -lm"},
     'realclean'    => {FILES => 't/demo?.rrd t/demo?.gif' }
 );

Modified: trunk/orca/packages/rrdtool-1.0.33/CHANGES
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/CHANGES	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/CHANGES	Sat Jul 13 21:26:36 2002
@@ -2,6 +2,373 @@
 ---------------------------
 - bugfix, + enhancement, * contrib, = RELEASE
 ---------------------------------------------
+= 1.0.33 2001/02/22 -- Tobi
+
+- 2001/02/20 -- Tobi
+  yet another file ... pod in perl 5.005 is a bitch ... 
+
+= 1.0.32 2001/02/20 -- Tobi
+
+- 2001/02/20 -- Tobi
+  still one file missing ... now it should work with old perls ... 
+  was all about the format of .pod manpages anyway ... the software
+  has not changed except for the version number
+
+= 1.0.31 2001/02/20 -- Tobi
+
+- 2001/02/20 -- Tobi
+  do not require perl 5.6 anymore ... 5.005 should be fine as well
+
+= 1.0.30 2001/02/19 -- Tobi
+
+- 2001/02/19 -- Alex
+  be more cautious when not redrawing a graph because of --lazy
+
++ 2001/02/19 -- Tobias Oetikr <oetiker at ee.ethz.ch>
+  added --help about --step to rrdgraph
+
+= Beta 1.0.29
+
++ 2001/02/11 -- Roman Hoogant <rhoogant at ee.ethz.ch>
+  add unix time to rrddump comment
+
+- 2001/02/11 -- Terminator rAT <karl_schilke at eli.net>
+  support --x-grid strings with space
+
+- 2001/02/11 -- Tobi
+  upgraded to libpng 1.0.9
+
++ 2001/02/11 -- Jesús Couto Fandiño
+  spanish translation of rrdtutorial
+
+- 2001/02/11 -- Alex
+  new well commented reduce_data implementation for rrd_graph
+
+- 2001/02/11 -- Alex
+  off by 1 fix for data_calc (now the results should be more the way you
+  expect them to be)
+
+* 2001/02/11 -- Bill Nash <billn at billn.net>
+  snmpstats contrib
+
++ 2001/02/10 -- Christophe VG <Christophe.VanGinneken at ubizen.com>
+  --no-legend option for rrd_graph
+
+* 2001/02/10 -- claus norrbohm <james at type-this.com>
+  contrib rrdexplorer (aka clickable rrd graphs)
+
+* 2001/02/10 -- Gilles LAMIRAL lamiral at mail.dotcom.fr
+  contrib rrdview
+
++ 2001/02/07 -- Tobi
+  added a standalone version of rrdupdate which is MUCH smaller as it does
+  not have any of the graphic libs linked
+
+- 2001/02/03 -- Alex
+  in rrdgraph, CDEF comparisons were returning *UNKNOWN* if one of the
+  operands was unknown. The correct behaviour is to return false (0)
+
+- 2001/02/03 -- Shane O'Donnell <shaneo at opennms.org>
+  make graph to stdout work in win32 (no more crlf)
+
++ 2001/02/03 -- Tobi
+  added new CDEF keyword: LTIME this is like TIME but for localtime
+  it takes the local timezone as well as daylight saving time into account.
+
+- 2001/02/03 -- Tuc <ttsg at ttsg.com>
+  bsdi3* does not need -fPIC, actually it hates this so much
+  that it does not compile the IEEE test if its defined. Modified
+  the ltconfig to treat it like beos, irix when it comes to -fPIC 
+
+- 2001/02/03 -- Petr Holub <hopet at chemi.muni.cz>
+  add check to configure for -OPT:IEEE_comparisons=ON (cc on IRIX)
+
+- 2001/02/03 -- Tobi & Jakob Ilves <jakob.ilves at oracle.com>
+  It seems HPUX does not libraries being built with -fPIC
+  so I am now trying to test for hpux and will replace any -fPIC in CFLAGS
+  with -fpic ... hope this helps
+
++ 2001/02/03 -- Mike Mitchell <mcm at unx.sas.com>
+  Modified the code for the alternate autoscale to change the scale of the
+  graph so that at least two major grid lines will be present with
+  meaningful labels
+
+- 2001/02/03 -- Tobi
+  added link to bin_dec_hex in tutorial
+
++ 2001/02/03 -- Tobi
+  added explanation on % in PRINT to the rrdgraph manpage
+
++ 2001/02/03 -- "BAARDA, Don" <don.baarda at baesystems.com>
+  explanation on the connection between Step and Heartbeat
+  added to rrdcreate manpage
+
++ 2001/02/03 -- Tobi
+  added special config 'none' to --x-grid and --y-grid options
+  of rrdgraph.
+
++ 2001/02/03 -- Tobi & Gilles Lamiral <lamiral at mail.dotcom.fr>
+  added strerror messages to fopen calls
+
++ 2001/02/03 -- Tobi
+  added --step option to rrdgraph which allows to set the 
+  dataresolution lower than the graph resolution
+
++ 2001/02/03 -- Craig Anderson <craig at abstract.co.nz>
+  allow to fix the exponent for the y axis (--unit-exponent)
+
++ 2000/11/12 -- Alex
+  replace dump with info in rrd resize manpage
+
++ 2000/11/05 -- David Schweikert <dws at ee.ethz.ch>
+  added section on total values to the HOW TO MEASURE part of rrdcreate doc 
+
++ 2000/11/05 -- Tobi
+  added section on HOW TO MEASURE to rrdcreate doc
+
+- 2000/10/17 -- Tobi
+  fixed configure ... caching for the IEEE tests was totally broken
+
+= 1.0.28 2000/09/14 -- Tobi
+- 2000/09/14 -- Betty Lee <bettylee at eng.concentric.net>
+  install rule for perl module was broken
+
+= 1.0.27 2000/09/10 -- Tobi
+- 2000/09/12 -- Tobi
+  fixed xff description in rrd_format.h and added xff to rrddump, rrdrestore, rrdinfo
+  *
+  * NOTE if you are generating rrd xml data, you must add the xff parameter now !
+  *
+
+= 1.0.26 2000/09/10 -- Tobi
+* 2000/08/28 -- Joe Miller <joeym at inficad.com>
+  PHP4 Bindings
+
+- 2000/08/21 -- Tobi
+  rrd_cgi.c parser now uses isspace as keyword separator identification
+
++ 2000/08/07 -- Tobi
+  added rrd.rows property to rrd_info
+
+- 2000/08/05 -- Tobi (after discussion on ML)
+  bsd install does not know -d modified Makefile to accomodate for this    
+
+- 2000/07/17 -- Tobi
+  Rewrote doc entry for --upper-limit in rrdgraph.pod
+
+- 2000/07/13 -- Tobi with lots of debugging help from Patrick Rother <krd at roka.net>
+  identified memory leak in rrd_info and RRDs.xs (mortals are cool)
+  
+= 1.0.25 2000/07/12 -- Tobi
+- 2000/06/26 -- Rainer.Bawidamann at informatik.uni-ulm.de
+  fix for segfault in rrd_info.c ... next->next was not initialized
+	
+= 1.0.24 2000/06/13 -- Tobi
+- 2000/06/13 -- Michael O'Reilly <Michael.O'Reilly at cwo.com.au>
+  RRDs:fetch was broken ... (missing braces in RRDs.xs)
+
+= 1.0.23 2000/06/12 -- Tobi
+* 2000/06/12 -- Bert Driehuis <bert_driehuis at nl.compuware.com>                                                 
+  Updated contrib/killspike
+
+- 2000/06/12 -- Tobi
+  RRDs.xs (perl module) error checking was broken after modification
+  of rrd_error ... 
+
+= 1.0.22 2000/06/10 -- Tobi
+- 2000/06/10 -- Tobi
+  added more complexity to IEEE test (sin(0.0) instead of 0.0))
+  this prevents the tests from being optimized away by some
+  compilers and thus rendeing them ineffctive ...
+
+- 2000/06/09 -- Tobi
+  Updated RRDs manpage better examples and correct Error info
+
++ 2000/06/09 -- Sean Summers <sean at Fenstermaker.com>
+  added RPM rrdtool.spec file
+
+- 2000/06/09 -- Philippe.Simonet at swisscom.com
+  added some missing fclose calles to rrd_tune
+
++ 2000/06/09 -- Sean McCreary mccreary at xoanon.colorado.edu
+  created rrd.h for people using librrd directly ...
+
+- 2000/06/09 -- Bruce Campbell <bruce.campbell at apnic.net>
+  properly added DS_NAM_SIZE in a few places a number was in use
+  allow - in DS names
+
++ 2000/06/09 --  Rainer Bawidamann <Rainer.Bawidamann at informatik.uni-ulm.de>
+  proper parsing for -h switch in rrdtool
+
++ 2000/06/09 -- Tobi
+  Added FLOOR and CEIL functions to CDEF
+
+- 2000/06/09 -- Tobi
+  Make sure the fpmask and setsig defines get passed on the the Makefile.PL
+  when run ... this should fix some freebsd issues
+
++ 2000/05/22 -- Albert Chin-A-Young <china at thewrittenword.com>
+  by default do not try to modify the compile options of the perl module
+  this just breaks way to often ... --with-perl-options allows to
+  override this
+
++ 2000/05/16 -- Tobi &  Sean McCreary mccreary at xoanon.colorado.edu
+  added strerror messages to open fails ... 
+
+- 2000/05/16 -- Tobi &  Sean McCreary mccreary at xoanon.colorado.edu
+  remove unnecessary maloc stuff from rrd_error.c
+
+- 2000/05/16 -- Tobi
+  made .so detectionfor installing the perl module  more robust ...
+
+- 2000/05/07 -- Tobi
+  made sure RRDs.xs returns undef for UNKNOWN values
+  in rrdfetch results
+
+- 2000/05/02 -- Alex
+  cdeftutorial ... on example was wrong
+
+= 1.0.21 2000/05/02 -- Tobi
+
+- 2000/05/02 -- Tobi
+  Added propper patchlevel detection to Makefile.PL. Fight build problems
+  with perl 5.6.0
+
+= 1.0.20 2000/05/02  -- Tobi
+
+- 2000/04/30 -- Albert Chin-A-Young <china at thewrittenword.com>
+  Determine shared library extension via perl Config.pm module
+  to use when installing RRDs shared library.
+
+- 2000/04/29 -- Tobi
+  applied patches a b and c to libpng
+
+- 2000/04/29 -- Albert Chin-A-Young <china at thewrittenword.com>
+  Removed HP-UX 10.20, 11.00 sections from config/config.h.in as
+  they are no longer needed (was already removed from configure.in).
+  Shared library for HP-UX is .sl not .so (lame update to Makefile.in).
+  Redefine finite in terms if isfinite in config/config.h.in.
+
+= 1.0.19 2000/04/29  -- Tobi
+
++ 2000/04/29 -- Tobi
+  upgraded libpng to version 1.0.6
+
+- 2000/04/29 -- Albert Chin-A-Young <china at thewrittenword.com>
+  portability cleanup of configure system things now build on
+  Everything builds on Solaris 2.5.1, 2.6, 2.7/SPARC, 2.7/x86 (without
+  optimizations turned on for the Sun C compiler), HP-UX 10.20, HP-UX
+  11.00, and Digital UNIX 4.0D.
+
+= 1.0.18 2000/04/29  -- Tobi
+
+- 2000/04/29 -- Tobi
+  tinkerd with tcl bindings ... unfortunately then do not
+  link clean ... any gurus ?
+
+- 2000/04/29 -- Tobi
+  fixed build process for cases where --enable-shared was given
+
+- 2000/04/29 -- Rainer Nagel <rainer at angor.de>
+  malloc error in rrdcgi fixed ... - 2 potential segfaults
+
+- 2000/04/29 -- Rainer.Bawidamann at informatik.uni-ulm.de
+  errors in HPUX ifdefs in configure and acconfig.h
+
+- 2000/04/29 -- Rainer.Bawidamann at informatik.uni-ulm.de
+  added perl 5.004 compatibility back to RRD.xs
+
+- 2000/04/18 -- Edouard Lagache <elagache at caida.org>
+  FileDescriptor Leak in Lazy option fixed
+
+= 1.0.17 2000/04/16  -- Tobi
+
++ 2000/04/13 -- Tobi (inspired by Rainer.Bawidamann at informatik.uni-ulm.de)
+  people keep asking for this ... here you go: rrd_info ... check
+  the  manpage.
+
+- 2000/04/13 -- Tobi
+  some people just love bsd make ... it almost worked ... now it does.
+  But please just use gnu make to stay out of trouble
+
+= 1.0.16 2000/04/06  -- Tobi
+
+- 2000/04/06 -- Tobi
+  added missing rrd_format.h back into the distro .. grrrr
+
+= 1.0.15 2000/04/06  -- Tobi
+
+- 2000/04/03 -- Thomas Parmelan <tom at proxad.net>
+  alloc error in RPN code of rrd_graph found ... and fixed
+
+- 2000/04/03 -- Tobi
+  Made tcl install optional as suggested by E. Lagache
+
+- 2000/04/03 -- Simon Leinen <simon at limmat.switch.ch>
+  TCL Build Fix
+
+- 2000/04/03 -- Joe Moore <Joe.Moore at sdrc.com>
+  configure.in had wrong error message for nan==nan
+
+= 1.0.14 2000/04/02 -- Tobi
+
+- 2000/04/02 -- Tobi
+  added function prototypes to rrd_graph and rrd_restore
+
+- 2000/04/01 -- Tobi
+  made perl build more robust
+
+* 2000/04/01 -- Claus Norrbohm <claus.norrbohm at pbs.dk>
+  clickgraph contrib ... interactive data explorer ...
+
+- 2000/03/26 -- Rainer Bawidamann <rb1 at mogwai.rz.uni-ulm.de>
+  fixes for TCL module compilation
+  rrdgraph dead code ...
+
++ 2000/03/26 -- Tobi
+  fetch pic flag from libtool ..
+
++ 2000/03/26 -- Frank Strauss strauss at ibr.cs.tu-bs.de
+  TCL bindings for rrdtool
+
+- 2000/03/26 -- Tobi
+  rrd_update should not change its argv string ... this can be
+  fatal for external processes calling it .. 
+
++ 2000/03/26 -- Poul-Henning Kamp <phk at freebsd.org>
+  made sure the CDEF evaluator does not ever try to compare against NaN 
+  added new CDEF operators MIN,MAX,LIMIT
+ 
+- 2000/03/26 -- Larry Parmelee <parmelee at CS.Cornell.EDU>
+  examples/pipe-demo.pl.in was still using %f instead of %lf
+
+- 2000/03/26 -- Tobi
+  added some check to free calls in rrdcgi so that we don't free anything
+  which is already NULL ... freebsd hates this ...
+
++ 2000/03/26 -- Tobi
+  Added RRD:GETENV to Pass 1 of rrdcgi (suggested by Jesper Skriver <jesper at skriver.dk>)
+
+- 2000/02/19 -- Bernard Fischer <bfischer at syslog.ch>
+  added casting to floating point routines where needed. (get 64bit working)
+ 
++ 2000/02/19 -- Bernard Fischer <bfischer at syslog.ch>
+  added --alt-autoscale-max to autoscale only on the max value.
+
+* 2000/02/14 -- Joey Miller <joeym at inficad.com>
+  contributed php3 bindings contrib/php3
+
+- 2000/03/26 -- Tobi
+  Removed PL_na reference from RRD.xs ... it does now work with Perl 5.6
+
++ 2000/03/02 -- Tobi
+  added many more warning switches to rrdtool
+
+- 2000/03/03 -- Tobias Weingartner <weingart at cs.ualberta.ca>
+  out of bounds error in OP_PREV processing (rrd_graph.c) fixed  
+
+- 2000/02/25 -- Tobi
+  hpux uses RRDs.sl instead of RRDs.so ... I have changed the Makefile to handle this.
 
 = 1.0.13 2000/02/13 -- Tobi
 

Modified: trunk/orca/packages/rrdtool-1.0.33/Makefile.am
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/Makefile.am	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/Makefile.am	Sat Jul 13 21:26:37 2002
@@ -1,31 +1,32 @@
 ## Process this file with automake to produce Makefile.in
 RSYNC = rsync --rsh=ssh
+
 # build the following subdirectories
-SUBDIRS = cgilib-0.4 config gd1.3 zlib-1.1.3 libpng-1.0.3 src doc examples contrib
+SUBDIRS = cgilib-0.4 config gd1.3 zlib-1.1.3 libpng-1.0.9 \
+          src doc examples contrib tcl
 
 # the following files are not mentioned in any other Makefile
-EXTRA_DIST = COPYRIGHT CHANGES NT-BUILD-TIPS.txt TODO CONTRIBUTORS  \
+EXTRA_DIST = COPYRIGHT CHANGES NT-BUILD-TIPS.txt TODO CONTRIBUTORS rrdtool.spec \
  perl-piped/MANIFEST perl-piped/README perl-piped/rrdpl.ds? \
  perl-piped/RRDp.pm perl-piped/Makefile.PL  perl-piped/t/base.t \
  perl-shared/MANIFEST perl-shared/README perl-shared/RRDs.xs \
  perl-shared/ntmake.pl perl-shared/Makefile.PL perl-shared/t/base.t \
  perl-shared/rrdpl.ds? perl-shared/RRDs.pm
 
-#
-
 CLEANFILES = config.cache
 
 # lets schedule the perl stuff for installation
+# the special call to install-sh is because the -d switch is not portable
 install-data-local:
-	$(INSTALL) -d -m 755 $(prefix)/lib/perl/auto/RRDs
-	$(INSTALL) -m 644 perl-piped/RRDp.pm $(prefix)/lib/perl
-	$(INSTALL) -m 644 perl-shared/RRDs.pm $(prefix)/lib/perl
-	$(INSTALL) -m 644 perl-shared/blib/arch/auto/RRDs/RRDs.bs $(prefix)/lib/perl/auto/RRDs
-	$(INSTALL) -m 755 perl-shared/blib/arch/auto/RRDs/RRDs.so $(prefix)/lib/perl/auto/RRDs
+	./config/mkinstalldirs $(DESTDIR)$(prefix)/lib/perl/auto/RRDs
+	$(INSTALL) -m 644 perl-piped/RRDp.pm $(DESTDIR)$(prefix)/lib/perl
+	$(INSTALL) -m 644 perl-shared/RRDs.pm $(DESTDIR)$(prefix)/lib/perl
+	$(INSTALL) -m 644 perl-shared/blib/arch/auto/RRDs/RRDs.bs $(DESTDIR)$(prefix)/lib/perl/auto/RRDs
+	$(INSTALL) -m 755 perl-shared/blib/arch/auto/RRDs/RRDs. at SO_EXT@ $(DESTDIR)$(prefix)/lib/perl/auto/RRDs
 
 
 # use relaxed rules when building dists
-AUTOMAKE_OPTIONS= foreign
+AUTOMAKE_OPTIONS= foreign no-dependencies
 
 # where we keep local rules for automake
 ACLOCAL_M4= 	$(top_srcdir)/config/aclocal.m4
@@ -34,33 +35,24 @@
 
 # rules for building the perl module
 perl_piped: perl-piped/Makefile
-	cd perl-piped && $(MAKE)  OPTIMIZE="$(CFLAGS)" CC="$(CC)"
+	cd perl-piped && $(MAKE)
 
 perl-piped/Makefile: perl-piped/Makefile.PL
-	cd perl-piped && $(PERL) Makefile.PL
+	cd perl-piped && $(PERL) Makefile.PL $(PERL_MAKE_OPTIONS)
 
 perl_shared: perl-shared/Makefile
-	cd perl-shared && $(MAKE) OPTIMIZE="$(CFLAGS)" CC="$(CC)"
+	cd perl-shared && $(MAKE)
 
 perl-shared/Makefile: perl-shared/Makefile.PL
-	cd perl-shared && $(PERL) Makefile.PL
+	cd perl-shared && $(PERL) Makefile.PL $(PERLFLAGS) $(PERL_MAKE_OPTIONS)
 
 # add the following to the all target
 all-local:	@COMP_PERL@
 
-# add to install
-
-#to-autoconf:
-#	aclocal -I config -I config/libtool --output=config/aclocal.m4
-#	automake --foreign
-#	autoconf --localdir=config
-#	autoheader --localdir=config
-#	./configure
-
 to-docs: to-versync
-	(cd doc && $(MAKE) clean && $(MAKE))
+	(cd doc && $(MAKE) clean && $(MAKE) && $(MAKE) pdf)
+	(cd website && wmk-1.7.4 -f manual tutorial contributors.wml && ./site-sync )
 
-#to-autoconf
 to-versync: 
 	perl -i -p -e '"$(VERSION)" =~ /(\d+)\.(\d+)\.(\d+)/; $$v=sprintf("%1d.%02d0%02d1" ,$${1},$${2},$${3}); s|VERSION\s*=\s*[\d.]+|VERSION = $$v|' perl-*/RRD?.pm
 	perl -i -p -e 's|RRDtool\s+\d+\.\d+\.\d+ |RRDtool $(VERSION) |' src/*.[ch]
@@ -69,8 +61,10 @@
 	mv $(PACKAGE)-$(VERSION).tar.gz archive
 
 to-scp: to-dist
-	$(RSYNC) CHANGES  archive/$(PACKAGE)-$(VERSION).tar.gz oetiker at tardis.ee.ethz.ch:/home/oetiker/public_html/webtools/rrdtool/pub/
-	$(RSYNC) CHANGES archive/$(PACKAGE)-$(VERSION).tar.gz tobi at ipn.caida.org:/ipn/web/Tools/RRDtool/pub/
+	cp CHANGES  archive/$(PACKAGE)-$(VERSION).tar.gz /home/oetiker/public_html/webtools/rrdtool/pub/
+	(cd /home/oetiker/public_html/webtools/rrdtool/pub; rm $(PACKAGE).tar.gz; ln -s $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE).tar.gz)
+
+#	$(RSYNC) CHANGES archive/$(PACKAGE)-$(VERSION).tar.gz tobi at ipn.caida.org:/ipn/web/Tools/RRDtool/pub/
 
 site-perl-inst: site-perl-install
 
@@ -78,6 +72,9 @@
 	cd perl-piped && $(MAKE) install
 	cd perl-shared && $(MAKE) install
 
+site-tcl-install:
+	cd tcl && $(MAKE) tcl-install
+
 clean-local:
 	cd perl-piped && test -f Makefile && $(MAKE) clean || true
 	cd perl-shared && test -f Makefile && $(MAKE) clean || true

Modified: trunk/orca/packages/rrdtool-1.0.33/gd1.3/gd.h
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/gd1.3/gd.h	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/gd1.3/gd.h	Sat Jul 13 21:26:37 2002
@@ -89,15 +89,15 @@
 void gdImageDestroy(gdImagePtr im);
 void gdImageSetPixel(gdImagePtr im, int x, int y, int color);
 int gdImageGetPixel(gdImagePtr im, int x, int y);
-void gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
+void gdImageLine(gdImagePtr im, int xA, int yA, int xB, int yB, int color);
 /* For backwards compatibility only. Use gdImageSetStyle()
 	for much more flexible line drawing. */
-void gdImageDashedLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
+void gdImageDashedLine(gdImagePtr im, int xA, int yA, int xB, int yB, int color);
 /* Corners specified (not width and height). Upper left first, lower right
  	second. */
-void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
+void gdImageRectangle(gdImagePtr im, int xA, int yA, int xB, int yB, int color);
 /* Solid bar. Upper left corner first, lower right corner second. */
-void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
+void gdImageFilledRectangle(gdImagePtr im, int xA, int yA, int xB, int yB, int color);
 int gdImageBoundsSafe(gdImagePtr im, int x, int y);
 void gdImageChar(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color);
 void gdImageCharUp(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color);

Modified: trunk/orca/packages/rrdtool-1.0.33/gd1.3/Makefile.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/gd1.3/Makefile.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/gd1.3/Makefile.in	Sat Jul 13 21:26:37 2002
@@ -10,11 +10,6 @@
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
-#AUTOMAKE_OPTIONS        =  foreign
-
-#ACLOCAL_M4 = $(top_srcdir)/config/aclocal.m4
-#AUTOHEADER = @AUTOHEADER@ --localdir=config
-
 
 SHELL = @SHELL@
 
@@ -69,15 +64,26 @@
 target_alias = @target_alias@
 target_triplet = @target@
 CC = @CC@
-CFLAGS = @CFLAGS@
 CGI_LIB_DIR = @CGI_LIB_DIR@
 COMP_PERL = @COMP_PERL@
 CPP = @CPP@
 GD_LIB_DIR = @GD_LIB_DIR@
 LIBTOOL = @LIBTOOL@
+NROFF = @NROFF@
 PERL = @PERL@
+PERLFLAGS = @PERLFLAGS@
+PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PNG_LIB_DIR = @PNG_LIB_DIR@
 RANLIB = @RANLIB@
+SO_EXT = @SO_EXT@
+TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
+TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
+TCL_PREFIX = @TCL_PREFIX@
+TCL_SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@
+TCL_SHLIB_LD = @TCL_SHLIB_LD@
+TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+TROFF = @TROFF@
+VERSION = @VERSION@
 ZLIB_LIB_DIR = @ZLIB_LIB_DIR@
 
 noinst_LTLIBRARIES = librrd_gd.la
@@ -102,6 +108,7 @@
 librrd_gd_la_OBJECTS =  gd.lo gdfontg.lo gdfontl.lo gdfontmb.lo \
 gdfonts.lo gdfontt.lo gdlucidab10.lo gdlucidab12.lo gdlucidab14.lo \
 gdlucidan10.lo gdlucidan12.lo gdlucidan14.lo
+CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
@@ -110,7 +117,6 @@
 
 
 PACKAGE = @PACKAGE@
-VERSION = @VERSION@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
@@ -217,7 +223,7 @@
 	@for file in $(DISTFILES); do \
 	  d=$(srcdir); \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$/$$file $(distdir)/$$file; \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
 	    test -f $(distdir)/$$file \
 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \

Modified: trunk/orca/packages/rrdtool-1.0.33/gd1.3/Makefile.am
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/gd1.3/Makefile.am	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/gd1.3/Makefile.am	Sat Jul 13 21:26:38 2002
@@ -1,10 +1,5 @@
 ## Process this file with automake to produce Makefile.in
 
-#AUTOMAKE_OPTIONS        =  foreign
-
-#ACLOCAL_M4 = $(top_srcdir)/config/aclocal.m4
-#AUTOHEADER = @AUTOHEADER@ --localdir=config
-
 noinst_LTLIBRARIES  = librrd_gd.la
 
 librrd_gd_la_SOURCES = \

Modified: trunk/orca/packages/rrdtool-1.0.33/gd1.3/gd.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/gd1.3/gd.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/gd1.3/gd.c	Sat Jul 13 21:26:38 2002
@@ -1284,12 +1284,12 @@
 static unsigned int compute_triangle_count(unsigned int count, unsigned int nrepcodes)
 {
  unsigned int perrep;
- unsigned int cost;
+ unsigned int ncost;
 
- cost = 0;
+ ncost = 0;
  perrep = (nrepcodes * (nrepcodes+1)) / 2;
  while (count >= perrep)
-  { cost += nrepcodes;
+  { ncost += nrepcodes;
     count -= perrep;
   }
  if (count > 0)
@@ -1297,9 +1297,9 @@
     n = isqrt(count);
     while ((n*(n+1)) >= 2*count) n --;
     while ((n*(n+1)) < 2*count) n ++;
-    cost += n;
+    ncost += n;
   }
- return(cost);
+ return(ncost);
 }
 
 static void max_out_clear(void)

Modified: trunk/orca/packages/rrdtool-1.0.33/examples/piped-demo.pl.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/examples/piped-demo.pl.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/examples/piped-demo.pl.in	Sat Jul 13 21:26:39 2002
@@ -118,12 +118,12 @@
         "AREA:alpha#0022e9:Alpha",
         "STACK:beta#00b871:Beta",
         "STACK:calc#ff0091:Calc\\j",
-	"PRINT:alpha:AVERAGE:'Average Alpha\\: %1.2f %S'",
-	"PRINT:alpha:MIN:'Min Alpha\\: %1.2f %S'",
-	"PRINT:alpha:MAX:'Max Alpha\\: %1.2f %S'",
-	"GPRINT:calc:AVERAGE:'Average calc\\: %1.2f %S\\r'",
-	"GPRINT:calc:MIN:'Min calc\\: %1.2f %S'",
-	"GPRINT:calc:MAX:'Max calc\\: %1.2f %S'",
+	"PRINT:alpha:AVERAGE:'Average Alpha\\: %1.2lf %S'",
+	"PRINT:alpha:MIN:'Min Alpha\\: %1.2lf %S'",
+	"PRINT:alpha:MAX:'Max Alpha\\: %1.2lf %S'",
+	"GPRINT:calc:AVERAGE:'Average calc\\: %1.2lf %S\\r'",
+	"GPRINT:calc:MIN:'Min calc\\: %1.2lf %S'",
+	"GPRINT:calc:MAX:'Max calc\\: %1.2lf %S'",
         "VRULE:".($now-3600)."#008877:'60 Minutes ago'",
         "COMMENT:'\\s'",
         "COMMENT:'Graph created on: ".localtime(time())."\\c'";
@@ -143,16 +143,3 @@
   $GRUNS/($real2-$real1);
 
 RRDp::end;
-
-
-
-
-
-
-
-
-
-
-
-
-

Modified: trunk/orca/packages/rrdtool-1.0.33/examples/Makefile.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/examples/Makefile.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/examples/Makefile.in	Sat Jul 13 21:26:39 2002
@@ -68,15 +68,26 @@
 target_alias = @target_alias@
 target_triplet = @target@
 CC = @CC@
-CFLAGS = @CFLAGS@
 CGI_LIB_DIR = @CGI_LIB_DIR@
 COMP_PERL = @COMP_PERL@
 CPP = @CPP@
 GD_LIB_DIR = @GD_LIB_DIR@
 LIBTOOL = @LIBTOOL@
+NROFF = @NROFF@
 PERL = @PERL@
+PERLFLAGS = @PERLFLAGS@
+PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PNG_LIB_DIR = @PNG_LIB_DIR@
 RANLIB = @RANLIB@
+SO_EXT = @SO_EXT@
+TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
+TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
+TCL_PREFIX = @TCL_PREFIX@
+TCL_SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@
+TCL_SHLIB_LD = @TCL_SHLIB_LD@
+TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+TROFF = @TROFF@
+VERSION = @VERSION@
 ZLIB_LIB_DIR = @ZLIB_LIB_DIR@
 
 EXTRA_DIST = cgi-demo.cgi.in    piped-demo.pl.in   shared-demo.pl.in stripes.pl.in bigtops.pl.in minmax.pl.in
@@ -94,7 +105,6 @@
 
 
 PACKAGE = @PACKAGE@
-VERSION = @VERSION@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
@@ -152,7 +162,7 @@
 	@for file in $(DISTFILES); do \
 	  d=$(srcdir); \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$/$$file $(distdir)/$$file; \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
 	    test -f $(distdir)/$$file \
 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \

Modified: trunk/orca/packages/rrdtool-1.0.33/examples/shared-demo.pl.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/examples/shared-demo.pl.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/examples/shared-demo.pl.in	Sat Jul 13 21:26:39 2002
@@ -54,7 +54,7 @@
 RRDs::create $RRD1, @options;
 
 my $ERROR = RRDs::error;
-ok("create", !$ERROR);								#  2
+ok("create A", !$ERROR);								#  2
 if ($ERROR) {
   die "$0: unable to create `$RRD1': $ERROR\n";
 }
@@ -63,7 +63,7 @@
 RRDs::create $RRD2, @options;
 
 $ERROR= RRDs::error;
-ok("creat",!$ERROR);								#  3
+ok("create B",!$ERROR);								#  3
 if ($ERROR) {
   die "$0: unable to create `$RRD2': $ERROR\n";
 }
@@ -72,13 +72,13 @@
 if ($ERROR = RRDs::error) {
   die "$0: unable to get last `$RRD1': $ERROR\n";
 }
-ok("last", $last == $START);							#  4
+ok("last A", $last == $START);							#  4
 
 $last = RRDs::last $RRD2;
 if ($ERROR = RRDs::error) {
   die "$0: unable to get last `$RRD2': $ERROR\n";
 }
-ok("last 2", $last == $START);							#  5
+ok("last B", $last == $START);							#  5
 
 print "* Filling $RRD1 and $RRD2 with $RUNS*5 values. One moment please ...\n";
 print "* If you are running over NFS this will take *MUCH* longer\n\n";

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngerror.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngerror.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngerror.c	Sat Jul 13 21:26:40 2002
@@ -1,11 +1,11 @@
 
 /* pngerror.c - stub functions for i/o and memory allocation
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This file provides a location for all error handling.  Users who
  * need special error handling are expected to write replacement functions
@@ -16,9 +16,11 @@
 #define PNG_INTERNAL
 #include "png.h"
 
-static void png_default_error PNGARG((png_structp png_ptr,
+static void /* PRIVATE */
+png_default_error PNGARG((png_structp png_ptr,
                                       png_const_charp message));
-static void png_default_warning PNGARG((png_structp png_ptr,
+static void /* PRIVATE */
+png_default_warning PNGARG((png_structp png_ptr,
                                         png_const_charp message));
 
 /* This function is called whenever there is a fatal error.  This function
@@ -26,7 +28,7 @@
  * you should supply a replacement error function and use png_set_error_fn()
  * to replace the error function at run-time.
  */
-void
+void PNGAPI
 png_error(png_structp png_ptr, png_const_charp message)
 {
    if (png_ptr->error_fn != NULL)
@@ -42,7 +44,7 @@
  * you should supply a replacement warning function and use
  * png_set_error_fn() to replace the warning function at run-time.
  */
-void
+void PNGAPI
 png_warning(png_structp png_ptr, png_const_charp message)
 {
    if (png_ptr->warning_fn != NULL)
@@ -62,26 +64,31 @@
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
 };
 
-static void
+static void /* PRIVATE */
 png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp message)
 {
    int iout = 0, iin = 0;
 
-   while (iin < 4) {
+   while (iin < 4)
+   {
       int c = png_ptr->chunk_name[iin++];
-      if (isnonalpha(c)) {
+      if (isnonalpha(c))
+      {
          buffer[iout++] = '[';
          buffer[iout++] = png_digit[(c & 0xf0) >> 4];
-         buffer[iout++] = png_digit[c & 0xf];
+         buffer[iout++] = png_digit[c & 0x0f];
          buffer[iout++] = ']';
-      } else {
-         buffer[iout++] = c;
+      }
+      else
+      {
+         buffer[iout++] = (png_byte)c;
       }
    }
 
    if (message == NULL)
       buffer[iout] = 0;
-   else {
+   else
+   {
       buffer[iout++] = ':';
       buffer[iout++] = ' ';
       png_memcpy(buffer+iout, message, 64);
@@ -89,15 +96,15 @@
    }
 }
 
-void
+void PNGAPI
 png_chunk_error(png_structp png_ptr, png_const_charp message)
 {
-   char msg[16+64];
+   char msg[18+64];
    png_format_buffer(png_ptr, msg, message);
    png_error(png_ptr, msg);
 }
 
-void
+void PNGAPI
 png_chunk_warning(png_structp png_ptr, png_const_charp message)
 {
    char msg[16+64];
@@ -110,21 +117,30 @@
  * function is used by default, or if the program supplies NULL for the
  * error function pointer in png_set_error_fn().
  */
-static void
+static void /* PRIVATE */
 png_default_error(png_structp png_ptr, png_const_charp message)
 {
 #ifndef PNG_NO_CONSOLE_IO
    fprintf(stderr, "libpng error: %s\n", message);
+#else
+   if (message)
+     /* make compiler happy */ ;
 #endif
 
-#ifdef USE_FAR_KEYWORD
+#ifdef PNG_SETJMP_SUPPORTED
+#  ifdef USE_FAR_KEYWORD
    {
       jmp_buf jmpbuf;
       png_memcpy(jmpbuf,png_ptr->jmpbuf,sizeof(jmp_buf));
       longjmp(jmpbuf, 1);
    }
-#else
+#  else
    longjmp(png_ptr->jmpbuf, 1);
+# endif
+#else
+   if (png_ptr)
+     /* make compiler happy */ ;
+   PNG_ABORT();
 #endif
 }
 
@@ -133,13 +149,16 @@
  * here if you don't want them to.  In the default configuration, png_ptr is
  * not used, but it is passed in case it may be useful.
  */
-static void
+static void /* PRIVATE */
 png_default_warning(png_structp png_ptr, png_const_charp message)
 {
 #ifndef PNG_NO_CONSOLE_IO
    fprintf(stderr, "libpng warning: %s\n", message);
+#else
+   if (message)
+     /* appease compiler */ ;
 #endif
-   if (png_ptr == NULL)
+   if (png_ptr)
       return;
 }
 
@@ -148,7 +167,7 @@
  * return to the calling routine or serious problems will occur.  The return
  * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
  */
-void
+void PNGAPI
 png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
    png_error_ptr error_fn, png_error_ptr warning_fn)
 {
@@ -162,7 +181,7 @@
  * functions.  The application should free any memory associated with this
  * pointer before png_write_destroy and png_read_destroy are called.
  */
-png_voidp
+png_voidp PNGAPI
 png_get_error_ptr(png_structp png_ptr)
 {
    return ((png_voidp)png_ptr->error_ptr);

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/README.rrdtool
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/README.rrdtool	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/README.rrdtool	Sat Jul 13 21:26:40 2002
@@ -1,2 +1,2 @@
-This version of libpng has been included with rrdtool. The scripts directory
-has been removed ... 
+This version of libpng has been included with rrdtool. The scripts and the
+contrib directories have been removed ... 

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwtran.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwtran.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwtran.c	Sat Jul 13 21:26:40 2002
@@ -1,11 +1,11 @@
 
 /* pngwtran.c - transforms the data in a row for PNG writers
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  */
 
 #define PNG_INTERNAL
@@ -14,11 +14,14 @@
 /* Transform the data according to the user's wishes.  The order of
  * transformations is significant.
  */
-void
+void /* PRIVATE */
 png_do_write_transformations(png_structp png_ptr)
 {
    png_debug(1, "in png_do_write_transformations\n");
 
+   if (png_ptr == NULL)
+      return;
+
 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
    if (png_ptr->transformations & PNG_USER_TRANSFORM)
       if(png_ptr->write_user_transform_fn != NULL)
@@ -79,7 +82,7 @@
  * row_info bit depth should be 8 (one pixel per byte).  The channels
  * should be 1 (this only happens on grayscale and paletted images).
  */
-void
+void /* PRIVATE */
 png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
 {
    png_debug(1, "in png_do_pack\n");
@@ -137,7 +140,7 @@
             {
                png_byte value;
 
-               value = (png_byte)(*sp & 0x3);
+               value = (png_byte)(*sp & 0x03);
                v |= (value << shift);
                if (shift == 0)
                {
@@ -169,7 +172,7 @@
             {
                png_byte value;
 
-               value = (png_byte)(*sp & 0xf);
+               value = (png_byte)(*sp & 0x0f);
                v |= (value << shift);
 
                if (shift == 0)
@@ -205,7 +208,7 @@
  * would pass 3 as bit_depth, and this routine would translate the
  * data to 0 to 15.
  */
-void
+void /* PRIVATE */
 png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
 {
    png_debug(1, "in png_do_shift\n");
@@ -311,7 +314,7 @@
             png_uint_16 value, v;
             int j;
 
-            v = ((png_uint_16)(*bp) << 8) + *(bp + 1);
+            v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
             value = 0;
             for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
             {
@@ -329,7 +332,7 @@
 #endif
 
 #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
-void
+void /* PRIVATE */
 png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_write_swap_alpha\n");
@@ -417,7 +420,7 @@
 #endif
 
 #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
-void
+void /* PRIVATE */
 png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_write_invert_alpha\n");
@@ -438,7 +441,7 @@
                *(dp++) = *(sp++);
                *(dp++) = *(sp++);
                *(dp++) = *(sp++);
-               *(dp++) = 255 - *(sp++);
+               *(dp++) = (png_byte)(255 - *(sp++));
             }
          }
          /* This inverts the alpha channel in RRGGBBAA */
@@ -456,8 +459,8 @@
                *(dp++) = *(sp++);
                *(dp++) = *(sp++);
                *(dp++) = *(sp++);
-               *(dp++) = 255 - *(sp++);
-               *(dp++) = 255 - *(sp++);
+               *(dp++) = (png_byte)(255 - *(sp++));
+               *(dp++) = (png_byte)(255 - *(sp++));
             }
          }
       }
@@ -473,7 +476,7 @@
             for (i = 0, sp = dp = row; i < row_width; i++)
             {
                *(dp++) = *(sp++);
-               *(dp++) = 255 - *(sp++);
+               *(dp++) = (png_byte)(255 - *(sp++));
             }
          }
          /* This inverts the alpha channel in GGAA */
@@ -487,11 +490,72 @@
             {
                *(dp++) = *(sp++);
                *(dp++) = *(sp++);
-               *(dp++) = 255 - *(sp++);
-               *(dp++) = 255 - *(sp++);
+               *(dp++) = (png_byte)(255 - *(sp++));
+               *(dp++) = (png_byte)(255 - *(sp++));
             }
          }
       }
    }
 }
 #endif
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+/* undoes intrapixel differencing  */
+void /* PRIVATE */
+png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_write_intrapixel\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       (row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      int bytes_per_pixel;
+      png_uint_32 row_width = row_info->width;
+      if (row_info->bit_depth == 8)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 3;
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 4;
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            *(rp)   = (png_byte)((*rp     - *(rp+1))&0xff);
+            *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
+         }
+      }
+      else if (row_info->bit_depth == 16)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 6;
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 8;
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            png_uint_32 s0=*(rp  )<<8 | *(rp+1);
+            png_uint_32 s1=*(rp+2)<<8 | *(rp+3);
+            png_uint_32 s2=*(rp+4)<<8 | *(rp+5);
+            png_uint_32 red=(s0-s1)&0xffff;
+            png_uint_32 blue=(s2-s1)&0xffff;
+            *(rp  ) = (png_byte)((red>>8)&0xff);
+            *(rp+1) = (png_byte)(red&0xff);
+            *(rp+4) = (png_byte)((blue>>8)&0xff);
+            *(rp+5) = (png_byte)(blue&0xff);
+         }
+      }
+   }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */

Added: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/configure
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/configure	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/configure	Sat Jul 13 21:26:41 2002
@@ -0,0 +1,6 @@
+echo "
+  There is no \"configure\" script for Libpng-1.0.9.  Instead, please
+  copy the appropriate makefile for your system from the \"scripts\"
+  directory.  Read the INSTALL file for more details.
+"
+

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/Makefile.in
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/Makefile.in	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/Makefile.in	Sat Jul 13 21:26:41 2002
@@ -10,12 +10,6 @@
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
-#AUTOMAKE_OPTIONS        = foreign
-
-# where we keep local rules for automake
-#ACLOCAL_M4 = $(top_srcdir)/config/aclocal.m4
-#AUTOHEADER = @AUTOHEADER@ --localdir=$(top_srcdir)/config
-
 
 SHELL = @SHELL@
 
@@ -70,21 +64,32 @@
 target_alias = @target_alias@
 target_triplet = @target@
 CC = @CC@
-CFLAGS = @CFLAGS@
 CGI_LIB_DIR = @CGI_LIB_DIR@
 COMP_PERL = @COMP_PERL@
 CPP = @CPP@
 GD_LIB_DIR = @GD_LIB_DIR@
 LIBTOOL = @LIBTOOL@
+NROFF = @NROFF@
 PERL = @PERL@
+PERLFLAGS = @PERLFLAGS@
+PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PNG_LIB_DIR = @PNG_LIB_DIR@
 RANLIB = @RANLIB@
+SO_EXT = @SO_EXT@
+TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
+TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
+TCL_PREFIX = @TCL_PREFIX@
+TCL_SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@
+TCL_SHLIB_LD = @TCL_SHLIB_LD@
+TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+TROFF = @TROFF@
+VERSION = @VERSION@
 
 ZLIB_LIB_DIR = @ZLIB_LIB_DIR@
 
 INCLUDES = -I$(top_srcdir)/$(ZLIB_LIB_DIR)
 
-EXTRA_DIST = ANNOUNCE CHANGES INSTALL KNOWNBUG README README.rrdtool TODO Y2KINFO example.c libpng.3 		libpng.txt libpngpf.3 png.5 png.dsp png.dsw 
+EXTRA_DIST = ANNOUNCE CHANGES INSTALL KNOWNBUG README README.rrdtool             TODO Y2KINFO example.c libpng.3     	    libpng.txt libpngpf.3 png.5 png.dsp png.dsw 
 
 
 noinst_LTLIBRARIES = librrd_png.la
@@ -106,16 +111,15 @@
 librrd_png_la_OBJECTS =  png.lo pngerror.lo pngget.lo pngmem.lo \
 pngpread.lo pngread.lo pngrio.lo pngrtran.lo pngrutil.lo pngset.lo \
 pngtrans.lo pngwio.lo pngwrite.lo pngwtran.lo pngwutil.lo
+CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
 LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
-DIST_COMMON =  README INSTALL Makefile.am Makefile.in TODO ansi2knr.1 \
-ansi2knr.c
+DIST_COMMON =  README INSTALL Makefile.am Makefile.in TODO configure
 
 
 PACKAGE = @PACKAGE@
-VERSION = @VERSION@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
@@ -128,7 +132,7 @@
 .SUFFIXES:
 .SUFFIXES: .S .c .lo .o .s
 $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-	cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps libpng-1.0.3/Makefile
+	cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps libpng-1.0.9/Makefile
 
 Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
 	cd $(top_builddir) \
@@ -216,13 +220,13 @@
 
 distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 
-subdir = libpng-1.0.3
+subdir = libpng-1.0.9
 
 distdir: $(DISTFILES)
 	@for file in $(DISTFILES); do \
 	  d=$(srcdir); \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$/$$file $(distdir)/$$file; \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
 	    test -f $(distdir)/$$file \
 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/libpng.txt
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/libpng.txt	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/libpng.txt	Sat Jul 13 21:26:42 2002
@@ -1,9 +1,9 @@
 libpng.txt - A description on how to use and modify libpng
 
- libpng version 1.0.3 - January 14, 1999
+ libpng version 1.0.9 - January 31, 2001
  Updated and distributed by Glenn Randers-Pehrson
- <randeg at alumni.rpi.edu>
- Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ <randeg at alum.rpi.edu>
+ Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson
  For conditions of distribution and use, see copyright
  notice in png.h.
 
@@ -19,8 +19,8 @@
  Schalnat, Group 42, Inc.
 
  Updated/rewritten per request in the libpng FAQ
- Copyright (c) 1995 Frank J. T. Wojcik
- December 18, 1995 && January 20, 1996
+ Copyright (c) 1995, 1996 Frank J. T. Wojcik
+ December 18, 1995 & January 20, 1996
 
 I. Introduction
 
@@ -35,13 +35,21 @@
 
 Libpng was written as a companion to the PNG specification, as a way
 of reducing the amount of time and effort it takes to support the PNG
-file format in application programs.  The PNG specification is available
+file format in application programs.
+
+The PNG-1.2 specification is available at <http://www.libpng.org/pub/png>
+and at <ftp://ftp.uu.net/graphics/png/documents/>.
+
+The PNG-1.0 specification is available
 as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/> and as a
 W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some
 additional chunks are described in the special-purpose public chunks
-documents at <ftp://ftp.uu.net/graphics/png/documents/>.  Other information
+documents at <ftp://ftp.uu.net/graphics/png/documents/>.
+
+Other information
 about PNG, and the latest version of libpng, can be found at the PNG home
-page, <http://www.cdrom.com/pub/png/>.
+page, <http://www.libpng.org/pub/png/>
+and at <ftp://ftp.uu.net/graphics/png/>.
 
 Most users will not have to modify the library significantly; advanced
 users may want to modify it more.  All attempts were made to make it as
@@ -59,7 +67,7 @@
 
 Libpng uses zlib for its compression and decompression of PNG files.
 Further information about zlib, and the latest version of zlib, can
-be found at the zlib home page, <http://www.cdrom.com/pub/infozip/zlib/>.
+be found at the zlib home page, <http://www.info-zip.org/pub/infozip/zlib/>.
 The zlib compression utility is a general purpose utility that is
 useful for more than PNG files, and can be used without libpng.
 See the documentation delivered with zlib for more details.
@@ -84,9 +92,20 @@
 PNG file.  At one time, the fields of png_info were intended to be
 directly accessible to the user.  However, this tended to cause problems
 with applications using dynamically loaded libraries, and as a result
-a set of interface functions for png_info was developed.  The fields
-of png_info are still available for older applications, but it is
-suggested that applications use the new interfaces if at all possible.
+a set of interface functions for png_info (the png_get_*() and png_set_*()
+functions) was developed.  The fields of png_info are still available for
+older applications, but it is suggested that applications use the new
+interfaces if at all possible.
+
+Applications that do make direct access to the members of png_struct (except
+for png_ptr->jmpbuf) must be recompiled whenever the library is updated,
+and applications that make direct access to the members of png_info must
+be recompiled if they were compiled or loaded with libpng version 1.0.6,
+in which the members were in a different order.  In version 1.0.7, the
+members of the png_info structure reverted to the old order, as they were
+in versions 0.97c through 1.0.5.  Starting with version 2.0.0, both
+structures are going to be hidden, and the contents of the structures will
+only be accessible through the png_get/png_set functions.
 
 The png.h header file is an invaluable reference for programming with libpng.
 And while I'm on the topic, make sure you include the libpng header file:
@@ -95,22 +114,23 @@
 
 III. Reading
 
-Reading PNG files:
-
 We'll now walk you through the possible functions to call when reading
-in a PNG file, briefly explaining the syntax and purpose of each one.
-See example.c and png.h for more detail.  While Progressive reading
-is covered in the next section, you will still need some of the
-functions discussed in this section to read a PNG file.
+in a PNG file sequentially, briefly explaining the syntax and purpose
+of each one.  See example.c and png.h for more detail.  While
+progressive reading is covered in the next section, you will still
+need some of the functions discussed in this section to read a PNG
+file.
+
+Setup
 
 You will want to do the I/O initialization(*) before you get into libpng,
 so if it doesn't work, you don't have much to undo.  Of course, you
 will also want to insure that you are, in fact, dealing with a PNG
 file.  Libpng provides a simple check to see if a file is a PNG file.
-To use it, pass in the first 1 to 8 bytes of the file, and it will
-return true or false (1 or 0) depending on whether the bytes could be
-part of a PNG file.  Of course, the more bytes you pass in, the
-greater the accuracy of the prediction.
+To use it, pass in the first 1 to 8 bytes of the file to the function
+png_sig_cmp(), and it will return 0 if the bytes match the corresponding
+bytes of the PNG signature, or nonzero otherwise.  Of course, the more bytes
+you pass in, the greater the accuracy of the prediction.
 
 If you are intending to keep the file pointer open for use in libpng,
 you must ensure you don't read more than 8 bytes from the beginning
@@ -126,13 +146,13 @@
     FILE *fp = fopen(file_name, "rb");
     if (!fp)
     {
-        return;
+        return (ERROR);
     }
     fread(header, 1, number, fp);
     is_png = !png_sig_cmp(header, 0, number);
     if (!is_png)
     {
-        return;
+        return (NOT_PNG);
     }
 
 
@@ -144,19 +164,21 @@
 use by the error functions, if necessary (the pointer and functions can
 be NULL if the default error handlers are to be used).  See the section
 on Changes to Libpng below regarding the old initialization functions.
+The structure allocation functions quietly return NULL if they fail to
+create the structure, so your application should check for that.
 
     png_structp png_ptr = png_create_read_struct
        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
         user_error_fn, user_warning_fn);
     if (!png_ptr)
-        return;
+        return (ERROR);
 
     png_infop info_ptr = png_create_info_struct(png_ptr);
     if (!info_ptr)
     {
         png_destroy_read_struct(&png_ptr,
            (png_infopp)NULL, (png_infopp)NULL);
-        return;
+        return (ERROR);
     }
 
     png_infop end_info = png_create_info_struct(png_ptr);
@@ -164,7 +186,7 @@
     {
         png_destroy_read_struct(&png_ptr, &info_ptr,
           (png_infopp)NULL);
-        return;
+        return (ERROR);
     }
 
 If you want to use your own memory allocation routines,
@@ -183,24 +205,29 @@
 
 When libpng encounters an error, it expects to longjmp back
 to your routine.  Therefore, you will need to call setjmp and pass
-your png_ptr->jmpbuf.  If you read the file from different
+your png_jmpbuf(png_ptr).  If you read the file from different
 routines, you will need to update the jmpbuf field every time you enter
-a new routine that will call a png_ function.
+a new routine that will call a png_*() function.
 
 See your documentation of setjmp/longjmp for your compiler for more
-handling in the Customizing Libpng section below for more information on
-the libpng error handling.  If an error occurs, and libpng longjmp's
+information on setjmp/longjmp.  See the discussion on libpng error
+handling in the Customizing Libpng section below for more information
+on the libpng error handling.  If an error occurs, and libpng longjmp's
 back to your setjmp, you will want to call png_destroy_read_struct() to
 free any memory.
 
-    if (setjmp(png_ptr->jmpbuf))
+    if (setjmp(png_jmpbuf(png_ptr)))
     {
         png_destroy_read_struct(&png_ptr, &info_ptr,
            &end_info);
         fclose(fp);
-        return;
+        return (ERROR);
     }
 
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
 Now you need to set up the input code.  The default for libpng is to
 use the C function fread().  If you use this, you will need to pass a
 valid FILE * in the function png_init_io().  Be sure that the file is
@@ -217,12 +244,48 @@
 
     png_set_sig_bytes(png_ptr, number);
 
+Setting up callback code
+
+You can set up a callback function to handle any unknown chunks in the
+input stream. You must supply the function
+
+    read_chunk_callback(png_ptr ptr,
+         png_unknown_chunkp chunk);
+    {
+       /* The unknown chunk structure contains your
+          chunk data: */
+           png_byte name[5];
+           png_byte *data;
+           png_size_t size;
+       /* Note that libpng has already taken care of the
+          CRC handling */
+
+       /* put your code here.  Return one of the following: */
+
+       return (-n); /* chunk had an error */
+       return (0); /* did not recognize */
+       return (n); /* success */
+    }
+
+(You can give your function another name that you like instead of
+"read_chunk_callback")
+
+To inform libpng about your function, use
+
+    png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr,
+        read_chunk_callback);
+
+This names not only the callback function, but also a user pointer that
+you can retrieve with
+
+    png_get_user_chunk_ptr(png_ptr);
+
 At this point, you can set up a callback function that will be
 called after each row has been read, which you can use to control
 a progress meter or the like.  It's demonstrated in pngtest.c.
 You must supply a function
 
-    void read_row_callback(png_ptr, png_uint_32 row, int pass);
+    void read_row_callback(png_ptr ptr, png_uint_32 row, int pass);
     {
       /* put your code here */
     }
@@ -233,44 +296,111 @@
 
     png_set_read_status_fn(png_ptr, read_row_callback);
 
-In PNG files, the alpha channel in an image is the level of opacity.
-If you need the alpha channel in an image to be the level of transparency
-instead of opacity, you can invert the alpha channel (or the tRNS chunk
-data) after it's read, so that 0 is fully opaque and 255 (in 8-bit or
-paletted images) or 65535 (in 16-bit images) is fully transparent, with
+Unknown-chunk handling
 
-    png_set_invert_alpha(png_ptr);
+Now you get to set the way the library processes unknown chunks in the
+input PNG stream. Both known and unknown chunks will be read.  Normal
+behavior is that known chunks will be parsed into information in
+various info_ptr members; unknown chunks will be discarded. To change
+this, you can call:
+
+    png_set_keep_unknown_chunks(png_ptr, info_ptr, keep,
+        chunk_list, num_chunks);
+    keep       - 0: do not keep
+                 1: keep only if safe-to-copy
+                 2: keep even if unsafe-to-copy
+    chunk_list - list of chunks affected (a byte string,
+                 five bytes per chunk, NULL or '\0' if
+                 num_chunks is 0)
+    num_chunks - number of chunks affected; if 0, all
+                 unknown chunks are affected
+
+Unknown chunks declared in this way will be saved as raw data onto a
+list of png_unknown_chunk structures.  If a chunk that is normally
+known to libpng is named in the list, it will be handled as unknown,
+according to the "keep" directive.  If a chunk is named in successive
+instances of png_set_keep_unknown_chunks(), the final instance will
+take precedence.
+
+The high-level read interface
+
+At this point there are two ways to proceed; through the high-level
+read interface, or through a sequence of low-level read operations.
+You can use the high-level interface if (a) you are willing to read
+the entire image into memory, and (b) the input transformations
+you want to do are limited to the following set:
+
+    PNG_TRANSFORM_IDENTITY      No transformation
+    PNG_TRANSFORM_STRIP_16      Strip 16-bit samples to 8 bits
+    PNG_TRANSFORM_STRIP_ALPHA   Discard the alpha channel
+    PNG_TRANSFORM_PACKING       Expand 1, 2 and 4-bit samples to bytes
+    PNG_TRANSFORM_PACKSWAP      Change order of packed pixels to LSB first
+    PNG_TRANSFORM_EXPAND        Perform set_expand()
+    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
+    PNG_TRANSFORM_SHIFT         Normalize pixels to the sBIT depth
+    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA to BGRA
+    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA to AG
+    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity to transparency
+    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples
+
+(This excludes setting a background color, doing gamma transformation,
+dithering, and setting filler.)  If this is the case, simply do this:
+
+    png_read_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the logical OR of
+some set of transformation flags.  This call is equivalent to png_read_info(),
+followed the set of transformations indicated by the transform mask,
+then png_read_image(), and finally png_read_end().
 
-This has to appear here rather than later with the other transformations
-because the tRNS chunk data must be modified in the case of paletted images.
-If your image is not a paletted image, the tRNS data (which in such cases
-represents a single color to be rendered as transparent) won't be changed.
+(The final parameter of this call is not yet used.  Someday it might point
+to transformation parameters required by some future input transform.)
 
-Finally, you can write your own transformation function if none of
-the existing ones meets your needs.  This is done by setting a callback
+After you have called png_read_png(), you can retrieve the image data
 with
 
-    png_set_read_user_transform_fn(png_ptr,
-       read_transform_fn);
+   row_pointers = png_get_rows(png_ptr, info_ptr);
 
-You must supply the function
+where row_pointers is an array of pointers to the pixel data for each row:
 
-    void read_transform_fn(png_ptr ptr, row_info_ptr
-       row_info, png_bytep data)
+   png_bytep row_pointers[height];
 
-See pngtest.c for a working example.  Your function will be called
-after all of the other transformations have been processed.
+If you know your image size and pixel size ahead of time, you can allocate
+row_pointers prior to calling png_read_png() with
+
+   row_pointers = png_malloc(png_ptr, height*sizeof(png_bytep));
+   for (int i=0; i<height, i++)
+      row_pointers[i]=png_malloc(png_ptr, width*pixel_size);
+   png_set_rows(png_ptr, info_ptr, &row_pointers);
 
-You are now ready to read all the file information up to the actual
-image data.  You do this with a call to png_read_info().
+Alternatively you could allocate your image in one big block and define
+row_pointers[i] to point into the proper places in your block.
+
+If you use png_set_rows(), the application is responsible for freeing
+row_pointers (and row_pointers[i], if they were separately allocated).
+
+If you don't allocate row_pointers ahead of time, png_read_png() will
+do it, and it'll be free'ed when you call png_destroy_*().
+
+The low-level read interface
+
+If you are going the low-level route, you are now ready to read all
+the file information up to the actual image data.  You do this with a
+call to png_read_info().
 
     png_read_info(png_ptr, info_ptr);
 
-Functions are used to get the information from the info_ptr:
+This will process all chunks up to but not including the image data.
+
+Querying the info structure
+
+Functions are used to get the information from the info_ptr once it
+has been read.  Note that these fields may not be completely filled
+in until png_read_end() has read the chunk data following the image.
 
     png_get_IHDR(png_ptr, info_ptr, &width, &height,
        &bit_depth, &color_type, &interlace_type,
-       &compression_type, &filter_type);
+       &compression_type, &filter_method);
 
     width          - holds the width of the image
                      in pixels (up to 2^31).
@@ -298,15 +428,18 @@
                      PNG_COLOR_MASK_COLOR
                      PNG_COLOR_MASK_ALPHA
 
-    filter_type    - (must be PNG_FILTER_TYPE_BASE
-                     for PNG 1.0)
+    filter_method  - (must be PNG_FILTER_TYPE_BASE
+                     for PNG 1.0, and can also be
+                     PNG_INTRAPIXEL_DIFFERENCING if
+                     the PNG datastream is embedded in
+                     a MNG-1.0 datastream)
     compression_type - (must be PNG_COMPRESSION_TYPE_BASE
                      for PNG 1.0)
     interlace_type - (PNG_INTERLACE_NONE or
                      PNG_INTERLACE_ADAM7)
     Any or all of interlace_type, compression_type, of
-                     filter_type can be
-    NULL if you are not interested in their values.
+                     filter_method can be NULL if you are
+                     not interested in their values.
 
     channels = png_get_channels(png_ptr, info_ptr);
     channels       - number of channels of info for the
@@ -336,7 +469,7 @@
                          info_ptr);
     color_type       = png_get_color_type(png_ptr,
                          info_ptr);
-    filter_type      = png_get_filter_type(png_ptr,
+    filter_method    = png_get_filter_type(png_ptr,
                          info_ptr);
     compression_type = png_get_compression_type(png_ptr,
                          info_ptr);
@@ -369,6 +502,16 @@
                      implies specific values of gAMA and
                      cHRM.
 
+    png_get_iCCP(png_ptr, info_ptr, &name, &compression_type,
+                      &profile, &proflen);
+    name            - The profile name.
+    compression     - The compression type; always PNG_COMPRESSION_TYPE_BASE
+                      for PNG 1.0.  You may give NULL to this argument
+                      to ignore it.
+    profile         - International Color Consortium color profile
+                      data. May contain NULs.
+    proflen         - length of profile data in bytes.
+
     png_get_sBIT(png_ptr, info_ptr, &sig_bit);
     sig_bit        - the number of significant bits for
                      (PNG_INFO_sBIT) each of the gray,
@@ -380,15 +523,16 @@
                      &trans_values);
     trans          - array of transparent entries for
                      palette (PNG_INFO_tRNS)
-    trans_values   - transparent pixel for non-paletted
-                     images (PNG_INFO_tRNS)
+    trans_values   - graylevel or color sample values of
+                     the single transparent color for
+                     non-paletted images (PNG_INFO_tRNS)
     num_trans      - number of transparent entries
                      (PNG_INFO_tRNS)
 
     png_get_hIST(png_ptr, info_ptr, &hist);
                      (PNG_INFO_hIST)
     hist           - histogram of palette (array of
-                     png_color_16)
+                     png_uint_16)
 
     png_get_tIME(png_ptr, info_ptr, &mod_time);
     mod_time       - time image was last modified
@@ -396,17 +540,43 @@
 
     png_get_bKGD(png_ptr, info_ptr, &background);
     background     - background color (PNG_VALID_bKGD)
+                     valid 16-bit red, green and blue
+                     values, regardless of color_type
 
-    num_text = png_get_text(png_ptr, info_ptr, &text_ptr);
+    num_comments   = png_get_text(png_ptr, info_ptr,
+                     &text_ptr, &num_text);
+    num_comments   - number of comments
     text_ptr       - array of png_text holding image
                      comments
-    text_ptr[i]->key   - keyword for comment.
-    text_ptr[i]->text  - text comments for current
-                         keyword.
-    text_ptr[i]->compression - type of compression used
-                     on "text" PNG_TEXT_COMPRESSION_NONE
-                     or PNG_TEXT_COMPRESSION_zTXt
-    num_text       - number of comments
+    text_ptr[i].compression - type of compression used
+                 on "text" PNG_TEXT_COMPRESSION_NONE
+                           PNG_TEXT_COMPRESSION_zTXt
+                           PNG_ITXT_COMPRESSION_NONE
+                           PNG_ITXT_COMPRESSION_zTXt
+    text_ptr[i].key   - keyword for comment.  Must contain
+                         1-79 characters.
+    text_ptr[i].text  - text comments for current
+                         keyword.  Can be empty.
+    text_ptr[i].text_length - length of text string,
+                 after decompression, 0 for iTXt
+    text_ptr[i].itxt_length - length of itxt string,
+                 after decompression, 0 for tEXt/zTXt
+    text_ptr[i].lang  - language of comment (empty
+                         string for unknown).
+    text_ptr[i].translated_keyword  - keyword in UTF-8
+                         (empty string for unknown).
+    num_text       - number of comments (same as num_comments;
+                     you can put NULL here to avoid the duplication)
+    Note while png_set_text() will accept text, language, and
+    translated keywords that can be NULL pointers, the structure
+    returned by png_get_text will always contain regular
+    zero-terminated C strings.  They might be empty strings but
+    they will never be NULL pointers.
+
+    num_spalettes = png_get_sPLT(png_ptr, info_ptr, &palette_ptr);
+    palette_ptr    - array of palette structures holding
+                     contents of one or more sPLT chunks read.
+    num_spalettes  - number of sPLT chunks read.
 
     png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,
                      &unit_type);
@@ -425,6 +595,30 @@
     unit_type      - PNG_RESOLUTION_UNKNOWN,
                      PNG_RESOLUTION_METER
 
+    png_get_sCAL(png_ptr, info_ptr, &unit, &width, &height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are doubles)
+
+    png_get_sCAL_s(png_ptr, info_ptr, &unit, &width, &height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are strings like "2.54")
+
+    num_unknown_chunks = png_get_unknown_chunks(png_ptr, info_ptr,
+                            &unknowns)
+    unknowns          - array of png_unknown_chunk structures holding
+                        unknown chunks
+    unknowns[i].name  - name of unknown chunk
+    unknowns[i].data  - data of unknown chunk
+    unknowns[i].size  - size of unknown chunk's data
+    unknowns[i].location - position of chunk in file
+
+    The value of "i" corresponds to the order in which the chunks were read
+    from the PNG file or inserted with the png_set_unknown_chunks() function.
+
 The data from the pHYs chunk can be retrieved in several convenient
 forms:
 
@@ -434,6 +628,12 @@
                   info_ptr)
     res_x_and_y = png_get_pixels_per_meter(png_ptr,
                   info_ptr)
+    res_x = png_get_x_pixels_per_inch(png_ptr,
+                  info_ptr)
+    res_y = png_get_y_pixels_per_inch(png_ptr,
+                  info_ptr)
+    res_x_and_y = png_get_pixels_per_inch(png_ptr,
+                  info_ptr)
     aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,
                   info_ptr)
 
@@ -441,6 +641,18 @@
        the data is not present or if res_x is 0;
        res_x_and_y is 0 if res_x != res_y)
 
+The data from the oFFs chunk can be retrieved in several convenient
+forms:
+
+    x_offset = png_get_x_offset_microns(png_ptr, info_ptr);
+    y_offset = png_get_y_offset_microns(png_ptr, info_ptr);
+    x_offset = png_get_x_offset_inches(png_ptr, info_ptr);
+    y_offset = png_get_y_offset_inches(png_ptr, info_ptr);
+
+   (Each of these returns 0 [signifying "unknown" if both
+       x and y are 0] if the data is not present or if the chunk
+       is present but the unit is the pixel)
+
 For more information, see the png_info definition in png.h and the
 PNG specification for chunk contents.  Be careful with trusting
 rowbytes, as some of the transformations could increase the space
@@ -459,14 +671,17 @@
 Keywords should be limited to 79 Latin-1 characters without leading or
 trailing spaces, but non-consecutive spaces are allowed within the
 keyword.  It is possible to have the same keyword any number of times.
-The text_ptr is an array of png_text structures, each holding pointer
-to a keyword and a pointer to a text string.  Only the text string may
-be null.  The keyword/text pairs are put into the array in the order
-that they are received.  However, some or all of the text chunks may be
-after the image, so, to make sure you have read all the text chunks,
-don't mess with these until after you read the stuff after the image.
-This will be mentioned again below in the discussion that goes with
-png_read_end().
+The text_ptr is an array of png_text structures, each holding a
+pointer to a language string, a pointer to a keyword and a pointer to
+a text string.  The text string, language code, and translated
+keyword may be empty or NULL pointers.  The keyword/text
+pairs are put into the array in the order that they are received.
+However, some or all of the text chunks may be after the image, so, to
+make sure you have read all the text chunks, don't mess with these
+until after you read the stuff after the image.  This will be
+mentioned again below in the discussion that goes with png_read_end().
+
+Input transformations
 
 After you've read the header information, you can set up the library
 to handle any special transformations of the image data.  The various
@@ -505,14 +720,19 @@
 grayscale images with bit depths of 2 or 4 or if there is a multiple-image
 viewing application that wishes to treat all images in the same way.
 
-    if (color_type == PNG_COLOR_TYPE_PALETTE &&
-        bit_depth <= 8) png_set_expand(png_ptr);
+    if (color_type == PNG_COLOR_TYPE_PALETTE)
+        png_set_palette_to_rgb(png_ptr);
 
     if (color_type == PNG_COLOR_TYPE_GRAY &&
-        bit_depth < 8) png_set_expand(png_ptr);
+        bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
 
     if (png_get_valid(png_ptr, info_ptr,
-        PNG_INFO_tRNS)) png_set_expand(png_ptr);
+        PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
+
+These three functions are actually aliases for png_set_expand(), added
+in libpng version 1.0.4, with the function names expanded to improve code
+readability.  In some future version they may actually do different
+things.
 
 PNG can have files with 16 bits per channel.  If you only can handle
 8 bits per channel, this will strip the pixels down to 8 bit.
@@ -520,17 +740,6 @@
     if (bit_depth == 16)
         png_set_strip_16(png_ptr);
 
-The png_set_background() function tells libpng to composite images
-with alpha or simple transparency against the supplied background
-color.  If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),
-you may use this color, or supply another color more suitable for
-the current display (e.g., the background color from a web page).  You
-need to tell libpng whether the color is in the gamma space of the
-display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file
-(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one
-that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't
-know why anyone would use this, but it's here).
-
 If, for some reason, you don't need the alpha channel on an image,
 and you want to remove it rather than combining it with the background
 (but the image author certainly had in mind that you *would* combine
@@ -539,6 +748,15 @@
     if (color_type & PNG_COLOR_MASK_ALPHA)
         png_set_strip_alpha(png_ptr);
 
+In PNG files, the alpha channel in an image
+is the level of opacity.  If you need the alpha channel in an image to
+be the level of transparency instead of opacity, you can invert the
+alpha channel (or the tRNS chunk data) after it's read, so that 0 is
+fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit
+images) is fully transparent, with
+
+    png_set_invert_alpha(png_ptr);
+
 PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
 they can, resulting in, for example, 8 pixels per byte for 1 bit
 files.  This code expands to 1 pixel per byte without changing the
@@ -592,14 +810,12 @@
           png_set_gray_to_rgb(png_ptr);
 
 Conversely, you can convert an RGB or RGBA image to grayscale or grayscale
-with alpha.  This is intended for conversion of images that really are
-gray (red == green == blue), so the function simply strips out the red
-and blue channels, leaving the green channel in the gray position.
+with alpha.
 
     if (color_type == PNG_COLOR_TYPE_RGB ||
         color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-          png_set_rgb_to_gray(png_ptr, error_action,
-             float red_weight, float green_weight);
+          png_set_rgb_to_gray_fixed(png_ptr, error_action,
+             int red_weight, int green_weight);
 
     error_action = 1: silently do the conversion
     error_action = 2: issue a warning if the original
@@ -610,10 +826,10 @@
                       image has any pixel where
                       red != green or red != blue
 
-    red_weight:       weight of red component
-                      (NULL -> default 54/256)
-    green_weight:     weight of green component
-                      (NULL -> default 183/256)
+    red_weight:       weight of red component times 100000
+    green_weight:     weight of green component times 100000
+                      If either weight is negative, default
+                      weights (21268, 71514) are used.
 
 If you have set error_action = 1 or 2, you can
 later check whether the image really was gray, after processing
@@ -623,13 +839,13 @@
 will be silently converted to grayscale, using the green channel
 data, regardless of the error_action setting.
 
-With 0.0<=red_weight+green_weight<=1.0,
+With red_weight+green_weight<=100000,
 the normalized graylevel is computed:
 
-    int rw = red_weight * 256;
-    int gw = green_weight * 256;
-    int bw = 256 - (rw + gw);
-    gray = (rw*red + gw*green + bw*blue)/256;
+    int rw = red_weight * 65536;
+    int gw = green_weight * 65536;
+    int bw = 65536 - (rw + gw);
+    gray = (rw*red + gw*green + bw*blue)/65536;
 
 The default values approximate those recommended in the Charles
 Poynton's Color FAQ, <http://www.inforamp.net/~poynton/>
@@ -639,16 +855,17 @@
 
 Libpng approximates this with
 
-    Y = 0.211 * R    + 0.715 * G    + 0.074 * B
+    Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
 
 which can be expressed with integers as
 
-    Y = (54 * R + 183 * G + 19 * B)/256
+    Y = (6969 * R + 23434 * G + 2365 * B)/32768
 
 The calculation is done in a linear colorspace, if the image gamma
 is known.
 
-If you have a grayscale and you are using png_set_expand() to change to
+If you have a grayscale and you are using png_set_expand_depth() or
+png_set_expand() to change to
 a higher bit-depth, you must either supply the background color as a gray
 value at the original file bit-depth (need_expand = 1) or else supply the
 background color as an RGB triplet at the final, expanded bit depth
@@ -666,20 +883,31 @@
         png_set_background(png_ptr, &my_background,
           PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
 
+The png_set_background() function tells libpng to composite images
+with alpha or simple transparency against the supplied background
+color.  If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),
+you may use this color, or supply another color more suitable for
+the current display (e.g., the background color from a web page).  You
+need to tell libpng whether the color is in the gamma space of the
+display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file
+(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one
+that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't
+know why anyone would use this, but it's here).
+
 To properly display PNG images on any kind of system, the application needs
 to know what the display gamma is.  Ideally, the user will know this, and
 the application will allow them to set it.  One method of allowing the user
-to set the display gamma separately for each system is to check for the
-DISPLAY_GAMMA and VIEWING_GAMMA environment variables or for a SCREEN_GAMMA
-environment variable, which will hopefully be correctly set.
-
-Note that display_gamma is the gamma of your display, while screen_gamma is
-the overall gamma correction required to produce pleasing results,
-which depends on the lighting conditions in the surrounding environment.
-Screen_gamma is display_gamma/viewing_gamma, where viewing_gamma is
-the amount of additional gamma correction needed to compensate for
-a (viewing_gamma=1.25) environment.  In a dim or brightly lit room, no
-compensation other than the display_gamma is needed (viewing_gamma=1.0).
+to set the display gamma separately for each system is to check for a
+SCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully be
+correctly set.
+
+Note that display_gamma is the overall gamma correction required to produce
+pleasing results, which depends on the lighting conditions in the surrounding
+environment.  In a dim or brightly lit room, no compensation other than
+the physical gamma exponent of the monitor is needed, while in a dark room
+a slightly smaller exponent is better.
+
+   double gamma, screen_gamma;
 
    if (/* We have a user-defined screen
        gamma value */)
@@ -691,7 +919,7 @@
    else if ((gamma_str = getenv("SCREEN_GAMMA"))
       != NULL)
    {
-      screen_gamma = atof(gamma_str);
+      screen_gamma = (double)atof(gamma_str);
    }
    /* If we don't have another value */
    else
@@ -734,7 +962,7 @@
       if (png_get_valid(png_ptr, info_ptr,
          PNG_INFO_PLTE))
       {
-         png_color_16p histogram;
+         png_uint_16p histogram;
 
          png_get_hIST(png_ptr, info_ptr,
             &histogram);
@@ -773,6 +1001,38 @@
     if (bit_depth < 8)
        png_set_packswap(png_ptr);
 
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs.  This is done by setting a callback
+with
+
+    png_set_read_user_transform_fn(png_ptr,
+       read_transform_fn);
+
+You must supply the function
+
+    void read_transform_fn(png_ptr ptr, row_info_ptr
+       row_info, png_bytep data)
+
+See pngtest.c for a working example.  Your function will be called
+after all of the other transformations have been processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function, and you can inform libpng that your transform
+function will change the number of channels or bit depth with the
+function
+
+    png_set_user_transform_info(png_ptr, user_ptr,
+       user_depth, user_channels);
+
+The user's application, not libpng, is responsible for allocating and
+freeing any memory required for the user structure.
+
+You can retrieve the pointer via the function
+png_get_user_transform_ptr().  For example:
+
+    voidp read_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
+
 The last thing to handle is interlacing; this is covered in detail below,
 but you must call the function here if you want libpng to handle expansion
 of the interlaced image.
@@ -796,6 +1056,8 @@
 array of pointers to each row, as it will be needed for some
 of the functions below.
 
+Reading image data
+
 After you've allocated memory, you can read the image data.
 The simplest way to do this is in one function call.  If you are
 allocating enough memory to hold the whole image, you can just
@@ -825,13 +1087,13 @@
 where row_pointers is the same as in the png_read_image() call.
 
 If you are doing this just one row at a time, you can do this with
-row_pointers:
+a single row_pointer instead of an array of row_pointers:
 
-    png_bytep row_pointers = row;
-    png_read_row(png_ptr, &row_pointers, NULL);
+    png_bytep row_pointer = row;
+    png_read_row(png_ptr, row_pointer, NULL);
 
-If the file is interlaced (info_ptr->interlace_type != 0), things get
-somewhat harder.  The only current (PNG Specification version 1.0)
+If the file is interlaced (interlace_type != 0 in the IHDR chunk), things
+get somewhat harder.  The only current (PNG Specification version 1.2)
 interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7)
 is a somewhat complicated 2D interlace scheme, known as Adam7, that
 breaks down an image into seven smaller images of varying size, based
@@ -904,12 +1166,14 @@
     png_read_rows(png_ptr, NULL, row_pointers,
        number_of_rows);
 
-After you are finished reading the image, you can finish reading
-the file.  If you are interested in comments or time, which may be
-stored either before or after the image data, you should pass the
-separate png_info struct if you want to keep the comments from
-before and after the image separate.  If you are not interested, you
-can pass NULL.
+Finishing a sequential read
+
+After you are finished reading the image through either the high- or
+low-level interfaces, you can finish reading the file.  If you are
+interested in comments or time, which may be stored either before or
+after the image data, you should pass the separate png_info struct if
+you want to keep the comments from before and after the image
+separate.  If you are not interested, you can pass NULL.
 
    png_read_end(png_ptr, end_info);
 
@@ -918,10 +1182,87 @@
    png_destroy_read_struct(&png_ptr, &info_ptr,
        &end_info);
 
-For a more compact example of reading a PNG image, see the file example.c.
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
 
+    png_free_data(png_ptr, info_ptr, mask, n)
+    mask - identifies data to be freed, a mask
+           containing the logical OR of one or
+           more of
+             PNG_FREE_PLTE, PNG_FREE_TRNS,
+             PNG_FREE_HIST, PNG_FREE_ICCP,
+             PNG_FREE_PCAL, PNG_FREE_ROWS,
+             PNG_FREE_SCAL, PNG_FREE_SPLT,
+             PNG_FREE_TEXT, PNG_FREE_UNKN,
+           or simply PNG_FREE_ALL
+    n    - sequence number of item to be freed
+           (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user and not by libpng,  and will in those
+cases do nothing.  The "n" parameter is ignored if only one item
+of the selected data type, such as PLTE, is allowed.  If "n" is not
+-1, and multiple items are allowed for the data type identified in
+the mask, such as text or sPLT, only the n'th item is freed.
+
+The default behavior is only to free data that was allocated internally
+by libpng.  This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+    png_data_freer(png_ptr, info_ptr, freer, mask)
+    mask   - which data elements are affected
+             same choices as in png_free_data()
+    freer  - one of
+               PNG_DESTROY_WILL_FREE_DATA
+               PNG_SET_WILL_FREE_DATA
+               PNG_USER_WILL_FREE_DATA
+
+This function only affects data that has already been allocated.
+You can call this function after reading the PNG data but before calling
+any png_set_*() functions, to control whether the user or the png_set_*()
+function is responsible for freeing any existing data that might be present,
+and again after the png_set_*() functions to control whether the user
+or png_destroy_*() is supposed to free the data.  When the user assumes
+responsibility for libpng-allocated data, the application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it (the png_zalloc() function is the same
+as png_malloc() except that it also zeroes the newly-allocated memory).
+
+If you allocated your row_pointers in a single block, as suggested above in
+the description of the high level read interface, you must not transfer
+responsibility for freeing it to the png_set_rows or png_read_destroy function,
+because they would also try to free the individual row_pointers[i].
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key.  Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
+
+The png_free_data() function will turn off the "valid" flag for anything
+it frees.  If you need to turn the flag off for a chunk that was freed by your
+application instead of by libpng, you can use
+
+    png_set_invalid(png_ptr, info_ptr, mask);
+    mask - identifies the chunks to be made invalid,
+           containing the logical OR of one or
+           more of
+             PNG_INFO_gAMA, PNG_INFO_sBIT,
+             PNG_INFO_cHRM, PNG_INFO_PLTE,
+             PNG_INFO_tRNS, PNG_INFO_bKGD,
+             PNG_INFO_hIST, PNG_INFO_pHYs,
+             PNG_INFO_oFFs, PNG_INFO_tIME,
+             PNG_INFO_pCAL, PNG_INFO_sRGB,
+             PNG_INFO_iCCP, PNG_INFO_sPLT,
+             PNG_INFO_sCAL, PNG_INFO_IDAT
+
+For a more compact example of reading a PNG image, see the file example.c.
 
-Reading PNG files progressively:
+Reading PNG files progressively
 
 The progressive reader is slightly different then the non-progressive
 reader.  Instead of calling png_read_info(), png_read_rows(), and
@@ -947,20 +1288,20 @@
         (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
          user_error_fn, user_warning_fn);
     if (!png_ptr)
-        return -1;
+        return (ERROR);
     info_ptr = png_create_info_struct(png_ptr);
     if (!info_ptr)
     {
         png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
            (png_infopp)NULL);
-        return -1;
+        return (ERROR);
     }
 
-    if (setjmp(png_ptr->jmpbuf))
+    if (setjmp(png_jmpbuf(png_ptr)))
     {
         png_destroy_read_struct(&png_ptr, &info_ptr,
            (png_infopp)NULL);
-        return -1;
+        return (ERROR);
     }
 
     /* This one's new.  You can provide functions
@@ -990,11 +1331,11 @@
  int
  process_data(png_bytep buffer, png_uint_32 length)
  {
-    if (setjmp(png_ptr->jmpbuf))
+    if (setjmp(png_jmpbuf(png_ptr)))
     {
         png_destroy_read_struct(&png_ptr, &info_ptr,
            (png_infopp)NULL);
-        return -1;
+        return (ERROR);
     }
 
     /* This one's new also.  Simply give it a chunk
@@ -1098,6 +1439,8 @@
 importance is repeated here, so you won't have to constantly look
 back up in the reading section to understand writing.
 
+Setup
+
 You will want to do the I/O initialization before you get into libpng,
 so if it doesn't work, you don't have anything to undo. If you are not
 using the standard I/O functions, you will need to replace them with
@@ -1106,7 +1449,7 @@
     FILE *fp = fopen(file_name, "wb");
     if (!fp)
     {
-       return;
+       return (ERROR);
     }
 
 Next, png_struct and png_info need to be allocated and initialized.
@@ -1121,19 +1464,19 @@
        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
         user_error_fn, user_warning_fn);
     if (!png_ptr)
-       return;
+       return (ERROR);
 
     png_infop info_ptr = png_create_info_struct(png_ptr);
     if (!info_ptr)
     {
        png_destroy_write_struct(&png_ptr,
          (png_infopp)NULL);
-       return;
+       return (ERROR);
     }
 
 If you want to use your own memory allocation routines,
 define PNG_USER_MEM_SUPPORTED and use
-png_create_write_struct_2() instead of png_create_read_struct():
+png_create_write_struct_2() instead of png_create_write_struct():
 
     png_structp png_ptr = png_create_write_struct_2
        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
@@ -1143,23 +1486,27 @@
 After you have these structures, you will need to set up the
 error handling.  When libpng encounters an error, it expects to
 longjmp() back to your routine.  Therefore, you will need to call
-setjmp() and pass the png_ptr->jmpbuf.  If you
+setjmp() and pass the png_jmpbuf(png_ptr).  If you
 write the file from different routines, you will need to update
-the jmpbuf field every time you enter a new routine that will
-call a png_ function.  See your documentation of setjmp/longjmp
+the png_jmpbuf(png_ptr) every time you enter a new routine that will
+call a png_*() function.  See your documentation of setjmp/longjmp
 for your compiler for more information on setjmp/longjmp.  See
 the discussion on libpng error handling in the Customizing Libpng
 section below for more information on the libpng error handling.
 
-    if (setjmp(png_ptr->jmpbuf))
+    if (setjmp(png_jmpbuf(png_ptr)))
     {
-        png_destroy_write_struct(&png_ptr, &info_ptr);
-        fclose(fp);
-        return;
+       png_destroy_write_struct(&png_ptr, &info_ptr);
+       fclose(fp);
+       return (ERROR);
     }
     ...
     return;
 
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
 Now you need to set up the output code.  The default for libpng is to
 use the C function fwrite().  If you use this, you will need to pass a
 valid FILE * in the function png_init_io().  Be sure that the file is
@@ -1169,6 +1516,8 @@
 
     png_init_io(png_ptr, fp);
 
+Write callbacks
+
 At this point, you can set up a callback function that will be
 called after each row has been written, which you can use to control
 a progress meter or the like.  It's demonstrated in pngtest.c.
@@ -1193,24 +1542,40 @@
 have no special needs in this area, let the library do what it wants by
 not calling this function at all, as it has been tuned to deliver a good
 speed/compression ratio. The second parameter to png_set_filter() is
-the filter method, for which the only valid value is '0' (as of the
-October 1996 PNG specification, version 1.0).  The third parameter is a
-flag that indicates which filter type(s) are to be tested for each
-scanline.  See the Compression Library for details on the specific filter
+the filter method, for which the only valid values are 0 (as of the
+July 1999 PNG specification, version 1.2) or 64 (if you are writing
+a PNG datastream that is to be embedded in a MNG datastream).  The third
+parameter is a flag that indicates which filter type(s) are to be tested
+for each scanline.  See the PNG specification for details on the specific filter
 types.
 
 
     /* turn on or off filtering, and/or choose
-       specific filters */
+       specific filters.  You can use either a single PNG_FILTER_VALUE_NAME
+       or the logical OR of one or more PNG_FILTER_NAME masks. */
     png_set_filter(png_ptr, 0,
-       PNG_FILTER_NONE | PNG_FILTER_SUB |
-       PNG_FILTER_PAETH);
+       PNG_FILTER_NONE  | PNG_FILTER_VALUE_NONE |
+       PNG_FILTER_SUB   | PNG_FILTER_VALUE_SUB  |
+       PNG_FILTER_UP    | PNG_FILTER_VALUE_UP   |
+       PNG_FILTER_AVE   | PNG_FILTER_VALUE_AVE  |
+       PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|
+       PNG_ALL_FILTERS);
+
+If an application
+wants to start and stop using particular filters during compression,
+it should start out with all of the filters (to ensure that the previous
+row of pixels will be stored in case it's needed later), and then add
+and remove them after the start of compression.
+
+If you are writing a PNG datastream that is to be embedded in a MNG
+datastream, the second parameter can be either 0 or 64.
 
-The png_set_compression_???() functions interface to the zlib compression
+The png_set_compression_*() functions interface to the zlib compression
 library, and should mostly be ignored unless you really know what you are
 doing.  The only generally useful call is png_set_compression_level()
 which changes how much time zlib spends on trying to compress the image
-data.  See the Compression Library for details on the compression levels.
+data.  See the Compression Library (zlib.h and algorithm.txt, distributed
+with zlib) for details on the compression levels.
 
     /* set the zlib compression level */
     png_set_compression_level(png_ptr,
@@ -1222,11 +1587,16 @@
         Z_DEFAULT_STRATEGY);
     png_set_compression_window_bits(png_ptr, 15);
     png_set_compression_method(png_ptr, 8);
+    png_set_compression_buffer_size(png_ptr, 8192)
+
+extern PNG_EXPORT(void,png_set_zbuf_size)
+
+Setting the contents of info for output
 
 You now need to fill in the png_info structure with all the data you
 wish to write before the actual image.  Note that the only thing you
 are allowed to write after the image is the text chunks and the time
-chunk (as of PNG Specification 1.0, anyway).  See png_write_end() and
+chunk (as of PNG Specification 1.2, anyway).  See png_write_end() and
 the latest PNG specification for more information on that.  If you
 wish to write them before the image, fill them in now, and flag that
 data as being valid.  If you want to wait until after the data, don't
@@ -1238,7 +1608,7 @@
 
     png_set_IHDR(png_ptr, info_ptr, width, height,
        bit_depth, color_type, interlace_type,
-       compression_type, filter_type)
+       compression_type, filter_method)
     width          - holds the width of the image
                      in pixels (up to 2^31).
     height         - holds the height of the image
@@ -1270,7 +1640,11 @@
                      PNG_INTERLACE_ADAM7
     compression_type - (must be
                      PNG_COMPRESSION_TYPE_DEFAULT)
-    filter_type    - (must be PNG_FILTER_TYPE_DEFAULT)
+    filter_method  - (must be PNG_FILTER_TYPE_DEFAULT
+                     or, if you are writing a PNG to
+                     be embedded in a MNG datastream,
+                     can also be
+                     PNG_INTRAPIXEL_DIFFERENCING)
 
     png_set_PLTE(png_ptr, info_ptr, palette,
        num_palette);
@@ -1294,10 +1668,10 @@
                      Color Consortium
                      (http://www.color.org).
                      It can be one of
-                     PNG_SRGB_INTENT_SATURATION,
-                     PNG_SRGB_INTENT_PERCEPTUAL,
-                     PNG_SRGB_INTENT_ABSOLUTE, or
-                     PNG_SRGB_INTENT_RELATIVE.
+                     PNG_sRGB_INTENT_SATURATION,
+                     PNG_sRGB_INTENT_PERCEPTUAL,
+                     PNG_sRGB_INTENT_ABSOLUTE, or
+                     PNG_sRGB_INTENT_RELATIVE.
 
 
     png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,
@@ -1311,6 +1685,16 @@
                      that are consistent with sRGB to be
                      written.
 
+    png_set_iCCP(png_ptr, info_ptr, name, compression_type,
+                      profile, proflen);
+    name            - The profile name.
+    compression     - The compression type; always PNG_COMPRESSION_TYPE_BASE
+                      for PNG 1.0.  You may give NULL to this argument
+                      to ignore it.
+    profile         - International Color Consortium color profile
+                      data. May contain NULs.
+    proflen         - length of profile data in bytes.
+
     png_set_sBIT(png_ptr, info_ptr, sig_bit);
     sig_bit        - the number of significant bits for
                      (PNG_INFO_sBIT) each of the gray, red,
@@ -1322,15 +1706,16 @@
        trans_values);
     trans          - array of transparent entries for
                      palette (PNG_INFO_tRNS)
-    trans_values   - transparent pixel for non-paletted
-                     images (PNG_INFO_tRNS)
+    trans_values   - graylevel or color sample values of
+                     the single transparent color for
+                     non-paletted images (PNG_INFO_tRNS)
     num_trans      - number of transparent entries
                      (PNG_INFO_tRNS)
 
     png_set_hIST(png_ptr, info_ptr, hist);
                     (PNG_INFO_hIST)
     hist           - histogram of palette (array of
-                     png_color_16)
+                     png_uint_16)
 
     png_set_tIME(png_ptr, info_ptr, mod_time);
     mod_time       - time image was last modified
@@ -1342,13 +1727,30 @@
     png_set_text(png_ptr, info_ptr, text_ptr, num_text);
     text_ptr       - array of png_text holding image
                      comments
-    text_ptr[i]->key   - keyword for comment.
-    text_ptr[i]->text  - text comments for current
-                         keyword.
-    text_ptr[i]->compression - type of compression used
-         on "text" PNG_TEXT_COMPRESSION_NONE or
-         PNG_TEXT_COMPRESSION_zTXt
-    num_text    - number of comments in text_ptr
+    text_ptr[i].compression - type of compression used
+                 on "text" PNG_TEXT_COMPRESSION_NONE
+                           PNG_TEXT_COMPRESSION_zTXt
+                           PNG_ITXT_COMPRESSION_NONE
+                           PNG_ITXT_COMPRESSION_zTXt
+    text_ptr[i].key   - keyword for comment.  Must contain
+                 1-79 characters.
+    text_ptr[i].text  - text comments for current
+                         keyword.  Can be NULL or empty.
+    text_ptr[i].text_length - length of text string,
+                 after decompression, 0 for iTXt
+    text_ptr[i].itxt_length - length of itxt string,
+                 after decompression, 0 for tEXt/zTXt
+    text_ptr[i].lang  - language of comment (NULL or
+                         empty for unknown).
+    text_ptr[i].translated_keyword  - keyword in UTF-8 (NULL
+                         or empty for unknown).
+    num_text       - number of comments
+
+    png_set_sPLT(png_ptr, info_ptr, &palette_ptr, num_spalettes);
+    palette_ptr    - array of png_sPLT_struct structures to be
+                     added to the list of palettes in the info
+                     structure.
+    num_spalettes  - number of palette structures to be added.
 
     png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,
         unit_type);
@@ -1367,30 +1769,52 @@
     unit_type   - PNG_RESOLUTION_UNKNOWN,
                   PNG_RESOLUTION_METER
 
-In PNG files, the alpha channel in an image is the level of opacity.
-If your data is supplied as a level of transparency, you can invert the
-alpha channel before you write it, so that 0 is fully transparent and 255
-(in 8-bit or paletted images) or 65535 (in 16-bit images) is fully opaque,
-with
-
-    png_set_invert_alpha(png_ptr);
-
-This must appear here instead of later with the other transformations
-because in the case of paletted images the tRNS chunk data has to
-be inverted before the tRNS chunk is written.  If your image is not a
-paletted image, the tRNS data (which in such cases represents a single
-color to be rendered as transparent) won't be changed.
+    png_set_sCAL(png_ptr, info_ptr, unit, width, height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                  (width and height are doubles)
+
+    png_set_sCAL_s(png_ptr, info_ptr, unit, width, height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are strings like "2.54")
+
+    png_set_unknown_chunks(png_ptr, info_ptr, &unknowns, num_unknowns)
+    unknowns          - array of png_unknown_chunk structures holding
+                        unknown chunks
+    unknowns[i].name  - name of unknown chunk
+    unknowns[i].data  - data of unknown chunk
+    unknowns[i].size  - size of unknown chunk's data
+    unknowns[i].location - position to write chunk in file
+                           0: do not write chunk
+                           PNG_HAVE_IHDR: before PLTE
+                           PNG_HAVE_PLTE: before IDAT
+                           PNG_AFTER_IDAT: after IDAT
+    The "location" member is set automatically according to
+    what part of the output file has already been written.
+    You can change its value after calling png_set_unknown_chunks()
+    as demonstrated in pngtest.c.  Within each of the "locations",
+    the chunks are sequenced according to their position in the
+    structure (that is, the value of "i", which is the order in which
+    the chunk was either read from the input file or defined with
+    png_set_unknown_chunks).
 
 A quick word about text and num_text.  text is an array of png_text
 structures.  num_text is the number of valid structures in the array.
-If you want, you can use max_text to hold the size of the array, but
-libpng ignores it for writing (it does use it for reading).  Each
-png_text structure holds a keyword-text value, and a compression type.
+Each png_text structure holds a language code, a keyword, a text value,
+and a compression type.
+
 The compression types have the same valid numbers as the compression
 types of the image data.  Currently, the only valid number is zero.
 However, you can store text either compressed or uncompressed, unlike
 images, which always have to be compressed.  So if you don't want the
 text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.
+Because tEXt and zTXt chunks don't have a language field, if you
+specify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt
+any language code or translated keyword will not be written out.
+
 Until text gets around 1000 bytes, it is not worth compressing it.
 After the text has been written out to the file, the compression type
 is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,
@@ -1433,7 +1857,7 @@
 is compressed anyway, so the compression would be meaningless.
 
 PNG supports modification time via the png_time structure.  Two
-conversion routines are proved, png_convert_from_time_t() for
+conversion routines are provided, png_convert_from_time_t() for
 time_t and png_convert_from_struct_tm() for struct tm.  The
 time_t routine uses gmtime().  You don't have to use either of
 these, but if you wish to fill in the png_time structure directly,
@@ -1456,9 +1880,79 @@
 png_convert_to_rfc1123(png_timep) is provided to convert from PNG
 time to an RFC 1123 format string.
 
-You are now ready to write all the file information up to the actual
-image data.  You do this with a call to png_write_info().
+Writing unknown chunks
+
+You can use the png_set_unknown_chunks function to queue up chunks
+for writing.  You give it a chunk name, raw data, and a size; that's
+all there is to it.  The chunks will be written by the next following
+png_write_info_before_PLTE, png_write_info, or png_write_end function.
+Any chunks previously read into the info structure's unknown-chunk
+list will also be written out in a sequence that satisfies the PNG
+specification's ordering rules.
+
+The high-level write interface
+
+At this point there are two ways to proceed; through the high-level
+write interface, or through a sequence of low-level write operations.
+You can use the high-level interface if your image data is present
+in the info structure.  All defined output
+transformations are permitted, enabled by the following masks.
+
+    PNG_TRANSFORM_IDENTITY      No transformation
+    PNG_TRANSFORM_PACKING       Pack 1, 2 and 4-bit samples
+    PNG_TRANSFORM_PACKSWAP      Change order of packed pixels to LSB first
+    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
+    PNG_TRANSFORM_SHIFT         Normalize pixels to the sBIT depth
+    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA to BGRA
+    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA to AG
+    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity to transparency
+    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples
+    PNG_TRANSFORM_STRIP_FILLER  Strip out filler bytes.
+
+If you have valid image data in the info structure (you can use
+png_set_rows() to put image data in the info structure), simply do this:
+
+    png_write_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the logical OR of some set of
+transformation flags.  This call is equivalent to png_write_info(),
+followed the set of transformations indicated by the transform mask,
+then png_write_image(), and finally png_write_end().
+
+(The final parameter of this call is not yet used.  Someday it might point
+to transformation parameters required by some future output transform.)
+
+The low-level write interface
+
+If you are going the low-level route instead, you are now ready to
+write all the file information up to the actual image data.  You do
+this with a call to png_write_info().
+
+    png_write_info(png_ptr, info_ptr);
+
+Note that there is one transformation you may need to do before
+png_write_info().  In PNG files, the alpha channel in an image is the
+level of opacity.  If your data is supplied as a level of
+transparency, you can invert the alpha channel before you write it, so
+that 0 is fully transparent and 255 (in 8-bit or paletted images) or
+65535 (in 16-bit images) is fully opaque, with
+
+    png_set_invert_alpha(png_ptr);
 
+This must appear before png_write_info() instead of later with the
+other transformations because in the case of paletted images the tRNS
+chunk data has to be inverted before the tRNS chunk is written.  If
+your image is not a paletted image, the tRNS data (which in such cases
+represents a single color to be rendered as transparent) won't need to
+be changed, and you can safely do this transformation after your
+png_write_info() call.
+
+If you need to write a private chunk that you want to appear before
+the PLTE chunk when PLTE is present, you can write the PNG info in
+two steps, and insert code to write your own chunk between them:
+
+    png_write_info_before_PLTE(png_ptr, info_ptr);
+    png_set_unknown_chunks(png_ptr, info_ptr, ...);
     png_write_info(png_ptr, info_ptr);
 
 After you've written the file information, you can set up the library
@@ -1472,14 +1966,15 @@
 data.  For example, don't swap red and blue on grayscale data.
 
 PNG files store RGB pixels packed into 3 or 6 bytes.  This code tells
-the library to expand the input data to 4 or 8 bytes per pixel
-(or expand 1 or 2-byte grayscale data to 2 or 4 bytes per pixel).
+the library to strip input data that has 4 or 8 bytes per pixel down
+to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2
+bytes per pixel).
 
     png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
 
-where the 0 is the value that will be put in the 4th byte, and the
-location is either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending
-upon whether the filler byte is stored XRGB or RGBX.
+where the 0 is unused, and the location is either PNG_FILLER_BEFORE or
+PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel
+is stored XRGB or RGBX.
 
 PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
 they can, resulting in, for example, 8 pixels per byte for 1 bit files.
@@ -1490,7 +1985,7 @@
 
 PNG files reduce possible bit depths to 1, 2, 4, 8, and 16.  If your
 data is of another bit depth, you can write an sBIT chunk into the
-file so that decoders can get the original data if desired.
+file so that decoders can recover the original data if desired.
 
     /* Set the true bit depth of the image data */
     if (color_type & PNG_COLOR_MASK_COLOR)
@@ -1555,7 +2050,21 @@
        row_info, png_bytep data)
 
 See pngtest.c for a working example.  Your function will be called
-before any of the other transformations have been processed.
+before any of the other transformations are processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function.
+
+    png_set_user_transform_info(png_ptr, user_ptr, 0, 0);
+
+The user_channels and user_depth parameters of this function are ignored
+when writing; you can set them to zero as shown.
+
+You can retrieve the pointer via the function png_get_user_transform_ptr().
+For example:
+
+    voidp write_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
 
 It is possible to have libpng flush any pending output, either manually,
 or automatically after a certain number of lines have been written.  To
@@ -1579,8 +2088,10 @@
 only degrade the compression performance by a few percent over images
 that do not use flushing.
 
+Writing the image data
+
 That's it for the transformations.  Now you can write the image data.
-The simplest way to do this is in one function call.  If have the
+The simplest way to do this is in one function call.  If you have the
 whole image in memory, you can just call png_write_image() and libpng
 will write the image.  You will need to pass in an array of pointers to
 each row.  This function automatically handles interlacing, so you don't
@@ -1605,15 +2116,15 @@
 row_pointers is the same as in the png_write_image() call.
 
 If you are just writing one row at a time, you can do this with
-row_pointers:
+a single row_pointer instead of an array of row_pointers:
 
     png_bytep row_pointer = row;
 
-    png_write_row(png_ptr, &row_pointer);
+    png_write_row(png_ptr, row_pointer);
 
 When the file is interlaced, things can get a good deal more
-complicated.  The only currently (as of February 1998 -- PNG Specification
-version 1.0, dated October 1996) defined interlacing scheme for PNG files
+complicated.  The only currently (as of the PNG Specification
+version 1.2, dated July 1999) defined interlacing scheme for PNG files
 is the "Adam7" interlace scheme, that breaks down an
 image into seven smaller images of varying size.  libpng will build
 these images for you, or you can do them yourself.  If you want to
@@ -1642,6 +2153,8 @@
 you may want to read about interlacing in the PNG specification,
 and only update the rows that are actually used.
 
+Finishing a sequential write
+
 After you are finished writing the image, you should finish writing
 the file.  If you are interested in writing comments or time, you should
 pass an appropriately filled png_info pointer.  If you are not interested,
@@ -1653,32 +2166,120 @@
 
     png_destroy_write_struct(&png_ptr, &info_ptr);
 
-You must free any data you allocated for info_ptr, such as comments,
-palette, or histogram, before the call to png_destroy_write_struct();
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
 
+    png_free_data(png_ptr, info_ptr, mask, n)
+    mask  - identifies data to be freed, a mask
+            containing the logical OR of one or
+            more of
+              PNG_FREE_PLTE, PNG_FREE_TRNS,
+              PNG_FREE_HIST, PNG_FREE_ICCP,
+              PNG_FREE_PCAL, PNG_FREE_ROWS,
+              PNG_FREE_SCAL, PNG_FREE_SPLT,
+              PNG_FREE_TEXT, PNG_FREE_UNKN,
+            or simply PNG_FREE_ALL
+    n     - sequence number of item to be freed
+            (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user  and not by libpng,  and will in those
+cases do nothing.  The "n" parameter is ignored if only one item
+of the selected data type, such as PLTE, is allowed.  If "n" is not
+-1, and multiple items are allowed for the data type identified in
+the mask, such as text or sPLT, only the n'th item is freed.
+
+If you allocated data such as a palette that you passed
+in to libpng with png_set_*, you must not free it until just before the call to
+png_destroy_write_struct().
+
+The default behavior is only to free data that was allocated internally
+by libpng.  This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+    png_data_freer(png_ptr, info_ptr, freer, mask)
+    mask   - which data elements are affected
+             same choices as in png_free_data()
+    freer  - one of
+               PNG_DESTROY_WILL_FREE_DATA
+               PNG_SET_WILL_FREE_DATA
+               PNG_USER_WILL_FREE_DATA
+
+For example, to transfer responsibility for some data from a read structure
+to a write structure, you could use
+
+    png_data_freer(read_ptr, read_info_ptr,
+       PNG_USER_WILL_FREE_DATA,
+       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+    png_data_freer(write_ptr, write_info_ptr,
+       PNG_DESTROY_WILL_FREE_DATA,
+       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+
+thereby briefly reassigning responsibility for freeing to the user but
+immediately afterwards reassigning it once more to the write_destroy
+function.  Having done this, it would then be safe to destroy the read
+structure and continue to use the PLTE, tRNS, and hIST data in the write
+structure.
+
+This function only affects data that has already been allocated.
+You can call this function before calling after the png_set_*() functions
+to control whether the user or png_destroy_*() is supposed to free the data.
+When the user assumes responsibility for libpng-allocated data, the
+application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it.
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key.  Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
 For a more compact example of writing a PNG image, see the file example.c.
 
-
 V. Modifying/Customizing libpng:
 
-There are two issues here.  The first is changing how libpng does
+There are three issues here.  The first is changing how libpng does
 standard things like memory allocation, input/output, and error handling.
 The second deals with more complicated things like adding new chunks,
 adding new transformations, and generally changing how libpng works.
+Both of those are compile-time issues; that is, they are generally
+determined at the time the code is written, and there is rarely a need
+to provide the user with a means of changing them.  The third is a
+run-time issue:  choosing between and/or tuning one or more alternate
+versions of computationally intensive routines; specifically, optimized
+assembly-language (and therefore compiler- and platform-dependent)
+versions.
+
+Memory allocation, input/output, and error handling
 
 All of the memory allocation, input/output, and error handling in libpng
-goes through callbacks that are user settable.  The default routines are
-in pngmem.c, pngrio.c, pngwio.c, and pngerror.c respectively.  To change
-these functions, call the appropriate png_set_???_fn() function.
-
-Memory allocation is done through the functions png_large_malloc(),
-png_malloc(), png_realloc(), png_large_free(), and png_free().  These
-currently just call the standard C functions.  The large functions must
-handle exactly 64K, but they don't have to handle more than that.  If
+goes through callbacks that are user-settable.  The default routines are
+in pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively.  To change
+these functions, call the appropriate png_set_*_fn() function.
+
+Memory allocation is done through the functions png_malloc(), png_zalloc(),
+and png_free().  These currently just call the standard C functions.  If
 your pointers can't access more then 64K at a time, you will want to set
 MAXSEG_64K in zlib.h.  Since it is unlikely that the method of handling
 memory allocation on a platform will change between applications, these
-functions must be modified in the library at compile time.
+functions must be modified in the library at compile time.  If you prefer
+to use a different method of allocating and freeing data, you can use
+
+    png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
+      malloc_fn, png_free_ptr free_fn)
+
+This function also provides a void pointer that can be retrieved via
+
+    mem_ptr=png_get_mem_ptr(png_ptr);
+
+Your replacement memory functions must have prototypes as follows:
+
+    png_voidp malloc_fn(png_structp png_ptr, png_uint_32 size);
+    void free_fn(png_structp png_ptr, png_voidp ptr);
 
 Input/Output in libpng is done through png_read() and png_write(),
 which currently just call fread() and fwrite().  The FILE * is stored in
@@ -1699,7 +2300,7 @@
     voidp read_io_ptr = png_get_io_ptr(read_ptr);
     voidp write_io_ptr = png_get_io_ptr(write_ptr);
 
-The replacement I/O functions should have prototypes as follows:
+The replacement I/O functions must have prototypes as follows:
 
     void user_read_data(png_structp png_ptr,
         png_bytep data, png_uint_32 length);
@@ -1714,15 +2315,20 @@
 Error handling in libpng is done through png_error() and png_warning().
 Errors handled through png_error() are fatal, meaning that png_error()
 should never return to its caller.  Currently, this is handled via
-setjmp() and longjmp(), but you could change this to do things like
-exit() if you should wish.  On non-fatal errors, png_warning() is called
+setjmp() and longjmp() (unless you have compiled libpng with
+PNG_SETJMP_NOT_SUPPORTED, in which case it is handled via PNG_ABORT()),
+but you could change this to do things like exit() if you should wish.
+
+On non-fatal errors, png_warning() is called
 to print a warning message, and then control returns to the calling code.
 By default png_error() and png_warning() print a message on stderr via
-fprintf() unless the library is compiled with PNG_NO_STDIO defined.  If
-you wish to change the behavior of the error functions, you will need to
-set up your own message callbacks.  These functions are normally supplied
-at the time that the png_struct is created.  It is also possible to change
-these functions after png_create_???_struct() has been called by calling:
+fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined
+(because you don't want the messages) or PNG_NO_STDIO defined (because
+fprintf() isn't available).  If you wish to change the behavior of the error
+functions, you will need to set up your own message callbacks.  These
+functions are normally supplied at the time that the png_struct is created.
+It is also possible to redirect errors and warnings to your own replacement
+functions after png_create_*_struct() has been called by calling:
 
     png_set_error_fn(png_structp png_ptr,
         png_voidp error_ptr, png_error_ptr error_fn,
@@ -1746,18 +2352,28 @@
 However, there are some uncertainties about the status of local variables
 after a longjmp, so the user may want to be careful about doing anything after
 setjmp returns non-zero besides returning itself.  Consult your compiler
-documentation for more details.
+documentation for more details.  For an alternative approach, you may wish
+to use the "cexcept" facility (see http://cexcept.sourceforge.net).
+
+Custom chunks
 
-If you need to read or write custom chunks, you will need to get deeper
-into the libpng code, as a mechanism has not yet been supplied for user
-callbacks with custom chunks.  First, read the PNG specification, and have
-a first level of understanding of how it works.  Pay particular attention
-to the sections that describe chunk names, and look at how other chunks
-were designed, so you can do things similarly.  Second, check out the
-sections of libpng that read and write chunks.  Try to find a chunk that
-is similar to yours and copy off of it.  More details can be found in the
-comments inside the code.  A way of handling unknown chunks in a generic
-method, potentially via callback functions, would be best.
+If you need to read or write custom chunks, you may need to get deeper
+into the libpng code.  The library now has mechanisms for storing
+and writing chunks of unknown type; you can even declare callbacks
+for custom chunks.  Hoewver, this may not be good enough if the
+library code itself needs to know about interactions between your
+chunk and existing `intrinsic' chunks.
+
+If you need to write a new intrinsic chunk, first read the PNG
+specification. Acquire a first level of
+understanding of how it works.  Pay particular attention to the
+sections that describe chunk names, and look at how other chunks were
+designed, so you can do things similarly.  Second, check out the
+sections of libpng that read and write chunks.  Try to find a chunk
+that is similar to yours and use it as a template.  More details can
+be found in the comments inside the code.  It is best to handle unknown
+chunks in a generic method, via callback functions, instead of by
+modifying libpng functions.
 
 If you wish to write your own transformation for the data, look through
 the part of the code that does the transformations, and check out some of
@@ -1765,22 +2381,19 @@
 transformation to the one you want to add and copy off of it.  More details
 can be found in the comments inside the code itself.
 
-Configuring for 16 bit platforms:
+Configuring for 16 bit platforms
 
-You may need to change the png_large_malloc() and png_large_free()
-routines in pngmem.c, as these are required to allocate 64K, although
-there is already support for many of the common DOS compilers.  Also,
-you will want to look into zconf.h to tell zlib (and thus libpng) that
+You will want to look into zconf.h to tell zlib (and thus libpng) that
 it cannot allocate more then 64K at a time.  Even if you can, the memory
 won't be accessible.  So limit zlib and libpng to 64K by defining MAXSEG_64K.
 
-Configuring for DOS:
+Configuring for DOS
 
 For DOS users who only have access to the lower 640K, you will
 have to limit zlib's memory usage via a png_set_compression_mem_level()
 call.  See zlib.h or zconf.h in the zlib library for more information.
 
-Configuring for Medium Model:
+Configuring for Medium Model
 
 Libpng's support for medium model has been tested on most of the popular
 compilers.  Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
@@ -1788,14 +2401,14 @@
 all set.  Everything in the library (except for zlib's structure) is
 expecting far data.  You must use the typedefs with the p or pp on
 the end for pointers (or at least look at them and be careful).  Make
-note that the row's of data are defined as png_bytepp, which is an
+note that the rows of data are defined as png_bytepp, which is an
 unsigned char far * far *.
 
 Configuring for gui/windowing platforms:
 
 You will need to write new error and warning functions that use the GUI
 interface, as described previously, and set them to be the error and
-warning functions at the time that png_create_???_struct() is called,
+warning functions at the time that png_create_*_struct() is called,
 in order to have them available during the structure initialization.
 They can be changed later via png_set_error_fn().  On some compilers,
 you may also have to change the memory allocators (png_malloc, etc.).
@@ -1839,8 +2452,9 @@
     png_set_compression_window_bits(png_ptr,
         window_bits);
     png_set_compression_method(png_ptr, method);
+    png_set_compression_buffer_size(png_ptr, size);
 
-Controlling row filtering:
+Controlling row filtering
 
 If you want to control whether libpng uses filtering or not, which
 filters are used, and how it goes about picking row filters, you
@@ -1852,24 +2466,34 @@
 for any images with bit depths less than 8 bits/pixel.
 
 The 'method' parameter sets the main filtering method, which is
-currently only '0' in the PNG 1.0 specification.  The 'filters'
+currently only '0' in the PNG 1.2 specification.  The 'filters'
 parameter sets which filter(s), if any, should be used for each
 scanline.  Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
 to turn filtering on and off, respectively.
 
 Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,
 PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise
-ORed together '|' to specify one or more filters to use.  These
-filters are described in more detail in the PNG specification.  If
+ORed together with '|' to specify one or more filters to use.
+These filters are described in more detail in the PNG specification.  If
 you intend to change the filter type during the course of writing
 the image, you should start with flags set for all of the filters
 you intend to use so that libpng can initialize its internal
 structures appropriately for all of the filter types.
 
     filters = PNG_FILTER_NONE | PNG_FILTER_SUB
-       | PNG_FILTER_UP;
+              PNG_FILTER_UP | PNG_FILTER_AVE |
+              PNG_FILTER_PAETH | PNG_ALL_FILTERS;
+    or
+    filters = one of PNG_FILTER_VALUE_NONE,
+              PNG_FILTER_VALUE_SUB, PNG_FILTER_VALUE_UP,
+              PNG_FILTER_VALUE_AVE, PNG_FILTER_VALUE_PAETH
+
     png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
        filters);
+              The second parameter can also be PNG_INTRAPIXEL_DIFFERENCING
+              if you are writing a PNG to be embedded in a MNG
+              datastream.  This parameter must be the same as the
+              value of filter_method used in png_set_IHDR().
 
 It is also possible to influence how libpng chooses from among the
 available filters.  This is done in two ways - by telling it how
@@ -1906,7 +2530,7 @@
 are given only to help explain the function usage.  Little testing has
 been done to find optimum values for either the costs or the weights.
 
-Removing unwanted object code:
+Removing unwanted object code
 
 There are a bunch of #define's in pngconf.h that control what parts of
 libpng are compiled.  All the defines end in _SUPPORTED.  If you are
@@ -1916,13 +2540,13 @@
 PNG_NO_.
 
 You can also turn all of the transforms and ancillary chunk capabilities
-off en masse with  compiler directives that define
+off en masse with compiler directives that define
 PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
 or all four,
 along with directives to turn on any of the capabilities that you do
 want.  The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable
 the extra transformations but still leave the library fully capable of reading
-and writing PNG files with all known public chunks [except for sPLT].
+and writing PNG files with all known public chunks
 Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive
 produces a library that is incapable of reading or writing ancillary chunks.
 If you are not using the progressive reading capability, you can
@@ -1944,7 +2568,7 @@
 The size of the library itself should not be an issue, because only
 those sections that are actually used will be loaded into memory.
 
-Requesting debug printout:
+Requesting debug printout
 
 The macro definition PNG_DEBUG can be used to request debugging
 printout.  Set it to an integer value in the range 0 to 3.  Higher
@@ -1981,7 +2605,33 @@
 having level = 0 will be printed.  There aren't any such statements in
 this version of libpng, but if you insert some they will be printed.
 
-VI.  Changes to Libpng from version 0.88
+
+VI.  MNG support
+
+The MNG specification (available at http://www.libpng.org/pub/mng) allows
+certain extensions to PNG for PNG images that are embedded in MNG datastreams.
+Libpng can support some of these extensions.  To enable them, use the
+png_permit_mng_features() function:
+
+   feature_set = png_permit_mng_features(png_ptr, mask)
+   mask is a png_uint_32 containing the logical OR of the
+        features you want to enable.  These include
+        PNG_FLAG_MNG_EMPTY_PLTE
+        PNG_FLAG_MNG_FILTER_64
+        PNG_ALL_MNG_FEATURES
+   feature_set is a png_32_uint that is the logical AND of
+      your mask with the set of MNG features that is
+      supported by the version of libpng that you are using.
+
+It is an error to use this function when reading or writing a standalone
+PNG file with the PNG 8-byte signature.  The PNG datastream must be wrapped
+in a MNG datastream.  As a minimum, it must have the MNG 8-byte signature
+and the MHDR and MEND chunks.  Libpng does not provide support for these
+or any other MNG chunks; your application must provide its own support for
+them.  You may wish to consider using libmng (available at
+http://www.libmng.com) instead.
+
+VII.  Changes to Libpng from version 0.88
 
 It should be noted that versions of libpng later than 0.96 are not
 distributed by the original libpng author, Guy Schalnat, nor by
@@ -1992,8 +2642,10 @@
 
 The old libpng functions png_read_init(), png_write_init(),
 png_info_init(), png_read_destroy(), and png_write_destory() have been
-moved to PNG_INTERNAL in version 0.95 to discourage their use.  The
-preferred method of creating and initializing the libpng structures is
+moved to PNG_INTERNAL in version 0.95 to discourage their use.  These
+functions will be removed from libpng version 2.0.0.
+
+The preferred method of creating and initializing the libpng structures is
 via the png_create_read_struct(), png_create_write_struct(), and
 png_create_info_struct() because they isolate the size of the structures
 from the application, allow version error checking, and also allow the
@@ -2010,20 +2662,34 @@
 because this caused applications that do not use custom error functions
 to fail if the png_ptr was not initialized to zero.  It is still possible
 to set the error callbacks AFTER png_read_init(), or to change them with
-png_set_error_fn(), which is essentially the same function, but with a
-new name to force compilation errors with applications that try to use
-the old method.
+png_set_error_fn(), which is essentially the same function, but with a new
+name to force compilation errors with applications that try to use the old
+method.
+
+Starting with version 1.0.7, you can find out which version of the library
+you are using at run-time:
+
+   png_uint_32 libpng_vn = png_access_version_number();
 
-VII. Y2K Compliance in libpng
+The number libpng_vn is constructed from the major version, minor
+version with leading zero, and release number with leading zero,
+(e.g., libpng_vn for version 1.0.7 is 10007).
 
-January 13, 1999
+You can also check which version of png.h you used when compiling your
+application:
+
+   png_uint_32 application_vn = PNG_LIBPNG_VER;
+
+VIII. Y2K Compliance in libpng
+
+January 31, 2001
 
 Since the PNG Development group is an ad-hoc body, we can't make
 an official declaration.
 
-This is your unofficial assurance that libpng from version 0.81 and
-upward are Y2K compliant.  It is my belief that earlier versions were
-also Y2K compliant.
+This is your unofficial assurance that libpng from version 0.71 and
+upward through 1.0.9 are Y2K compliant.  It is my belief that earlier
+versions were also Y2K compliant.
 
 Libpng only has three year fields.  One is a 2-byte unsigned integer that
 will hold years up to 65535.  The other two hold the date in text
@@ -2038,7 +2704,7 @@
 
 There are seven time-related functions:
 
-    png_convert_to_rfc_1123() in png.c 
+    png_convert_to_rfc_1123() in png.c
       (formerly png_convert_to_rfc_1152() in error)
     png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
     png_convert_from_time_t() in pngwrite.c
@@ -2047,20 +2713,23 @@
     png_set_tIME() in pngset.c
     png_write_tIME() in pngwutil.c, called in pngwrite.c
 
-All appear to handle dates properly in a Y2K environment.  The 
+All appear to handle dates properly in a Y2K environment.  The
 png_convert_from_time_t() function calls gmtime() to convert from system
 clock time, which returns (year - 1900), which we properly convert to
 the full 4-digit year.  There is a possibility that applications using
 libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
-function, or incorrectly passing only a 2-digit year instead of
-"year - 1900" into the png_convert_from_struct_tm() function, but this
-is not under our control.  The libpng documentation has always stated
-that it works with 4-digit years, and the APIs have been documented as
-such.
+function, or that they are incorrectly passing only a 2-digit year
+instead of "year - 1900" into the png_convert_from_struct_tm() function,
+but this is not under our control.  The libpng documentation has always
+stated that it works with 4-digit years, and the APIs have been
+documented as such.
 
 The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
 integer to hold the year, and can hold years as large as 65535.
 
+zlib, upon which libpng depends, is also Y2K compliant.  It contains
+no date-related code.
+
 
    Glenn Randers-Pehrson
    libpng maintainer

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/KNOWNBUG
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/KNOWNBUG	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/KNOWNBUG	Sat Jul 13 21:26:43 2002
@@ -1,32 +1,4 @@
 
-Known bugs and suggested enhancements in libpng-1.0.3
-
-
-1. March 15, 1998 -- OPTIMIZATION -- Kevin Bracey
-
-   Loops need to be optimized everywhere
-
-   Make them count down instead of up -- Kevin Bracey
-
-   Optimizing compilers don't need this, and making
-   the change would be error prone -- Tom Lane, Glenn R-P
-
-   Question whether i-- or --i is better.
-
-   STATUS: Under investigation, postponed until after
-   libpng-1.0.3.  About 160 loops will be turned around
-   in libpng-1.0.Nn, for testing.
-
-2. July 4, 1998 -- ENHANCEMENT -- Glenn R-P
-
-   libpng-1.0.2 and earlier transform colors to gamma=1.0 space for
-   merging with background, and then back to the image's gamma.  The
-   bit_depth of the intermediate (gamma=1.0) representation is probably
-   not sufficient.  In the typical gamma=1/2.2 situation, the linear
-   pixels need about 4 more bits than the gamma-encoded ones, to avoid
-   loss of precision.  A similar situation exists with the rgb_to_gray
-   operation.
-
-   STATUS: under development.
-
+Known bugs in libpng-1.0.9
 
+None.

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngread.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngread.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngread.c	Sat Jul 13 21:26:43 2002
@@ -1,11 +1,11 @@
 
 /* pngread.c - read a PNG file
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This file contains routines that an application calls directly to
  * read a PNG file or stream.
@@ -15,7 +15,7 @@
 #include "png.h"
 
 /* Create a PNG structure for reading, and allocate any memory needed. */
-png_structp
+png_structp PNGAPI
 png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
    png_error_ptr error_fn, png_error_ptr warn_fn)
 {
@@ -26,7 +26,7 @@
 }
 
 /* Alternate create PNG structure for reading, and allocate any memory needed. */
-png_structp
+png_structp PNGAPI
 png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
    png_malloc_ptr malloc_fn, png_free_ptr free_fn)
@@ -34,9 +34,15 @@
 #endif /* PNG_USER_MEM_SUPPORTED */
 
    png_structp png_ptr;
+
+#ifdef PNG_SETJMP_SUPPORTED
 #ifdef USE_FAR_KEYWORD
    jmp_buf jmpbuf;
 #endif
+#endif
+
+   int i;
+
    png_debug(1, "in png_create_read_struct\n");
 #ifdef PNG_USER_MEM_SUPPORTED
    if ((png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
@@ -47,6 +53,8 @@
    {
       return (png_structp)NULL;
    }
+
+#ifdef PNG_SETJMP_SUPPORTED
 #ifdef USE_FAR_KEYWORD
    if (setjmp(jmpbuf))
 #else
@@ -54,29 +62,53 @@
 #endif
    {
       png_free(png_ptr, png_ptr->zbuf);
+      png_ptr->zbuf=NULL;
       png_destroy_struct(png_ptr);
       return (png_structp)NULL;
    }
 #ifdef USE_FAR_KEYWORD
    png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
 #endif
+#endif
 
 #ifdef PNG_USER_MEM_SUPPORTED
    png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
-#endif /* PNG_USER_MEM_SUPPORTED */
+#endif
 
    png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
 
-   /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
-    * we must recompile any applications that use any older library version.
-    * For versions after libpng 1.0, we will be compatible, so we need
-    * only check the first digit.
-    */
-   if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
-       (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+   i=0;
+   do
    {
-      png_error(png_ptr,
-         "Incompatible libpng version in application and library");
+     if(user_png_ver[i] != png_libpng_ver[i])
+        png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+   } while (png_libpng_ver[i++]);
+
+   if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
+   {
+     /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+      * we must recompile any applications that use any older library version.
+      * For versions after libpng 1.0, we will be compatible, so we need
+      * only check the first digit.
+      */
+     if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+         (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+     {
+        png_error(png_ptr,
+           "Incompatible libpng version in application and library");
+     }
+
+     /* Libpng 1.0.6 was not binary compatible, due to insertion of the
+        info_ptr->free_me member.  Note to maintainer: this test can be
+        removed from version 2.0.0 and beyond because the previous test
+        would have already rejected it. */
+
+     if (user_png_ver[4] == '6' && user_png_ver[2] == '0' &&
+         user_png_ver[0] == '1' && user_png_ver[5] == '\0')
+     {
+        png_error(png_ptr,
+           "Application must be recompiled; version 1.0.6 was incompatible");
+     }
    }
 
    /* initialize zbuf - compression buffer */
@@ -107,20 +139,59 @@
 /* Initialize PNG structure for reading, and allocate any memory needed.
    This interface is deprecated in favour of the png_create_read_struct(),
    and it will eventually disappear. */
-void
+#undef png_read_init
+void PNGAPI
 png_read_init(png_structp png_ptr)
 {
+   /* We only come here via pre-1.0.7-compiled applications */
+   png_read_init_2(png_ptr, "1.0.0", 10000, 10000);
+}
+
+void PNGAPI
+png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
+   png_size_t png_struct_size, png_size_t png_info_size)
+{
+#ifdef PNG_SETJMP_SUPPORTED
    jmp_buf tmp_jmp;  /* to save current jump buffer */
+#endif
+
+   int i=0;
+   do
+   {
+     if(user_png_ver[i] != png_libpng_ver[i])
+     {
+#ifdef PNG_LEGACY_SUPPORTED
+       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+#else
+       png_ptr->error_fn=(png_error_ptr)NULL;
+       png_error(png_ptr,
+        "Application uses deprecated png_read_init() and must be recompiled.");
+#endif
+     }
+   } while (png_libpng_ver[i++]);
+
+   if(sizeof(png_struct) > png_struct_size ||
+      sizeof(png_info) > png_info_size)
+     {
+       png_ptr->error_fn=(png_error_ptr)NULL;
+       png_error(png_ptr,
+      "Application and library have different sized structs. Please recompile.");
+     }
+
+   png_debug(1, "in png_read_init_2\n");
 
-   png_debug(1, "in png_read_init\n");
+#ifdef PNG_SETJMP_SUPPORTED
    /* save jump buffer and error functions */
    png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
+#endif
 
    /* reset all variables to 0 */
    png_memset(png_ptr, 0, sizeof (png_struct));
 
+#ifdef PNG_SETJMP_SUPPORTED
    /* restore jump buffer */
    png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
+#endif
 
    /* initialize zbuf - compression buffer */
    png_ptr->zbuf_size = PNG_ZBUF_SIZE;
@@ -153,7 +224,7 @@
  * here.  The application can then have access to the signature bytes we
  * read if it is determined that this isn't a valid PNG file.
  */
-void
+void PNGAPI
 png_read_info(png_structp png_ptr, png_infop info_ptr)
 {
    png_debug(1, "in png_read_info\n");
@@ -175,10 +246,69 @@
          else
             png_error(png_ptr, "PNG file corrupted by ASCII conversion");
       }
+      if (num_checked < 3)
+         png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
    }
 
    for(;;)
    {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IHDR;
+      PNG_IDAT;
+      PNG_IEND;
+      PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+      PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+      PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+      PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+      PNG_hIST;
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+      PNG_iCCP;
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      PNG_iTXt;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+      PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+      PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+      PNG_sBIT;
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+      PNG_sCAL;
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+      PNG_sPLT;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      PNG_sRGB;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+      PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+      PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      PNG_zTXt;
+#endif
+#endif /* PNG_GLOBAL_ARRAYS */
       png_byte chunk_length[4];
       png_uint_32 length;
 
@@ -188,17 +318,37 @@
       png_reset_crc(png_ptr);
       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
 
-      png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
+      png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
+         length);
 
       /* This should be a binary subdivision search or a hash for
        * matching the chunk name rather than a linear search.
        */
       if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
          png_handle_IHDR(png_ptr, info_ptr, length);
-      else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
-         png_handle_PLTE(png_ptr, info_ptr, length);
       else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
          png_handle_IEND(png_ptr, info_ptr, length);
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+      else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
+      {
+         if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+            png_ptr->mode |= PNG_HAVE_IDAT;
+         png_handle_unknown(png_ptr, info_ptr, length);
+         if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+            png_ptr->mode |= PNG_HAVE_PLTE;
+         else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+         {
+            if (!(png_ptr->mode & PNG_HAVE_IHDR))
+               png_error(png_ptr, "Missing IHDR before IDAT");
+            else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+                     !(png_ptr->mode & PNG_HAVE_PLTE))
+               png_error(png_ptr, "Missing PLTE before IDAT");
+            break;
+         }
+      }
+#endif
+      else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+         png_handle_PLTE(png_ptr, info_ptr, length);
       else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
       {
          if (!(png_ptr->mode & PNG_HAVE_IHDR))
@@ -235,6 +385,10 @@
       else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
          png_handle_pCAL(png_ptr, info_ptr, length);
 #endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+         png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
 #if defined(PNG_READ_pHYs_SUPPORTED)
       else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
          png_handle_pHYs(png_ptr, info_ptr, length);
@@ -247,6 +401,14 @@
       else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
          png_handle_sRGB(png_ptr, info_ptr, length);
 #endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+         png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+         png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
 #if defined(PNG_READ_tEXt_SUPPORTED)
       else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
          png_handle_tEXt(png_ptr, info_ptr, length);
@@ -263,19 +425,26 @@
       else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
          png_handle_zTXt(png_ptr, info_ptr, length);
 #endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+         png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
       else
          png_handle_unknown(png_ptr, info_ptr, length);
    }
 }
 
 /* optional call to update the users info_ptr structure */
-void
+void PNGAPI
 png_read_update_info(png_structp png_ptr, png_infop info_ptr)
 {
    png_debug(1, "in png_read_update_info\n");
    /* save jump buffer and error functions */
    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
       png_read_start_row(png_ptr);
+   else
+      png_warning(png_ptr,
+      "Ignoring extra png_read_update_info() call; row buffer not reallocated");
    png_read_transform_info(png_ptr, info_ptr);
 }
 
@@ -284,7 +453,7 @@
  * the user to obtain a gamma-corrected palette, for example.
  * If the user doesn't call this, we will do it ourselves.
  */
-void
+void PNGAPI
 png_start_read_image(png_structp png_ptr)
 {
    png_debug(1, "in png_start_read_image\n");
@@ -293,11 +462,16 @@
       png_read_start_row(png_ptr);
 }
 
-void
+void PNGAPI
 png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IDAT;
+   const int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+   const int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
+#endif
    int ret;
-   png_debug2(1, "in png_read_row (row %d, pass %d)\n",
+   png_debug2(1, "in png_read_row (row %lu, pass %d)\n",
       png_ptr->row_number, png_ptr->pass);
    /* save jump buffer and error functions */
    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
@@ -342,7 +516,7 @@
       switch (png_ptr->pass)
       {
          case 0:
-            if (png_ptr->row_number & 7)
+            if (png_ptr->row_number & 0x07)
             {
                if (dsp_row != NULL)
                   png_combine_row(png_ptr, dsp_row,
@@ -352,7 +526,7 @@
             }
             break;
          case 1:
-            if ((png_ptr->row_number & 7) || png_ptr->width < 5)
+            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
             {
                if (dsp_row != NULL)
                   png_combine_row(png_ptr, dsp_row,
@@ -362,7 +536,7 @@
             }
             break;
          case 2:
-            if ((png_ptr->row_number & 7) != 4)
+            if ((png_ptr->row_number & 0x07) != 4)
             {
                if (dsp_row != NULL && (png_ptr->row_number & 4))
                   png_combine_row(png_ptr, dsp_row,
@@ -464,17 +638,25 @@
    png_ptr->row_info.channels = png_ptr->channels;
    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
-   {
-      png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
-         (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
-   }
+   png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
+      (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
 
+   if(png_ptr->row_buf[0])
    png_read_filter_row(png_ptr, &(png_ptr->row_info),
       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
       (int)(png_ptr->row_buf[0]));
 
    png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
       png_ptr->rowbytes + 1);
+   
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+   if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+      (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+   {
+      /* Intrapixel differencing */
+      png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
+   }
+#endif
 
    if (png_ptr->transformations)
       png_do_read_transformations(png_ptr);
@@ -485,8 +667,11 @@
       (png_ptr->transformations & PNG_INTERLACE))
    {
       if (png_ptr->pass < 6)
+/*       old interface (pre-1.0.9):
          png_do_read_interlace(&(png_ptr->row_info),
             png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
+ */
+         png_do_read_interlace(png_ptr);
 
       if (dsp_row != NULL)
          png_combine_row(png_ptr, dsp_row,
@@ -530,10 +715,10 @@
  * not called png_set_interlace_handling(), the display_row buffer will
  * be ignored, so pass NULL to it.
  *
- * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.3.
+ * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.9
  */
 
-void
+void PNGAPI
 png_read_rows(png_structp png_ptr, png_bytepp row,
    png_bytepp display_row, png_uint_32 num_rows)
 {
@@ -579,9 +764,9 @@
  * only call this function once.  If you desire to have an image for
  * each pass of a interlaced image, use png_read_rows() instead.
  *
- * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.3.
+ * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.9
  */
-void
+void PNGAPI
 png_read_image(png_structp png_ptr, png_bytepp image)
 {
    png_uint_32 i,image_height;
@@ -590,7 +775,16 @@
 
    png_debug(1, "in png_read_image\n");
    /* save jump buffer and error functions */
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
    pass = png_set_interlace_handling(png_ptr);
+#else
+   if (png_ptr->interlaced)
+      png_error(png_ptr,
+        "Cannot read interlaced image -- interlace handler disabled.");
+   pass = 1;
+#endif
+
 
    image_height=png_ptr->height;
    png_ptr->num_rows = image_height; /* Make sure this is set correctly */
@@ -610,7 +804,7 @@
  * file, will verify the end is accurate, and will read any comments
  * or time information at the end of the file, if info is not NULL.
  */
-void
+void PNGAPI
 png_read_end(png_structp png_ptr, png_infop info_ptr)
 {
    png_byte chunk_length[4];
@@ -622,6 +816,64 @@
 
    do
    {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IHDR;
+      PNG_IDAT;
+      PNG_IEND;
+      PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+      PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+      PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+      PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+      PNG_hIST;
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+      PNG_iCCP;
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      PNG_iTXt;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+      PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+      PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+      PNG_sBIT;
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+      PNG_sCAL;
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+      PNG_sPLT;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      PNG_sRGB;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+      PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+      PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      PNG_zTXt;
+#endif
+#endif /* PNG_GLOBAL_ARRAYS */
+
       png_read_data(png_ptr, chunk_length, 4);
       length = png_get_uint_32(chunk_length);
 
@@ -632,6 +884,23 @@
 
       if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
          png_handle_IHDR(png_ptr, info_ptr, length);
+      else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+         png_handle_IEND(png_ptr, info_ptr, length);
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+      else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
+      {
+         if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+         {
+            if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT)
+               png_error(png_ptr, "Too many IDAT's found");
+         }
+         else
+            png_ptr->mode |= PNG_AFTER_IDAT;
+         png_handle_unknown(png_ptr, info_ptr, length);
+         if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+            png_ptr->mode |= PNG_HAVE_PLTE;
+      }
+#endif
       else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
       {
          /* Zero length IDATs are legal after the last IDAT has been
@@ -639,13 +908,10 @@
           */
          if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT)
             png_error(png_ptr, "Too many IDAT's found");
-         else
-            png_crc_finish(png_ptr, 0);
+         png_crc_finish(png_ptr, length);
       }
       else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
          png_handle_PLTE(png_ptr, info_ptr, length);
-      else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
-         png_handle_IEND(png_ptr, info_ptr, length);
 #if defined(PNG_READ_bKGD_SUPPORTED)
       else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
          png_handle_bKGD(png_ptr, info_ptr, length);
@@ -670,6 +936,10 @@
       else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
          png_handle_pCAL(png_ptr, info_ptr, length);
 #endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+         png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
 #if defined(PNG_READ_pHYs_SUPPORTED)
       else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
          png_handle_pHYs(png_ptr, info_ptr, length);
@@ -682,6 +952,14 @@
       else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
          png_handle_sRGB(png_ptr, info_ptr, length);
 #endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+         png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+         png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
 #if defined(PNG_READ_tEXt_SUPPORTED)
       else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
          png_handle_tEXt(png_ptr, info_ptr, length);
@@ -698,13 +976,17 @@
       else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
          png_handle_zTXt(png_ptr, info_ptr, length);
 #endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+         png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
       else
          png_handle_unknown(png_ptr, info_ptr, length);
    } while (!(png_ptr->mode & PNG_HAVE_IEND));
 }
 
 /* free all memory used by the read */
-void
+void PNGAPI
 png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
    png_infopp end_info_ptr_ptr)
 {
@@ -712,7 +994,7 @@
    png_infop info_ptr = NULL, end_info_ptr = NULL;
 #ifdef PNG_USER_MEM_SUPPORTED
    png_free_ptr free_fn = NULL;
-#endif /* PNG_USER_MEM_SUPPORTED */
+#endif
 
    png_debug(1, "in png_destroy_read_struct\n");
    /* save jump buffer and error functions */
@@ -733,8 +1015,8 @@
 
    if (info_ptr != NULL)
    {
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
-      png_free(png_ptr, info_ptr->text);
+#if defined(PNG_TEXT_SUPPORTED)
+      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
 #endif
 
 #ifdef PNG_USER_MEM_SUPPORTED
@@ -747,8 +1029,8 @@
 
    if (end_info_ptr != NULL)
    {
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
-      png_free(png_ptr, end_info_ptr->text);
+#if defined(PNG_READ_TEXT_SUPPORTED)
+      png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
 #endif
 #ifdef PNG_USER_MEM_SUPPORTED
       png_destroy_struct_2((png_voidp)end_info_ptr, free_fn);
@@ -770,10 +1052,12 @@
 }
 
 /* free all memory used by the read (old method) */
-void
+void PNGAPI
 png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
 {
+#ifdef PNG_SETJMP_SUPPORTED
    jmp_buf tmp_jmp;
+#endif
    png_error_ptr error_fn;
    png_error_ptr warning_fn;
    png_voidp error_ptr;
@@ -803,13 +1087,37 @@
    png_free(png_ptr, png_ptr->gamma_from_1);
    png_free(png_ptr, png_ptr->gamma_to_1);
 #endif
-   if (png_ptr->flags & PNG_FLAG_FREE_PALETTE)
+#ifdef PNG_FREE_ME_SUPPORTED
+   if (png_ptr->free_me & PNG_FREE_PLTE)
+      png_zfree(png_ptr, png_ptr->palette);
+   png_ptr->free_me &= ~PNG_FREE_PLTE;
+#else
+   if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
       png_zfree(png_ptr, png_ptr->palette);
-   if (png_ptr->flags & PNG_FLAG_FREE_TRANS)
+   png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
+#endif
+#if defined(PNG_tRNS_SUPPORTED) || \
+    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+#ifdef PNG_FREE_ME_SUPPORTED
+   if (png_ptr->free_me & PNG_FREE_TRNS)
+      png_free(png_ptr, png_ptr->trans);
+   png_ptr->free_me &= ~PNG_FREE_TRNS;
+#else
+   if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
       png_free(png_ptr, png_ptr->trans);
+   png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
+#endif
+#endif
 #if defined(PNG_READ_hIST_SUPPORTED)
+#ifdef PNG_FREE_ME_SUPPORTED
+   if (png_ptr->free_me & PNG_FREE_HIST)
+      png_free(png_ptr, png_ptr->hist);
+   png_ptr->free_me &= ~PNG_FREE_HIST;
+#else
    if (png_ptr->flags & PNG_FLAG_FREE_HIST)
       png_free(png_ptr, png_ptr->hist);
+   png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
+#endif
 #endif
 #if defined(PNG_READ_GAMMA_SUPPORTED)
    if (png_ptr->gamma_16_table != NULL)
@@ -847,7 +1155,7 @@
 #endif
 #if defined(PNG_TIME_RFC1123_SUPPORTED)
    png_free(png_ptr, png_ptr->time_buffer);
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
+#endif
 
    inflateEnd(&png_ptr->zstream);
 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
@@ -857,7 +1165,9 @@
    /* Save the important info out of the png_struct, in case it is
     * being used again.
     */
+#ifdef PNG_SETJMP_SUPPORTED
    png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
+#endif
 
    error_fn = png_ptr->error_fn;
    warning_fn = png_ptr->warning_fn;
@@ -875,11 +1185,155 @@
    png_ptr->free_fn = free_fn;
 #endif
 
+#ifdef PNG_SETJMP_SUPPORTED
    png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
+#endif
+
 }
 
-void
+void PNGAPI
 png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
 {
    png_ptr->read_row_fn = read_row_fn;
 }
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+void PNGAPI
+png_read_png(png_structp png_ptr, png_infop info_ptr,
+                           int transforms,
+                           voidp params)
+{
+   int row;
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+   /* invert the alpha channel from opacity to transparency */
+   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+       png_set_invert_alpha(png_ptr);
+#endif
+
+   /* The call to png_read_info() gives us all of the information from the
+    * PNG file before the first IDAT (image data chunk).
+    */
+   png_read_info(png_ptr, info_ptr);
+
+   /* -------------- image transformations start here ------------------- */
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+   /* tell libpng to strip 16 bit/color files down to 8 bits/color */
+   if (transforms & PNG_TRANSFORM_STRIP_16)
+       png_set_strip_16(png_ptr);
+#endif
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+   /* Strip alpha bytes from the input data without combining with the
+    * background (not recommended).
+    */
+   if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
+       png_set_strip_alpha(png_ptr);
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
+   /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
+    * byte into separate bytes (useful for paletted and grayscale images).
+    */
+   if (transforms & PNG_TRANSFORM_PACKING)
+       png_set_packing(png_ptr);
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+   /* Change the order of packed pixels to least significant bit first
+    * (not useful if you are using png_set_packing). */
+   if (transforms & PNG_TRANSFORM_PACKSWAP)
+       png_set_packswap(png_ptr);
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+   /* Expand paletted colors into true RGB triplets
+    * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
+    * Expand paletted or RGB images with transparency to full alpha
+    * channels so the data will be available as RGBA quartets.
+    */
+   if (transforms & PNG_TRANSFORM_EXPAND)
+       if ((png_ptr->bit_depth < 8) ||
+           (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
+           (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
+         png_set_expand(png_ptr);
+#endif
+
+   /* We don't handle background color or gamma transformation or dithering. */
+
+#if defined(PNG_READ_INVERT_SUPPORTED)
+   /* invert monochrome files to have 0 as white and 1 as black */
+   if (transforms & PNG_TRANSFORM_INVERT_MONO)
+       png_set_invert_mono(png_ptr);
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+   /* If you want to shift the pixel values from the range [0,255] or
+    * [0,65535] to the original [0,7] or [0,31], or whatever range the
+    * colors were originally in:
+    */
+   if ((transforms & PNG_TRANSFORM_SHIFT)
+       && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
+   {
+      png_color_8p sig_bit;
+
+      png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+      png_set_shift(png_ptr, sig_bit);
+   }
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED)
+   /* flip the RGB pixels to BGR (or RGBA to BGRA) */
+   if (transforms & PNG_TRANSFORM_BGR)
+       png_set_bgr(png_ptr);
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+   /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
+   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+       png_set_swap_alpha(png_ptr);
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED)
+   /* swap bytes of 16 bit files to least significant byte first */
+   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+       png_set_swap(png_ptr);
+#endif
+
+   /* We don't handle adding filler bytes */
+
+   /* Optional call to gamma correct and add the background to the palette
+    * and update info structure.  REQUIRED if you are expecting libpng to
+    * update the palette for you (ie you selected such a transform above).
+    */
+   png_read_update_info(png_ptr, info_ptr);
+
+   /* -------------- image transformations end here ------------------- */
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+#endif
+   if(info_ptr->row_pointers == NULL)
+   {
+      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
+                                         info_ptr->height * sizeof(png_bytep));
+#ifdef PNG_FREE_ME_SUPPORTED
+      info_ptr->free_me |= PNG_FREE_ROWS;
+#endif
+      for (row = 0; row < (int)info_ptr->height; row++)
+         info_ptr->row_pointers[row] = png_malloc(png_ptr,
+            png_get_rowbytes(png_ptr, info_ptr));
+   }
+
+   png_read_image(png_ptr, info_ptr->row_pointers);
+   info_ptr->valid |= PNG_INFO_IDAT;
+
+   /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
+   png_read_end(png_ptr, info_ptr);
+
+   if(transforms == 0 || params == (voidp)NULL)
+      /* quiet compiler warnings */ return;
+
+}
+#endif

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngmem.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngmem.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngmem.c	Sat Jul 13 21:26:43 2002
@@ -1,11 +1,11 @@
 
 /* pngmem.c - stub functions for memory allocation
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This file provides a location for all memory allocation.  Users who
  * need special memory handling are expected to supply replacement
@@ -23,7 +23,7 @@
 
 /* Allocate memory for a png_struct.  The malloc and memset can be replaced
    by a single call to calloc() if this is thought to improve performance. */
-png_voidp
+png_voidp /* PRIVATE */
 png_create_struct(int type)
 {
 #ifdef PNG_USER_MEM_SUPPORTED
@@ -31,7 +31,7 @@
 }
 
 /* Alternate version of png_create_struct, for use with user-defined malloc. */
-png_voidp
+png_voidp /* PRIVATE */
 png_create_struct_2(int type, png_malloc_ptr malloc_fn)
 {
 #endif /* PNG_USER_MEM_SUPPORTED */
@@ -62,7 +62,7 @@
 
 
 /* Free memory allocated by a png_create_struct() call */
-void
+void /* PRIVATE */
 png_destroy_struct(png_voidp struct_ptr)
 {
 #ifdef PNG_USER_MEM_SUPPORTED
@@ -70,7 +70,7 @@
 }
 
 /* Free memory allocated by a png_create_struct() call */
-void
+void /* PRIVATE */
 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn)
 {
 #endif
@@ -82,12 +82,10 @@
          png_struct dummy_struct;
          png_structp png_ptr = &dummy_struct;
          (*(free_fn))(png_ptr, struct_ptr);
-         struct_ptr = NULL;
          return;
       }
 #endif /* PNG_USER_MEM_SUPPORTED */
       farfree (struct_ptr);
-      struct_ptr = NULL;
    }
 }
 
@@ -110,7 +108,7 @@
  * result, we would be truncating potentially larger memory requests
  * (which should cause a fatal error) and introducing major problems.
  */
-png_voidp
+png_voidp PNGAPI
 png_malloc(png_structp png_ptr, png_uint_32 size)
 {
 #ifndef PNG_USER_MEM_SUPPORTED
@@ -126,7 +124,7 @@
        return png_malloc_default(png_ptr, size);
 }
 
-png_voidp
+png_voidp PNGAPI
 png_malloc_default(png_structp png_ptr, png_uint_32 size)
 {
    png_voidp ret;
@@ -157,8 +155,9 @@
                ret = NULL;
             }
 
-            num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
-            if (num_blocks < 1)
+            if(png_ptr->zlib_window_bits > 14)
+               num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
+            else
                num_blocks = 1;
             if (png_ptr->zlib_mem_level >= 7)
                num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
@@ -192,12 +191,12 @@
             if ((png_size_t)hptr & 0xf)
             {
                hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
-               hptr += 16L;
+               hptr = hptr + 16L;  /* "hptr += 16L" fails on Turbo C++ 3.0 */
             }
             for (i = 0; i < num_blocks; i++)
             {
                png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
-               hptr += (png_uint_32)65536L;
+               hptr = hptr + (png_uint_32)65536L;  /* "+=" fails on TC++3.0 */
             }
 
             png_ptr->offset_table_number = num_blocks;
@@ -225,7 +224,7 @@
 /* free a pointer allocated by png_malloc().  In the default
    configuration, png_ptr is not used, but is passed in case it
    is needed.  If ptr is NULL, return without taking any action. */
-void
+void PNGAPI
 png_free(png_structp png_ptr, png_voidp ptr)
 {
    if (png_ptr == NULL || ptr == NULL)
@@ -235,13 +234,12 @@
    if (png_ptr->free_fn != NULL)
    {
       (*(png_ptr->free_fn))(png_ptr, ptr);
-      ptr = NULL;
       return;
    }
    else png_free_default(png_ptr, ptr);
 }
 
-void
+void PNGAPI
 png_free_default(png_structp png_ptr, png_voidp ptr)
 {
 #endif /* PNG_USER_MEM_SUPPORTED */
@@ -271,7 +269,6 @@
    if (ptr != NULL)
    {
       farfree(ptr);
-      ptr = NULL;
    }
 }
 
@@ -280,7 +277,7 @@
 /* Allocate memory for a png_struct or a png_info.  The malloc and
    memset can be replaced by a single call to calloc() if this is thought
    to improve performance noticably.*/
-png_voidp
+png_voidp /* PRIVATE */
 png_create_struct(int type)
 {
 #ifdef PNG_USER_MEM_SUPPORTED
@@ -290,7 +287,7 @@
 /* Allocate memory for a png_struct or a png_info.  The malloc and
    memset can be replaced by a single call to calloc() if this is thought
    to improve performance noticably.*/
-png_voidp
+png_voidp /* PRIVATE */
 png_create_struct_2(int type, png_malloc_ptr malloc_fn)
 {
 #endif /* PNG_USER_MEM_SUPPORTED */
@@ -331,7 +328,7 @@
 
 
 /* Free memory allocated by a png_create_struct() call */
-void
+void /* PRIVATE */
 png_destroy_struct(png_voidp struct_ptr)
 {
 #ifdef PNG_USER_MEM_SUPPORTED
@@ -339,7 +336,7 @@
 }
 
 /* Free memory allocated by a png_create_struct() call */
-void
+void /* PRIVATE */
 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn)
 {
 #endif /* PNG_USER_MEM_SUPPORTED */
@@ -351,20 +348,16 @@
          png_struct dummy_struct;
          png_structp png_ptr = &dummy_struct;
          (*(free_fn))(png_ptr, struct_ptr);
-         struct_ptr = NULL;
          return;
       }
 #endif /* PNG_USER_MEM_SUPPORTED */
 #if defined(__TURBOC__) && !defined(__FLAT__)
       farfree(struct_ptr);
-      struct_ptr = NULL;
 #else
 # if defined(_MSC_VER) && defined(MAXSEG_64K)
       hfree(struct_ptr);
-      struct_ptr = NULL;
 # else
       free(struct_ptr);
-      struct_ptr = NULL;
 # endif
 #endif
    }
@@ -377,7 +370,7 @@
    need to allocate exactly 64K, so whatever you call here must
    have the ability to do that. */
 
-png_voidp
+png_voidp PNGAPI
 png_malloc(png_structp png_ptr, png_uint_32 size)
 {
 #ifndef PNG_USER_MEM_SUPPORTED
@@ -392,7 +385,7 @@
    else
        return (png_malloc_default(png_ptr, size));
 }
-png_voidp
+png_voidp /* PRIVATE */
 png_malloc_default(png_structp png_ptr, png_uint_32 size)
 {
    png_voidp ret;
@@ -423,7 +416,7 @@
 
 /* Free a pointer allocated by png_malloc().  If ptr is NULL, return
    without taking any action. */
-void
+void PNGAPI
 png_free(png_structp png_ptr, png_voidp ptr)
 {
    if (png_ptr == NULL || ptr == NULL)
@@ -433,33 +426,32 @@
    if (png_ptr->free_fn != NULL)
    {
       (*(png_ptr->free_fn))(png_ptr, ptr);
-      ptr = NULL;
       return;
    }
    else png_free_default(png_ptr, ptr);
 }
-void
+void /* PRIVATE */
 png_free_default(png_structp png_ptr, png_voidp ptr)
 {
+   if (png_ptr == NULL || ptr == NULL)
+      return;
+
 #endif /* PNG_USER_MEM_SUPPORTED */
 
 #if defined(__TURBOC__) && !defined(__FLAT__)
    farfree(ptr);
-   ptr = NULL;
 #else
 # if defined(_MSC_VER) && defined(MAXSEG_64K)
    hfree(ptr);
-   ptr = NULL;
 # else
    free(ptr);
-   ptr = NULL;
 # endif
 #endif
 }
 
 #endif /* Not Borland DOS special memory handler */
 
-png_voidp
+png_voidp /* PRIVATE */
 png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
    png_uint_32 length)
 {
@@ -472,7 +464,7 @@
    return(png_memcpy (s1, s2, size));
 }
 
-png_voidp
+png_voidp /* PRIVATE */
 png_memset_check (png_structp png_ptr, png_voidp s1, int value,
    png_uint_32 length)
 {
@@ -490,7 +482,7 @@
 /* This function is called when the application wants to use another method
  * of allocating and freeing memory.
  */
-void
+void PNGAPI
 png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
   malloc_fn, png_free_ptr free_fn)
 {
@@ -503,7 +495,7 @@
  * functions.  The application should free any memory associated with this
  * pointer before png_write_destroy and png_read_destroy are called.
  */
-png_voidp
+png_voidp PNGAPI
 png_get_mem_ptr(png_structp png_ptr)
 {
    return ((png_voidp)png_ptr->mem_ptr);

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/png.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/png.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/png.c	Sat Jul 13 21:26:44 2002
@@ -1,92 +1,101 @@
 
 /* png.c - location for general purpose libpng functions
  *
- * libpng version 1.0.3 - January 14, 1999
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- * 
+ * libpng version 1.0.9 - January 31, 2001
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
  */
 
 #define PNG_INTERNAL
 #define PNG_NO_EXTERN
 #include "png.h"
 
+/* Generate a compiler error if there is an old png.h in the search path. */
+typedef version_1_0_9 Your_png_h_is_not_version_1_0_9;
+
 /* Version information for C files.  This had better match the version
- * string defined in png.h.
- */
+ * string defined in png.h.  */
 
-char png_libpng_ver[12] = "1.0.3";
+#ifdef PNG_USE_GLOBAL_ARRAYS
+/* png_libpng_ver was changed to a function in version 1.0.5c */
+const char png_libpng_ver[18] = "1.0.9";
 
+/* png_sig was changed to a function in version 1.0.5c */
 /* Place to hold the signature string for a PNG file. */
-png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+const png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
 
-/* Constant strings for known chunk types.  If you need to add a chunk,
- * add a string holding the name here.  If you want to make the code
- * portable to EBCDIC machines, use ASCII numbers, not characters.
- */
-png_byte FARDATA png_IHDR[5] = { 73,  72,  68,  82, '\0'};
-png_byte FARDATA png_IDAT[5] = { 73,  68,  65,  84, '\0'};
-png_byte FARDATA png_IEND[5] = { 73,  69,  78,  68, '\0'};
-png_byte FARDATA png_PLTE[5] = { 80,  76,  84,  69, '\0'};
-png_byte FARDATA png_bKGD[5] = { 98,  75,  71,  68, '\0'};
-png_byte FARDATA png_cHRM[5] = { 99,  72,  82,  77, '\0'};
-png_byte FARDATA png_gAMA[5] = {103,  65,  77,  65, '\0'};
-png_byte FARDATA png_hIST[5] = {104,  73,  83,  84, '\0'};
-png_byte FARDATA png_oFFs[5] = {111,  70,  70, 115, '\0'};
-png_byte FARDATA png_pCAL[5] = {112,  67,  65,  76, '\0'};
-png_byte FARDATA png_pHYs[5] = {112,  72,  89, 115, '\0'};
-png_byte FARDATA png_sBIT[5] = {115,  66,  73,  84, '\0'};
-png_byte FARDATA png_sRGB[5] = {115,  82,  71,  66, '\0'};
-png_byte FARDATA png_tEXt[5] = {116,  69,  88, 116, '\0'};
-png_byte FARDATA png_tIME[5] = {116,  73,  77,  69, '\0'};
-png_byte FARDATA png_tRNS[5] = {116,  82,  78,  83, '\0'};
-png_byte FARDATA png_zTXt[5] = {122,  84,  88, 116, '\0'};
+/* Invoke global declarations for constant strings for known chunk types */
+PNG_IHDR;
+PNG_IDAT;
+PNG_IEND;
+PNG_PLTE;
+PNG_bKGD;
+PNG_cHRM;
+PNG_gAMA;
+PNG_hIST;
+PNG_iCCP;
+PNG_iTXt;
+PNG_oFFs;
+PNG_pCAL;
+PNG_sCAL;
+PNG_pHYs;
+PNG_sBIT;
+PNG_sPLT;
+PNG_sRGB;
+PNG_tEXt;
+PNG_tIME;
+PNG_tRNS;
+PNG_zTXt;
 
 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
 
 /* start of interlace block */
-int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
 
 /* offset to next interlace block */
-int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
 
 /* start of interlace block in the y direction */
-int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
 
 /* offset to next interlace block in the y direction */
-int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
 
-/* Width of interlace block.  This is not currently used - if you need
- * it, uncomment it here and in png.h
-int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
-*/
+/* width of interlace block (used in assembler routines only) */
+#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
+#endif
 
 /* Height of interlace block.  This is not currently used - if you need
  * it, uncomment it here and in png.h
-int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
 */
 
 /* Mask to determine which pixels are valid in a pass */
-int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
+const int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
 
 /* Mask to determine which pixels to overwrite while displaying */
-int FARDATA png_pass_dsp_mask[] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+const int FARDATA png_pass_dsp_mask[]
+   = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
 
+#endif
 
 /* Tells libpng that we have already handled the first "num_bytes" bytes
  * of the PNG file signature.  If the PNG data is embedded into another
  * stream we can set num_bytes = 8 so that libpng will not attempt to read
  * or write any of the magic bytes before it starts on the IHDR.
  */
-void
+
+void PNGAPI
 png_set_sig_bytes(png_structp png_ptr, int num_bytes)
 {
    png_debug(1, "in png_set_sig_bytes\n");
    if (num_bytes > 8)
       png_error(png_ptr, "Too many bytes for PNG signature.");
 
-   png_ptr->sig_bytes = num_bytes < 0 ? 0 : num_bytes;
+   png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
 }
 
 /* Checks whether the supplied bytes match the PNG signature.  We allow
@@ -97,9 +106,10 @@
  * respectively, to be less than, to match, or be greater than the correct
  * PNG signature (this is the same behaviour as strcmp, memcmp, etc).
  */
-int
+int PNGAPI
 png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
 {
+   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
    if (num_to_check > 8)
       num_to_check = 8;
    else if (num_to_check < 1)
@@ -111,26 +121,27 @@
    if (start + num_to_check > 8)
       num_to_check = 8 - start;
 
-   return ((int)(png_memcmp(&sig[start], &png_sig[start], num_to_check)));
+   return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
 }
 
 /* (Obsolete) function to check signature bytes.  It does not allow one
  * to check a partial signature.  This function might be removed in the
  * future - use png_sig_cmp().  Returns true (nonzero) if the file is a PNG.
  */
-int
+int PNGAPI
 png_check_sig(png_bytep sig, int num)
 {
   return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
 }
 
-/* Function to allocate memory for zlib. */
-voidpf
+/* Function to allocate memory for zlib and clear it to 0. */
+voidpf PNGAPI
 png_zalloc(voidpf png_ptr, uInt items, uInt size)
 {
    png_uint_32 num_bytes = (png_uint_32)items * size;
    png_voidp ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
 
+#ifndef PNG_NO_ZALLOC_ZERO
    if (num_bytes > (png_uint_32)0x8000L)
    {
       png_memset(ptr, 0, (png_size_t)0x8000L);
@@ -141,11 +152,12 @@
    {
       png_memset(ptr, 0, (png_size_t)num_bytes);
    }
+#endif
    return ((voidpf)ptr);
 }
 
 /* function to free memory for zlib */
-void
+void PNGAPI
 png_zfree(voidpf png_ptr, voidpf ptr)
 {
    png_free((png_structp)png_ptr, (png_voidp)ptr);
@@ -154,7 +166,7 @@
 /* Reset the CRC variable to 32 bits of 1's.  Care must be taken
  * in case CRC is > 32 bits to leave the top bits 0.
  */
-void
+void /* PRIVATE */
 png_reset_crc(png_structp png_ptr)
 {
    png_ptr->crc = crc32(0, Z_NULL, 0);
@@ -165,7 +177,7 @@
  * also check that this data will actually be used before going to the
  * trouble of calculating it.
  */
-void
+void /* PRIVATE */
 png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
 {
    int need_crc = 1;
@@ -192,7 +204,7 @@
  * and png_info_init() so that applications that want to use a shared
  * libpng don't have to be recompiled if png_info changes size.
  */
-png_infop
+png_infop PNGAPI
 png_create_info_struct(png_structp png_ptr)
 {
    png_infop info_ptr;
@@ -217,7 +229,7 @@
  * png_destroy_write_struct() to free an info struct, but this may be
  * useful for some applications.
  */
-void
+void PNGAPI
 png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
 {
    png_infop info_ptr = NULL;
@@ -243,7 +255,7 @@
  * and applications using it are urged to use png_create_info_struct()
  * instead.
  */
-void
+void PNGAPI
 png_info_init(png_infop info_ptr)
 {
    png_debug(1, "in png_info_init\n");
@@ -251,36 +263,276 @@
    png_memset(info_ptr, 0, sizeof (png_info));
 }
 
+#ifdef PNG_FREE_ME_SUPPORTED
+void PNGAPI
+png_data_freer(png_structp png_ptr, png_infop info_ptr,
+   int freer, png_uint_32 mask)
+{
+   png_debug(1, "in png_data_freer\n");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+   if(freer == PNG_DESTROY_WILL_FREE_DATA)
+      info_ptr->free_me |= mask;
+   else if(freer == PNG_USER_WILL_FREE_DATA)
+      info_ptr->free_me &= ~mask;
+   else
+      png_warning(png_ptr,
+         "Unknown freer parameter in png_data_freer.");
+}
+#endif
+
+void PNGAPI
+png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, int num)
+{
+   png_debug(1, "in png_free_data\n");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+#if defined(PNG_TEXT_SUPPORTED)
+/* free text item num or (if num == -1) all text items */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_TEXT)
+#endif
+{
+   if (num != -1)
+   {
+     if (info_ptr->text && info_ptr->text[num].key)
+     {
+         png_free(png_ptr, info_ptr->text[num].key);
+         info_ptr->text[num].key = NULL;
+     }
+   }
+   else
+   {
+       int i;
+       for (i = 0; i < info_ptr->num_text; i++)
+           png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
+       png_free(png_ptr, info_ptr->text);
+       info_ptr->text = NULL;
+       info_ptr->num_text=0;
+   }
+}
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+/* free any tRNS entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
+#else
+if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
+#endif
+{
+    png_free(png_ptr, info_ptr->trans);
+    info_ptr->valid &= ~PNG_INFO_tRNS;
+    info_ptr->trans = NULL;
+}
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+/* free any sCAL entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_SCAL)
+#endif
+{
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+    png_free(png_ptr, info_ptr->scal_s_width);
+    png_free(png_ptr, info_ptr->scal_s_height);
+    info_ptr->scal_s_width = NULL;
+    info_ptr->scal_s_height = NULL;
+#endif
+    info_ptr->valid &= ~PNG_INFO_sCAL;
+}
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+/* free any pCAL entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_PCAL)
+#endif
+{
+    png_free(png_ptr, info_ptr->pcal_purpose);
+    png_free(png_ptr, info_ptr->pcal_units);
+    info_ptr->pcal_purpose = NULL;
+    info_ptr->pcal_units = NULL;
+    if (info_ptr->pcal_params != NULL)
+    {
+        int i;
+        for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
+        {
+          png_free(png_ptr, info_ptr->pcal_params[i]);
+          info_ptr->pcal_params[i]=NULL;
+        }
+        png_free(png_ptr, info_ptr->pcal_params);
+        info_ptr->pcal_params = NULL;
+    }
+    info_ptr->valid &= ~PNG_INFO_pCAL;
+}
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+/* free any iCCP entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_ICCP)
+#endif
+{
+    png_free(png_ptr, info_ptr->iccp_name);
+    png_free(png_ptr, info_ptr->iccp_profile);
+    info_ptr->iccp_name = NULL;
+    info_ptr->iccp_profile = NULL;
+    info_ptr->valid &= ~PNG_INFO_iCCP;
+}
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+/* free a given sPLT entry, or (if num == -1) all sPLT entries */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_SPLT)
+#endif
+{
+   if (num != -1)
+   {
+      if(info_ptr->splt_palettes)
+      {
+          png_free(png_ptr, info_ptr->splt_palettes[num].name);
+          png_free(png_ptr, info_ptr->splt_palettes[num].entries);
+          info_ptr->splt_palettes[num].name = NULL;
+          info_ptr->splt_palettes[num].entries = NULL;
+      }
+   }
+   else
+   {
+       if(info_ptr->splt_palettes_num)
+       {
+         int i;
+         for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+            png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
+
+         png_free(png_ptr, info_ptr->splt_palettes);
+         info_ptr->splt_palettes = NULL;
+         info_ptr->splt_palettes_num = 0;
+       }
+       info_ptr->valid &= ~PNG_INFO_sPLT;
+   }
+}
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_UNKN)
+#endif
+{
+   if (num != -1)
+   {
+       if(info_ptr->unknown_chunks)
+       {
+          png_free(png_ptr, info_ptr->unknown_chunks[num].data);
+          info_ptr->unknown_chunks[num].data = NULL;
+       }
+   }
+   else
+   {
+       int i;
+
+       if(info_ptr->unknown_chunks_num)
+       {
+         for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
+            png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
+
+         png_free(png_ptr, info_ptr->unknown_chunks);
+         info_ptr->unknown_chunks = NULL;
+         info_ptr->unknown_chunks_num = 0;
+       }
+   }
+}
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+/* free any hIST entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_HIST)  & info_ptr->free_me)
+#else
+if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
+#endif
+{
+    png_free(png_ptr, info_ptr->hist);
+    info_ptr->hist = NULL;
+    info_ptr->valid &= ~PNG_INFO_hIST;
+}
+#endif
+
+/* free any PLTE entry that was internally allocated */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
+#else
+if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
+#endif
+{
+    png_zfree(png_ptr, info_ptr->palette);
+    info_ptr->palette = NULL;
+    info_ptr->valid &= ~PNG_INFO_PLTE;
+    info_ptr->num_palette = 0;
+}
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+/* free any image bits attached to the info structure */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
+#else
+if (mask & PNG_FREE_ROWS)
+#endif
+{
+    if(info_ptr->row_pointers)
+    {
+       int row;
+       for (row = 0; row < (int)info_ptr->height; row++)
+       {
+          png_free(png_ptr, info_ptr->row_pointers[row]);
+          info_ptr->row_pointers[row]=NULL;
+       }
+       png_free(png_ptr, info_ptr->row_pointers);
+       info_ptr->row_pointers=NULL;
+    }
+    info_ptr->valid &= ~PNG_INFO_IDAT;
+}
+#endif
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   if(num == -1)
+     info_ptr->free_me &= ~mask;
+   else
+     info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
+#endif
+}
+
 /* This is an internal routine to free any memory that the info struct is
  * pointing to before re-using it or freeing the struct itself.  Recall
  * that png_free() checks for NULL pointers for us.
  */
-void
+void /* PRIVATE */
 png_info_destroy(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
    png_debug(1, "in png_info_destroy\n");
-   if (info_ptr->text != NULL)
-   {
-      int i;
-      for (i = 0; i < info_ptr->num_text; i++)
-      {
-         png_free(png_ptr, info_ptr->text[i].key);
-      }
-      png_free(png_ptr, info_ptr->text);
-   }
-#endif
-#if defined(PNG_READ_pCAL_SUPPORTED)
-   png_free(png_ptr, info_ptr->pcal_purpose);
-   png_free(png_ptr, info_ptr->pcal_units);
-   if (info_ptr->pcal_params != NULL)
+
+   png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+   if (png_ptr->num_chunk_list)
    {
-      int i;
-      for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
-      {
-         png_free(png_ptr, info_ptr->pcal_params[i]);
-      }
-      png_free(png_ptr, info_ptr->pcal_params);
+       png_free(png_ptr, png_ptr->chunk_list);
+       png_ptr->chunk_list=NULL;
+       png_ptr->num_chunk_list=0;
    }
 #endif
 
@@ -291,7 +543,7 @@
  * functions.  The application should free any memory associated with this
  * pointer before png_write_destroy() or png_read_destroy() are called.
  */
-png_voidp
+png_voidp PNGAPI
 png_get_io_ptr(png_structp png_ptr)
 {
    return (png_ptr->io_ptr);
@@ -300,10 +552,12 @@
 #if !defined(PNG_NO_STDIO)
 /* Initialize the default input/output functions for the PNG file.  If you
  * use your own read or write routines, you can call either png_set_read_fn()
- * or png_set_write_fn() instead of png_init_io().
+ * or png_set_write_fn() instead of png_init_io().  If you have defined
+ * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
+ * necessarily available.
  */
-void
-png_init_io(png_structp png_ptr, FILE *fp)
+void PNGAPI
+png_init_io(png_structp png_ptr, png_FILE_p fp)
 {
    png_debug(1, "in png_init_io\n");
    png_ptr->io_ptr = (png_voidp)fp;
@@ -314,7 +568,7 @@
 /* Convert the supplied time into an RFC 1123 string suitable for use in
  * a "Creation Time" or other text-based time string.
  */
-png_charp
+png_charp PNGAPI
 png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
 {
    static PNG_CONST char short_months[12][4] =
@@ -327,6 +581,17 @@
          sizeof(char)));
    }
 
+#if defined(_WIN32_WCE)
+  {
+     wchar_t time_buf[29];
+     wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),
+              ptime->day % 32, short_months[(ptime->month - 1) % 12],
+              ptime->year, ptime->hour % 24, ptime->minute % 60,
+              ptime->second % 61);
+     WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29,
+        NULL, NULL);
+  }
+#else
 #ifdef USE_FAR_KEYWORD
    {
       char near_time_buf[29];
@@ -343,17 +608,104 @@
                ptime->year, ptime->hour % 24, ptime->minute % 60,
                ptime->second % 61);
 #endif
+#endif /* _WIN32_WCE */
    return ((png_charp)png_ptr->time_buffer);
 }
 #endif /* PNG_TIME_RFC1123_SUPPORTED */
 
-png_charp
+#if 0
+/* Signature string for a PNG file. */
+png_bytep PNGAPI
+png_sig_bytes(void)
+{
+   return ((png_bytep)"\211\120\116\107\015\012\032\012");
+}
+#endif
+
+png_charp PNGAPI
 png_get_copyright(png_structp png_ptr)
 {
-   if(png_ptr == NULL)
-     /* silence compiler warning about unused png_ptr */ ;
-   return("\n libpng version 1.0.3 - January 14, 1999\n\
-   Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.\n\
+   if (png_ptr != NULL || png_ptr == NULL)  /* silence compiler warning */
+   return ((png_charp) "\n libpng version 1.0.9 - January 31, 2001\n\
+   Copyright (c) 1998-2001 Glenn Randers-Pehrson\n\
    Copyright (c) 1996, 1997 Andreas Dilger\n\
-   Copyright (c) 1998, 1999, Glenn Randers-Pehrson\n");
+   Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.\n");
+   return ((png_charp) "");
+}
+
+/* The following return the library version as a short string in the
+ * format 1.0.0 through 99.99.99zz.  To get the version of *.h files used
+ * with your application, print out PNG_LIBPNG_VER_STRING, which is defined
+ * in png.h.
+ */
+
+png_charp PNGAPI
+png_get_libpng_ver(png_structp png_ptr)
+{
+   /* Version of *.c files used when building libpng */
+   if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
+      return((png_charp) "1.0.9");
+   return((png_charp) "1.0.9");
+}
+
+png_charp PNGAPI
+png_get_header_ver(png_structp png_ptr)
+{
+   /* Version of *.h files used when building libpng */
+   if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
+      return((png_charp) PNG_LIBPNG_VER_STRING);
+   return((png_charp) PNG_LIBPNG_VER_STRING);
+}
+
+png_charp PNGAPI
+png_get_header_version(png_structp png_ptr)
+{
+   /* Returns longer string containing both version and date */
+   if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
+      return((png_charp) PNG_HEADER_VERSION_STRING);
+   return((png_charp) PNG_HEADER_VERSION_STRING);
+}
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+int PNGAPI
+png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
+{
+   /* check chunk_name and return "keep" value if it's on the list, else 0 */
+   int i;
+   png_bytep p;
+   if((png_ptr == NULL && chunk_name == NULL) || png_ptr->num_chunk_list<=0)
+      return 0;
+   p=png_ptr->chunk_list+png_ptr->num_chunk_list*5-5;
+   for (i = png_ptr->num_chunk_list; i; i--, p-=5)
+      if (!png_memcmp(chunk_name, p, 4))
+        return ((int)*(p+4));
+   return 0;
+}
+#endif
+
+/* This function, added to libpng-1.0.6g, is untested. */
+int PNGAPI
+png_reset_zstream(png_structp png_ptr)
+{
+   return (inflateReset(&png_ptr->zstream));
 }
+
+/* This function was added to libpng-1.0.7 */
+png_uint_32 PNGAPI
+png_access_version_number(void)
+{
+   /* Version of *.c files used when building libpng */
+   return((png_uint_32) 10009L);
+}
+
+
+#if 0 /* delay this until version 1.2.0 */
+/* this function was added to libpng 1.0.9 (porting aid to libpng-1.2.0) */
+#ifndef PNG_ASSEMBLER_CODE_SUPPORTED
+int PNGAPI
+png_mmx_support(void)
+{
+    return -1;
+}
+#endif
+#endif /* 0 */

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngget.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngget.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngget.c	Sat Jul 13 21:26:44 2002
@@ -1,17 +1,17 @@
 
 /* pngget.c - retrieval of values from info struct
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  */
 
 #define PNG_INTERNAL
 #include "png.h"
 
-png_uint_32
+png_uint_32 PNGAPI
 png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
 {
    if (png_ptr != NULL && info_ptr != NULL)
@@ -20,7 +20,7 @@
       return(0);
 }
 
-png_uint_32
+png_uint_32 PNGAPI
 png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
@@ -29,9 +29,20 @@
       return(0);
 }
 
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+png_bytepp PNGAPI
+png_get_rows(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->row_pointers);
+   else
+      return(0);
+}
+#endif
+
 #ifdef PNG_EASY_ACCESS_SUPPORTED
 /* easy access to info, added in libpng-0.99 */
-png_uint_32
+png_uint_32 PNGAPI
 png_get_image_width(png_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
@@ -41,7 +52,7 @@
    return (0);
 }
 
-png_uint_32
+png_uint_32 PNGAPI
 png_get_image_height(png_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
@@ -51,7 +62,7 @@
    return (0);
 }
 
-png_byte
+png_byte PNGAPI
 png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
@@ -61,7 +72,7 @@
    return (0);
 }
 
-png_byte
+png_byte PNGAPI
 png_get_color_type(png_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
@@ -71,7 +82,7 @@
    return (0);
 }
 
-png_byte
+png_byte PNGAPI
 png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
@@ -81,7 +92,7 @@
    return (0);
 }
 
-png_byte
+png_byte PNGAPI
 png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
@@ -91,7 +102,7 @@
    return (0);
 }
 
-png_byte
+png_byte PNGAPI
 png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
@@ -101,43 +112,48 @@
    return (0);
 }
 
-png_uint_32
+png_uint_32 PNGAPI
 png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_pHYs)
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter");
       if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
           return (0);
       else return (info_ptr->x_pixels_per_unit);
    }
-   else
+#else
+   return (0);
 #endif
    return (0);
 }
 
-png_uint_32
+png_uint_32 PNGAPI
 png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_pHYs)
    {
-      png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter");
+       png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter");
       if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
           return (0);
       else return (info_ptr->y_pixels_per_unit);
    }
-   else
+#else
+   return (0);
 #endif
    return (0);
 }
 
-png_uint_32
+png_uint_32 PNGAPI
 png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_pHYs)
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter");
       if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
@@ -145,137 +161,150 @@
           return (0);
       else return (info_ptr->x_pixels_per_unit);
    }
-   else
+#else
+   return (0);
 #endif
    return (0);
 }
 
-float
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
 png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
    {
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_pHYs)
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio");
       if (info_ptr->x_pixels_per_unit == 0)
          return ((float)0.0);
       else
-         return ((float)info_ptr->y_pixels_per_unit
-            /(float)info_ptr->x_pixels_per_unit);
+         return ((float)((float)info_ptr->y_pixels_per_unit
+            /(float)info_ptr->x_pixels_per_unit));
    }
-   else
+#else
+   return (0.0);
 #endif
-      return ((float)0.0);
+   return ((float)0.0);
 }
+#endif
 
-png_uint_32
+png_int_32 PNGAPI
 png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_oFFs)
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
       if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
           return (0);
       else return (info_ptr->x_offset);
    }
-   else
+#else
+   return (0);
 #endif
    return (0);
 }
 
-png_uint_32
+png_int_32 PNGAPI
 png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_oFFs)
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
       if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
           return (0);
       else return (info_ptr->y_offset);
    }
-   else
+#else
+   return (0);
 #endif
    return (0);
 }
 
-png_uint_32
+png_int_32 PNGAPI
 png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_oFFs)
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
       if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
           return (0);
       else return (info_ptr->x_offset);
    }
-   else
+#else
+   return (0);
 #endif
    return (0);
 }
 
-png_uint_32
+png_int_32 PNGAPI
 png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
-   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+   if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_oFFs)
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
       if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
           return (0);
       else return (info_ptr->y_offset);
    }
-   else
+#else
+   return (0);
 #endif
    return (0);
 }
 
-#ifdef PNG_INCH_CONVERSIONS
-png_uint_32
+#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
+png_uint_32 PNGAPI
 png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
 {
    return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
-     *.03937 +.5)
+     *.0254 +.5));
 }
 
-png_uint_32
+png_uint_32 PNGAPI
 png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
 {
    return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
-     *.03937 +.5)
+     *.0254 +.5));
 }
 
-png_uint_32
+png_uint_32 PNGAPI
 png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
 {
    return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
-     *.03937 +.5)
+     *.0254 +.5));
 }
 
-float
+float PNGAPI
 png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
 {
    return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
-     *.03937/1000000. +.5)
+     *.00003937);
 }
 
-float
+float PNGAPI
 png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
 {
    return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
-     *.03937/1000000. +.5)
+     *.00003937);
 }
 
 #if defined(PNG_READ_pHYs_SUPPORTED)
-png_uint_32
+png_uint_32 PNGAPI
 png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
 {
    png_uint_32 retval = 0;
 
-   if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs)
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
    {
       png_debug1(1, "in %s retrieval function\n", "pHYs");
       if (res_x != NULL)
@@ -292,23 +321,23 @@
       {
          *unit_type = (int)info_ptr->phys_unit_type;
          retval |= PNG_INFO_pHYs;
-         if(unit_type == 1)
+         if(*unit_type == 1)
          {
-            if (res_x != NULL) *res_x = (png_uint_32)(*res_x * 39.37 + .50);
-            if (res_y != NULL) *res_y = (png_uint_32)(*res_y * 39.37 + .50);
+            if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
+            if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
          }
       }
    }
    return (retval);
 }
 #endif /* PNG_READ_pHYs_SUPPORTED */
-#endif  /* PNG_INCH_CONVERSIONS */
+#endif  /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
 
 /* png_get_channels really belongs in here, too, but it's been around longer */
 
 #endif  /* PNG_EASY_ACCESS_SUPPORTED */
 
-png_byte
+png_byte PNGAPI
 png_get_channels(png_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
@@ -317,7 +346,7 @@
       return (0);
 }
 
-png_bytep
+png_bytep PNGAPI
 png_get_signature(png_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
@@ -327,7 +356,7 @@
 }
 
 #if defined(PNG_READ_bKGD_SUPPORTED)
-png_uint_32
+png_uint_32 PNGAPI
 png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
    png_color_16p *background)
 {
@@ -343,7 +372,8 @@
 #endif
 
 #if defined(PNG_READ_cHRM_SUPPORTED)
-png_uint_32
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
 png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
    double *white_x, double *white_y, double *red_x, double *red_y,
    double *green_x, double *green_y, double *blue_x, double *blue_y)
@@ -372,9 +402,42 @@
    return (0);
 }
 #endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
+   png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
+   png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
+   png_fixed_point *blue_x, png_fixed_point *blue_y)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+   {
+      png_debug1(1, "in %s retrieval function\n", "cHRM");
+      if (white_x != NULL)
+         *white_x = info_ptr->int_x_white;
+      if (white_y != NULL)
+         *white_y = info_ptr->int_y_white;
+      if (red_x != NULL)
+         *red_x = info_ptr->int_x_red;
+      if (red_y != NULL)
+         *red_y = info_ptr->int_y_red;
+      if (green_x != NULL)
+         *green_x = info_ptr->int_x_green;
+      if (green_y != NULL)
+         *green_y = info_ptr->int_y_green;
+      if (blue_x != NULL)
+         *blue_x = info_ptr->int_x_blue;
+      if (blue_y != NULL)
+         *blue_y = info_ptr->int_y_blue;
+      return (PNG_INFO_cHRM);
+   }
+   return (0);
+}
+#endif
+#endif
 
 #if defined(PNG_READ_gAMA_SUPPORTED)
-png_uint_32
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
 png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
 {
    if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
@@ -387,9 +450,25 @@
    return (0);
 }
 #endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr,
+    png_fixed_point *int_file_gamma)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+      && int_file_gamma != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "gAMA");
+      *int_file_gamma = info_ptr->int_gamma;
+      return (PNG_INFO_gAMA);
+   }
+   return (0);
+}
+#endif
+#endif
 
 #if defined(PNG_READ_sRGB_SUPPORTED)
-png_uint_32
+png_uint_32 PNGAPI
 png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
 {
    if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
@@ -403,8 +482,41 @@
 }
 #endif
 
+#if defined(PNG_READ_iCCP_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
+             png_charpp name, int *compression_type,
+             png_charpp profile, png_uint_32 *proflen)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
+      && name != NULL && profile != NULL && proflen != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "iCCP");
+      *name = info_ptr->iccp_name;
+      *profile = info_ptr->iccp_profile;
+      /* compression_type is a dummy so the API won't have to change
+         if we introduce multiple compression types later. */
+      *proflen = (int)info_ptr->iccp_proflen;
+      *compression_type = (int)info_ptr->iccp_compression;
+      return (PNG_INFO_iCCP);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_READ_sPLT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_sPLT(png_structp png_ptr, png_infop info_ptr,
+             png_sPLT_tpp spalettes)
+{
+   if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
+     *spalettes = info_ptr->splt_palettes;
+   return ((png_uint_32)info_ptr->splt_palettes_num);
+}
+#endif
+
 #if defined(PNG_READ_hIST_SUPPORTED)
-png_uint_32
+png_uint_32 PNGAPI
 png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
 {
    if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
@@ -418,7 +530,7 @@
 }
 #endif
 
-png_uint_32
+png_uint_32 PNGAPI
 png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
    png_uint_32 *width, png_uint_32 *height, int *bit_depth,
    int *color_type, int *interlace_type, int *compression_type,
@@ -454,7 +566,7 @@
          channels++;
       pixel_depth = *bit_depth * channels;
       rowbytes_per_pixel = (pixel_depth + 7) >> 3;
-      if ((*width > (png_uint_32)2147483647L/rowbytes_per_pixel))
+      if ((*width > PNG_MAX_UINT/rowbytes_per_pixel))
       {
          png_warning(png_ptr,
             "Width too large for libpng to process image data.");
@@ -465,9 +577,9 @@
 }
 
 #if defined(PNG_READ_oFFs_SUPPORTED)
-png_uint_32
+png_uint_32 PNGAPI
 png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
-   png_uint_32 *offset_x, png_uint_32 *offset_y, int *unit_type)
+   png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
 {
    if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
       && offset_x != NULL && offset_y != NULL && unit_type != NULL)
@@ -483,13 +595,13 @@
 #endif
 
 #if defined(PNG_READ_pCAL_SUPPORTED)
-png_uint_32
+png_uint_32 PNGAPI
 png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
    png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
    png_charp *units, png_charpp *params)
 {
-   if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_pCAL &&
-      purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
+      && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
       nparams != NULL && units != NULL && params != NULL)
    {
       png_debug1(1, "in %s retrieval function\n", "pCAL");
@@ -506,14 +618,51 @@
 }
 #endif
 
+#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
+             int *unit, double *width, double *height)
+{
+    if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_sCAL))
+    {
+        *unit = info_ptr->scal_unit;
+        *width = info_ptr->scal_pixel_width;
+        *height = info_ptr->scal_pixel_height;
+        return (PNG_INFO_sCAL);
+    }
+    return(0);
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr,
+             int *unit, png_charpp width, png_charpp height)
+{
+    if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_sCAL))
+    {
+        *unit = info_ptr->scal_unit;
+        *width = info_ptr->scal_s_width;
+        *height = info_ptr->scal_s_height;
+        return (PNG_INFO_sCAL);
+    }
+    return(0);
+}
+#endif
+#endif
+#endif
+
 #if defined(PNG_READ_pHYs_SUPPORTED)
-png_uint_32
+png_uint_32 PNGAPI
 png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
 {
    png_uint_32 retval = 0;
 
-   if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs)
+   if (png_ptr != NULL && info_ptr != NULL &&
+      (info_ptr->valid & PNG_INFO_pHYs))
    {
       png_debug1(1, "in %s retrieval function\n", "pHYs");
       if (res_x != NULL)
@@ -536,12 +685,12 @@
 }
 #endif
 
-png_uint_32
+png_uint_32 PNGAPI
 png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
    int *num_palette)
 {
-   if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_PLTE &&
-       palette != NULL)
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
+       && palette != NULL)
    {
       png_debug1(1, "in %s retrieval function\n", "PLTE");
       *palette = info_ptr->palette;
@@ -553,11 +702,11 @@
 }
 
 #if defined(PNG_READ_sBIT_SUPPORTED)
-png_uint_32
+png_uint_32 PNGAPI
 png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
 {
-   if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_sBIT &&
-       sig_bit != NULL)
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
+      && sig_bit != NULL)
    {
       png_debug1(1, "in %s retrieval function\n", "sBIT");
       *sig_bit = &(info_ptr->sig_bit);
@@ -567,8 +716,8 @@
 }
 #endif
 
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
-png_uint_32
+#if defined(PNG_READ_TEXT_SUPPORTED)
+png_uint_32 PNGAPI
 png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
    int *num_text)
 {
@@ -583,16 +732,18 @@
          *num_text = info_ptr->num_text;
       return ((png_uint_32)info_ptr->num_text);
    }
+   if (num_text != NULL)
+     *num_text = 0;
    return(0);
 }
 #endif
 
 #if defined(PNG_READ_tIME_SUPPORTED)
-png_uint_32
+png_uint_32 PNGAPI
 png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
 {
-   if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_tIME &&
-       mod_time != NULL)
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
+       && mod_time != NULL)
    {
       png_debug1(1, "in %s retrieval function\n", "tIME");
       *mod_time = &(info_ptr->mod_time);
@@ -603,12 +754,12 @@
 #endif
 
 #if defined(PNG_READ_tRNS_SUPPORTED)
-png_uint_32
+png_uint_32 PNGAPI
 png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
    png_bytep *trans, int *num_trans, png_color_16p *trans_values)
 {
    png_uint_32 retval = 0;
-   if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
    {
       png_debug1(1, "in %s retrieval function\n", "tRNS");
       if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
@@ -641,10 +792,37 @@
 }
 #endif
 
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
+             png_unknown_chunkpp unknowns)
+{
+   if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
+     *unknowns = info_ptr->unknown_chunks;
+   return ((png_uint_32)info_ptr->unknown_chunks_num);
+}
+#endif
+
 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-png_byte
+png_byte PNGAPI
 png_get_rgb_to_gray_status (png_structp png_ptr)
 {
-   return png_ptr->rgb_to_gray_status;
+   return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0);
+}
+#endif
+
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+png_voidp PNGAPI
+png_get_user_chunk_ptr(png_structp png_ptr)
+{
+   return (png_ptr? png_ptr->user_chunk_ptr : NULL);
 }
 #endif
+
+
+png_uint_32 PNGAPI
+png_get_compression_buffer_size(png_structp png_ptr)
+{
+   return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L);
+}
+

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/INSTALL
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/INSTALL	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/INSTALL	Sat Jul 13 21:26:45 2002
@@ -1,5 +1,5 @@
 
-Installing libpng version 1.0.3 - January 14, 1999
+Installing libpng version 1.0.9 - January 31, 2001
 
 Before installing libpng, you must first install zlib.  zlib
 can usually be found wherever you got libpng.  zlib can be
@@ -10,7 +10,7 @@
 version of zlib that's installed.
 
 You can rename the directories that you downloaded (they
-might be called "libpng-1.0.3" or "lpng103" and "zlib-1.1.3"
+might be called "libpng-1.0.9" or "lpng109" and "zlib-1.1.3"
 or "zlib113") so that you have directories called "zlib" and "libpng".
 
 Your directory structure should look like this:
@@ -21,6 +21,16 @@
           README
           *.h
           *.c
+          contrib
+             gregbook
+             msvctest
+             pngminus
+             pngsuite
+             visupng
+          projects
+             borland
+             msvc
+             wince
           scripts
              makefile.*
           pngtest.png
@@ -32,44 +42,72 @@
           contrib
           etc.
 
-First enter the zlib directory and follow the instructions
-in zlib/README.  Then come back here and choose the
-appropriate makefile.sys in the scripts directory.
+If the line endings in the files look funny, you may wish to get the other
+distribution of libpng.  It is available in both tar.gz (UNIX style line
+endings) and zip (DOS style line endings) formats.
+
+If you are building libpng with MSVC, you can enter the libpng\msvc directory
+and follow the instructions in msvc\README.txt.  You can build libpng for
+WindowsCE by entering the libpng\wince directory and following the
+instructions in the README* files.
+
+Else enter the zlib directory and follow the instructions in zlib/README,
+then come back here and choose the appropriate makefile.sys in the scripts
+directory.
+
 The files that are presently available in the scripts directory
 include
 
-      descrip.mms   =>  VMS makefile for MMS or MMK
-      makefile.std  =>  Generic UNIX makefile
-      makefile.knr  =>  Archaic UNIX Makefile that converts files with ansi2knr
-      makefile.dec  =>  DEC Alpha UNIX makefile
-      makefile.hux  =>  HPUX (10.20 and 11.00) makefile
-      makefile.sgi  =>  Silicon Graphics IRIX makefile
-      makefile.sun  =>  Sun makefile
-      makefile.s2x  =>  Solaris 2.X makefile (gcc, creates libpng.so.2.1.0)
-      makefile.lnx  =>  Linux/ELF makefile (gcc, creates libpng.so.2.1.0)
-      makefile.mip  =>  MIPS makefile
-      makefile.aco  =>  Acorn makefile
-      makefile.ama  =>  Amiga makefile
-      smakefile.ppc =>  AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
-                        (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
-      makefile.atr  =>  Atari makefile
-      makefile.bor  =>  Borland makefile
-      build.bat     =>  MS-DOS batch file for Borland compiler
-      makefile.dj2  =>  DJGPP 2 makefile
-      makefile.msc  =>  Microsoft C makefile
-      makefile.w32  =>  makefile for Microsoft Visual C++ 4.0 and later
-      makefile.tc3  =>  Turbo C 3.0 makefile
-      makefile.os2  =>  OS/2 Makefile (gcc and emx, requires pngos2.def)
-      pngos2.def    =>  OS/2 module definition file used by makefile.os2
-      makefile.wat  =>  Watcom 10a+ Makefile, 32-bit flat memory model
-      makevms.com   =>  VMS build script
-      pngdll.mak    =>  To make a png32bd.dll with Borland C++ 4.5
-      pngdef.pas    =>  Defines for a png32bd.dll with Borland C++ 4.5
+ makefile.std      =>  Generic UNIX makefile (cc, creates static libpng.a)
+ makefile.linux    =>  Linux/ELF makefile (gcc, creates libpng.so.2.1.0.9)
+ makefile.gcmmx    =>  Linux/ELF makefile (gcc, creates libpng.so.2.1.0.9,
+                       uses assembler code tuned for Intel MMX platform)
+ makefile.gcc      =>  Generic makefile (gcc, creates static libpng.a)
+ makefile.knr      =>  Archaic UNIX Makefile that converts files with
+                       ansi2knr (Requires ansi2knr.c from
+                       ftp://ftp.cs.wisc.edu/ghost)
+ makefile.aix      =>  AIX makefile
+ makefile.cygwin   =>  Cygwin/gcc makefile
+ makefile.dec      =>  DEC Alpha UNIX makefile
+ makefile.hpux     =>  HPUX (10.20 and 11.00) makefile
+ makefile.ibmc     =>  IBM C/C++ version 3.x for Win32 and OS/2 (static)
+ makefile.intel    =>  Intel C/C++ version 4.0 and later
+ libpng.icc        =>  Project file for IBM VisualAge/C++ version 4.0 or later
+ makefile.macosx   =>  MACOS X Makefile
+ makefile.sgi      =>  Silicon Graphics IRIX makefile (cc, creates static lib)
+ makefile.sggcc    =>  Silicon Graphics (gcc, creates libpng.so.2.1.0.9)
+ makefile.sunos    =>  Sun makefile
+ makefile.solaris  =>  Solaris 2.X makefile (gcc, creates libpng.so.2.1.0.9)
+ makefile.sco      =>  For SCO OSr5  ELF and Unixware 7 with Native cc
+ makefile.mips     =>  MIPS makefile
+ makefile.acorn    =>  Acorn makefile
+ makefile.amiga    =>  Amiga makefile
+ smakefile.ppc     =>  AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
+                       (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
+ makefile.atari    =>  Atari makefile
+ makefile.beos     =>  BEOS makefile for X86
+ makefile.bor      =>  Borland makefile (uses bcc)
+ makefile.bc32     =>  32-bit Borland C++ (all modules compiled in C mode)
+ makefile.bd32     =>  To make a png32bd.dll with Borland C++ 4.5
+ makefile.tc3      =>  Turbo C 3.0 makefile
+ makefile.dj2      =>  DJGPP 2 makefile
+ makefile.msc      =>  Microsoft C makefile
+ makefile.vcawin32 =>  makefile for Microsoft Visual C++ 5.0 and later (uses
+                       assembler code tuned for Intel MMX platform)
+ makefile.vcwin32  =>  makefile for Microsoft Visual C++ 4.0 and later (does
+                       not use assembler code)
+ makefile.os2      =>  OS/2 Makefile (gcc and emx, requires pngos2.def)
+ pngos2.def        =>  OS/2 module definition file used by makefile.os2
+ makefile.watcom   =>  Watcom 10a+ Makefile, 32-bit flat memory model
+ makevms.com       =>  VMS build script
+ descrip.mms       =>  VMS makefile for MMS or MMK
+ pngdef.pas        =>  Defines for a png32bd.dll with Borland C++ 4.5
+ SCOPTIONS.ppc     =>  Used with smakefile.ppc
 
 Copy the file (or files) that you need from the
 scripts directory into this directory, for example
 
-   MSDOS example: copy scripts\makefile.msd makefile
+   MSDOS example: copy scripts\makefile.msc makefile
    UNIX example:    cp scripts/makefile.std makefile
 
 Read the makefile to see if you need to change any source or
@@ -81,11 +119,16 @@
 Then just run "make test" which will create the libpng library in
 this directory and run a quick test that reads the "pngtest.png"
 file and writes a "pngout.png" file that should be identical to it.
+Look for "9782 zero samples" in the output of the test.  For more
+confidence, you can run another test by typing "pngtest pngnow.png"
+and looking for "289 zero samples" in the output.  Also, you can
+run "pngtest -m *.png" in the "contrib/pngsuite" directory and compare
+your output with the result shown in contrib/pngsuite/README.
 
 Most of the makefiles will allow you to run "make install" to
 put the library in its final resting place (if you want to
 do that, run "make install" in the zlib directory first if necessary).
 
 Further information can be found in the README and libpng.txt
-files, in the individual makefiles, and in png.h, and the manual
-pages libpng.3 and png.5.
+files, in the individual makefiles, in png.h, in the README files in
+subdirectories of the LIB directory, and the manual pages libpng.3 and png.5.

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/CHANGES
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/CHANGES	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/CHANGES	Sat Jul 13 21:26:45 2002
@@ -123,6 +123,7 @@
      - all chunk handling routines have the same prototypes, so we will
        be able to handle all chunks via a callback mechanism
   try to fix Linux "setjmp" buffer size problems
+  removed png_large_malloc, png_large_free, and png_realloc functions.
 version 0.95 [March, 1997]
   fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never
   fixed bug in PNG file signature compares when start != 0
@@ -259,6 +260,7 @@
   Minor changes to previous minor changes to pngtest.c
   Changed PNG_READ_NOT_FULLY_SUPPORTED to PNG_READ_TRANSFORMS_NOT_SUPPORTED
   and added PNG_PROGRESSIVE_READ_NOT_SUPPORTED macro
+  Added user transform capability
 version 1.00 [March 7, 1998]
   Changed several typedefs in pngrutil.c
   Added makefile.wat (Pawel Mrochen), updated makefile.tc3 (Willem van Schaik)
@@ -377,7 +379,7 @@
   Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and makefile.sco.
   Removed lines after Dynamic Dependencies" in makefile.aco .
   Revised makefile.dec to make a shared library (Jeremie Petit).
-  Removed trailing blanks from all files. 
+  Removed trailing blanks from all files.
 version 1.0.2a [January 6, 1999]
   Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h
   Added "if" tests to silence complaints about unused png_ptr in png.h and png.c
@@ -386,4 +388,513 @@
     which is obsolete.
 version 1.0.3 [January 14, 1999]
   Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice)
-  Added a statement of Y2K compliance in png.h, libpng.1, and Y2KINFO.
+  Added a statement of Y2K compliance in png.h, libpng.3, and Y2KINFO.
+version 1.0.3a [August 12, 1999]
+  Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning
+     if an attempt is made to read an interlaced image when it's not supported.
+  Added check if png_ptr->trans is defined before freeing it in pngread.c
+  Modified the Y2K statement to include versions back to version 0.71
+  Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c
+  Modified makefile.wat (added -zp8 flag, ".symbolic", changed some comments)
+  Replaced leading blanks with tab characters in makefile.hux
+  Changed "dworkin.wustl.edu" to "ccrc.wustl.edu" in various documents.
+  Changed (float)red and (float)green to (double)red, (double)green
+     in png_set_rgb_to_gray() to avoid "promotion" problems in AIX.
+  Fixed a bug in pngconf.h that omitted <stdio.h> when PNG_DEBUG==0 (K Bracey).
+  Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt).
+  Updated documentation to refer to the PNG-1.2 specification.
+  Removed ansi2knr.c and left pointers to the latest source for ansi2knr.c
+    in makefile.knr, INSTALL, and README (L. Peter Deutsch)
+  Fixed bugs in calculation of the length of rowbytes when adding alpha
+    channels to 16-bit images, in pngrtran.c (Chris Nokleberg)
+  Added function png_set_user_transform_info() to store user_transform_ptr,
+    user_depth, and user_channels into the png_struct, and a function
+    png_get_user_transform_ptr() to retrieve the pointer (Chris Nokleberg)
+  Added function png_set_empty_plte_permitted() to make libpng useable
+    in MNG applications.
+  Corrected the typedef for png_free_ptr in png.h (Jesse Jones).
+  Correct gamma with srgb is 45455 instead of 45000 in pngrutil.c, to be
+    consistent with PNG-1.2, and allow variance of 500 before complaining.
+  Added assembler code contributed by Intel in file pngvcrd.c and modified
+    makefile.w32 to use it (Nirav Chhatrapati, INTEL Corporation, Gilles Vollant)
+  Changed "ln -s -f" to "ln -f -s" in the makefiles to make Solaris happy.
+  Added some aliases for png_set_expand() in pngrtran.c, namely
+    png_set_expand_PLTE(), png_set_expand_depth(), and png_set_expand_tRNS()
+    (Greg Roelofs, in "PNG: The Definitive Guide").
+  Added makefile.beo for BEOS on X86, contributed by Sander Stok.
+version 1.0.3b [August 26, 1999]
+  Replaced 2147483647L several places with PNG_MAX_UINT macro, defined in png.h
+  Changed leading blanks to tabs in all makefiles.
+  Define PNG_USE_PNGVCRD in makefile.w32, to get MMX assembler code.
+  Made alternate versions of  png_set_expand() in pngrtran.c, namely
+    png_set_gray_1_2_4_to_8, png_set_palette_to_rgb, and png_set_tRNS_to_alpha
+    (Greg Roelofs, in "PNG: The Definitive Guide").  Deleted the 1.0.3a aliases.
+  Relocated start of 'extern "C"' block in png.h so it doesn't include pngconf.h
+  Revised calculation of num_blocks in pngmem.c to avoid a potentially
+    negative shift distance, whose results are undefined in the C language.
+  Added a check in pngset.c to prevent writing multiple tIME chunks.
+  Added a check in pngwrite.c to detect invalid small window_bits sizes.
+version 1.0.3d [September 4, 1999]
+  Fixed type casting of igamma in pngrutil.c
+  Added new png_expand functions to scripts/pngdef.pas and pngos2.def
+  Added a demo read_user_transform_fn that examines the row filters in pngtest.c
+version 1.0.4 [September 24, 1999]
+  Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined
+  Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h
+  Made several minor corrections to pngtest.c
+  Renamed the makefiles with longer but more user friendly extensions.
+  Copied the PNG copyright and license to a separate LICENSE file.
+  Revised documentation, png.h, and example.c to remove reference to
+    "viewing_gamma" which no longer appears in the PNG specification.
+  Revised pngvcrd.c to use MMX code for interlacing only on the final pass.
+  Updated pngvcrd.c to use the faster C filter algorithms from libpng-1.0.1a
+  Split makefile.win32vc into two versions, makefile.vcawin32 (uses MMX
+    assembler code) and makefile.vcwin32 (doesn't).
+  Added a CPU timing report to pngtest.c (enabled by defining PNGTEST_TIMING)
+  Added a copy of pngnow.png to the distribution.
+version 1.0.4a [September 25, 1999]
+  Increase max_pixel_depth in pngrutil.c if a user transform needs it.
+  Changed several division operations to right-shifts in pngvcrd.c
+version 1.0.4b [September 30, 1999]
+  Added parentheses in line 3732 of pngvcrd.c
+  Added a comment in makefile.linux warning about buggy -O3 in pgcc 2.95.1
+version 1.0.4c [October 1, 1999]
+  Added a "png_check_version" function in png.c and pngtest.c that will generate
+    a helpful compiler error if an old png.h is found in the search path.
+  Changed type of png_user_transform_depth|channels from int to png_byte.
+version 1.0.4d [October 6, 1999]
+  Changed 0.45 to 0.45455 in png_set_sRGB()
+  Removed unused PLTE entries from pngnow.png
+  Re-enabled some parts of pngvcrd.c (png_combine_row) that work properly.
+version 1.0.4e [October 10, 1999]
+  Fixed sign error in pngvcrd.c (Greg Roelofs)
+  Replaced some instances of memcpy with simple assignments in pngvcrd (GR-P)
+version 1.0.4f [October 15, 1999]
+  Surrounded example.c code with #if 0 .. #endif to prevent people from
+    inadvertently trying to compile it.
+  Changed png_get_header_version() from a function to a macro in png.h
+  Added type casting mostly in pngrtran.c and pngwtran.c
+  Removed some pointless "ptr = NULL" in pngmem.c
+  Added a "contrib" directory containing the source code from Greg's book.
+version 1.0.5 [October 15, 1999]
+  Minor editing of the INSTALL and README files.
+version 1.0.5a [October 23, 1999]
+  Added contrib/pngsuite and contrib/pngminus (Willem van Schaik)
+  Fixed a typo in the png_set_sRGB() function call in example.c (Jan Nijtmans)
+  Further optimization and bugfix of pngvcrd.c
+  Revised pngset.c so that it does not allocate or free memory in the user's
+    text_ptr structure.  Instead, it makes its own copy.
+  Created separate write_end_info_struct in pngtest.c for a more severe test.
+  Added code in pngwrite.c to free info_ptr->text[i].key to stop a memory leak.
+version 1.0.5b [November 23, 1999]
+  Moved PNG_FLAG_HAVE_CHUNK_HEADER, PNG_FLAG_BACKGROUND_IS_GRAY and
+    PNG_FLAG_WROTE_tIME from flags to mode.
+  Added png_write_info_before_PLTE() function.
+  Fixed some typecasting in contrib/gregbook/*.c
+  Updated scripts/makevms.com and added makevms.com to contrib/gregbook
+    and contrib/pngminus (Martin Zinser)
+version 1.0.5c [November 26, 1999]
+  Moved png_get_header_version from png.h to png.c, to accomodate ansi2knr.
+  Removed all global arrays (according to PNG_NO_GLOBAL_ARRAYS macro), to
+    accomodate making DLL's: Moved usr_png_ver from global variable to function
+    png_get_header_ver() in png.c.  Moved png_sig to png_sig_bytes in png.c and
+    eliminated use of png_sig in pngwutil.c.  Moved the various png_CHNK arrays
+    into pngtypes.h.  Eliminated use of global png_pass arrays.  Declared the
+    png_CHNK and png_pass arrays to be "const".  Made the global arrays
+    available to applications (although none are used in libpng itself) when
+    PNG_NO_GLOBAL_ARRAYS is not defined or when PNG_GLOBAL_ARRAYS is defined.
+  Removed some extraneous "-I" from contrib/pngminus/makefile.std
+  Changed the PNG_sRGB_INTENT macros in png.h to be consistent with PNG-1.2.
+  Change PNG_SRGB_INTENT to PNG_sRGB_INTENT in libpng.txt and libpng.3
+version 1.0.5d [November 29, 1999]
+  Add type cast (png_const_charp) two places in png.c
+  Eliminated pngtypes.h; use macros instead to declare PNG_CHNK arrays.
+  Renamed "PNG_GLOBAL_ARRAYS" to "PNG_USE_GLOBAL_ARRAYS" and made available
+    to applications a macro "PNG_USE_LOCAL_ARRAYS".
+  #ifdef out all the new declarations when PNG_USE_GLOBAL_ARRAYS is defined.
+  Added PNG_EXPORT_VAR macro to accommodate making DLL's.
+version 1.0.5e [November 30, 1999]
+  Added iCCP, iTXt, and sPLT support; added "lang" member to the png_text
+    structure; refactored the inflate/deflate support to make adding new chunks
+    with trailing compressed parts easier in the future, and added new functions
+    png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP,
+    png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond).
+  NOTE: Applications that write text chunks MUST define png_text->lang
+    before calling png_set_text(). It must be set to NULL if you want to
+    write tEXt or zTXt chunks.  If you want your application to be able to
+    run with older versions of libpng, use
+
+      #ifdef PNG_iTXt_SUPPORTED
+         png_text[i].lang = NULL;
+      #endif
+
+  Changed png_get_oFFs() and png_set_oFFs() to use signed rather than unsigned
+    offsets (Eric S. Raymond).
+  Combined PNG_READ_cHNK_SUPPORTED and PNG_WRITE_cHNK_SUPPORTED macros into
+    PNG_cHNK_SUPPORTED and combined the three types of PNG_text_SUPPORTED
+    macros, leaving the separate macros also available.
+  Removed comments on #endifs at the end of many short, non-nested #if-blocks.
+version 1.0.5f [December 6, 1999]
+  Changed makefile.solaris to issue a warning about potential problems when
+    the ucb "ld" is in the path ahead of the ccs "ld".
+  Removed "- [date]" from the "synopsis" line in libpng.3 and libpngpf.3.
+  Added sCAL chunk support (Eric S. Raymond).
+version 1.0.5g [December 7, 1999]
+  Fixed "png_free_spallettes" typo in png.h
+  Added code to handle new chunks in pngpread.c
+  Moved PNG_CHNK string macro definitions outside of PNG_NO_EXTERN block
+  Added "translated_key" to png_text structure and png_write_iTXt().
+  Added code in pngwrite.c to work around a newly discovered zlib bug.
+version 1.0.5h [December 10, 1999]
+  NOTE: regarding the note for version 1.0.5e, the following must also
+    be included in your code:
+        png_text[i].translated_key = NULL;
+  Unknown chunk handling is now supported.
+  Option to eliminate all floating point support was added.  Some new
+    fixed-point functions such as png_set_gAMA_fixed() were added.
+  Expanded tabs and removed trailing blanks in source files.
+version 1.0.5i [December 13, 1999]
+  Added some type casts to silence compiler warnings.
+  Renamed "png_free_spalette" to "png_free_spalettes" for consistency.
+  Removed leading blanks from a #define in pngvcrd.c
+  Added some parameters to the new png_set_keep_unknown_chunks() function.
+  Added a test for up->location != 0 in the first instance of writing
+    unknown chunks in pngwrite.c
+  Changed "num" to "i" in png_free_spalettes() and png_free_unknowns() to
+    prevent recursion.
+  Added png_free_hIST() function.
+  Various patches to fix bugs in the sCAL and integer cHRM processing,
+    and to add some convenience macros for use with sCAL.
+version 1.0.5j [December 21, 1999]
+  Changed "unit" parameter of png_write_sCAL from png_byte to int, to work
+    around buggy compilers.
+  Added new type "png_fixed_point" for integers that hold float*100000 values
+  Restored backward compatibility of tEXt/zTXt chunk processing:
+    Restored the first four members of png_text to the same order as v.1.0.5d.
+    Added members "lang_key" and "itxt_length" to png_text struct.  Set
+    text_length=0 when "text" contains iTXt data.  Use the "compression"
+    member to distinguish among tEXt/zTXt/iTXt types.  Added
+    PNG_ITXT_COMPRESSION_NONE (1) and PNG_ITXT_COMPRESSION_zTXt(2) macros.
+    The "Note" above, about backward incompatibility of libpng-1.0.5e, no
+    longer applies.
+  Fixed png_read|write_iTXt() to read|write parameters in the right order,
+    and to write the iTXt chunk after IDAT if it appears in the end_ptr.
+  Added pnggccrd.c, version of pngvcrd.c Intel assembler for gcc (Greg Roelofs)
+  Reversed the order of trying to write floating-point and fixed-point gAMA.
+version 1.0.5k [December 27, 1999]
+  Added many parentheses, e.g., "if (a && b & c)" becomes "if (a && (b & c))"
+  Added png_handle_as_unknown() function (Glenn)
+  Added png_free_chunk_list() function and chunk_list and num_chunk_list members
+    of png_ptr.
+  Eliminated erroneous warnings about multiple sPLT chunks and sPLT-after-PLTE.
+  Fixed a libpng-1.0.5h bug in pngrutil.c that was issuing erroneous warnings
+    about ignoring incorrect gAMA with sRGB (gAMA was in fact not ignored)
+  Added png_free_tRNS(); png_set_tRNS() now malloc's its own trans array (ESR).
+  Define png_get_int_32 when oFFs chunk is supported as well as when pCAL is.
+  Changed type of proflen from png_int_32 to png_uint_32 in png_get_iCCP().
+version 1.0.5l [January 1, 2000]
+  Added functions png_set_read_user_chunk_fn() and png_get_user_chunk_ptr()
+    for setting a callback function to handle unknown chunks and for
+    retrieving the associated user pointer (Glenn).
+version 1.0.5m [January 7, 2000]
+  Added high-level functions png_read_png(), png_write_png(), png_free_pixels().
+version 1.0.5n [January 9, 2000]
+  Added png_free_PLTE() function, and modified png_set_PLTE() to malloc its
+    own memory for info_ptr->palette.  This makes it safe for the calling
+    application to free its copy of the palette any time after it calls
+    png_set_PLTE().
+version 1.0.5o [January 20, 2000]
+  Cosmetic changes only (removed some trailing blanks and TABs)
+version 1.0.5p [January 31, 2000]
+  Renamed pngdll.mak to makefile.bd32
+  Cosmetic changes in pngtest.c
+version 1.0.5q [February 5, 2000]
+  Relocated the makefile.solaris warning about PATH problems.
+  Fixed pngvcrd.c bug by pushing/popping registers in mmxsupport (Bruce Oberg)
+  Revised makefile.gcmmx
+  Added PNG_SETJMP_SUPPORTED, PNG_SETJMP_NOT_SUPPORTED, and PNG_ABORT() macros
+version 1.0.5r [February 7, 2000]
+  Removed superfluous prototype for png_get_itxt from png.h
+  Fixed a bug in pngrtran.c that improperly expanded the background color.
+  Return *num_text=0 from png_get_text() when appropriate, and fix documentation
+    of png_get_text() in libpng.txt/libpng.3.
+version 1.0.5s [February 18, 2000]
+  Added "png_jmp_env()" macro to pngconf.h, to help people migrate to the
+    new error handler that's planned for the next libpng release, and changed
+    example.c, pngtest.c, and contrib programs to use this macro.
+  Revised some of the DLL-export macros in pngconf.h (Greg Roelofs)
+  Fixed a bug in png_read_png() that caused it to fail to expand some images
+    that it should have expanded.
+  Fixed some mistakes in the unused and undocumented INCH_CONVERSIONS functions
+    in pngget.c
+  Changed the allocation of palette, history, and trans arrays back to
+    the version 1.0.5 method (linking instead of copying) which restores
+    backward compatibility with version 1.0.5.  Added some remarks about
+    that in example.c.  Added "free_me" member to info_ptr and png_ptr
+    and added png_free_data() function.
+  Updated makefile.linux and makefile.gccmmx to make directories conditionally.
+  Made cosmetic changes to pngasmrd.h
+  Added png_set_rows() and png_get_rows(), for use with png_read|write_png().
+  Modified png_read_png() to allocate info_ptr->row_pointers only if it
+    hasn't already been allocated.
+version 1.0.5t [March 4, 2000]
+  Changed png_jmp_env() migration aiding macro to png_jmpbuf().
+  Fixed "interlace" typo (should be "interlaced") in contrib/gregbook/read2-x.c
+  Fixed bug with use of PNG_BEFORE_IHDR bit in png_ptr->mode, introduced when
+    PNG_FLAG_HAVE_CHUNK_HEADER was moved into png_ptr->mode in version 1.0.5b
+  Files in contrib/gregbook were revised to use png_jmpbuf() and to select
+    a 24-bit visual if one is available, and to allow abbreviated options.
+  Files in contrib/pngminus were revised to use the png_jmpbuf() macro.
+  Removed spaces in makefile.linux and makefile.gcmmx, introduced in 1.0.5s
+version 1.0.5u [March 5, 2000]
+  Simplified the code that detects old png.h in png.c and pngtest.c
+  Renamed png_spalette (_p, _pp) to png_sPLT_t (_tp, _tpp)
+  Increased precision of rgb_to_gray calculations from 8 to 15 bits and
+    added png_set_rgb_to_gray_fixed() function.
+  Added makefile.bc32 (32-bit Borland C++, C mode)
+version 1.0.5v [March 11, 2000]
+  Added some parentheses to the png_jmpbuf macro definition.
+  Updated references to the zlib home page, which has moved to freesoftware.com.
+  Corrected bugs in documentation regarding png_read_row() and png_write_row().
+  Updated documentation of png_rgb_to_gray calculations in libpng.3/libpng.txt.
+  Renamed makefile.borland,turboc3 back to makefile.bor,tc3 as in version 1.0.3,
+    revised borland makefiles; added makefile.ibmvac3 and makefile.gcc (Cosmin)
+version 1.0.6 [March 20, 2000]
+  Minor revisions of makefile.bor, libpng.txt, and gregbook/rpng2-win.c
+  Added makefile.sggcc (SGI IRIX with gcc)
+version 1.0.6d [April 7, 2000]
+  Changed sprintf() to strcpy() in png_write_sCAL_s() to work without STDIO
+  Added data_length parameter to png_decompress_chunk() function
+  Revised documentation to remove reference to abandoned png_free_chnk functions
+  Fixed an error in png_rgb_to_gray_fixed()
+  Revised example.c, usage of png_destroy_write_struct().
+  Renamed makefile.ibmvac3 to makefile.ibmc, added libpng.icc IBM project file
+  Added a check for info_ptr->free_me&PNG_FREE_TEXT when freeing text in png.c
+  Simplify png_sig_bytes() function to remove use of non-ISO-C strdup().
+version 1.0.6e [April 9, 2000]
+  Added png_data_freer() function.
+  In the code that checks for over-length tRNS chunks, added check of
+    info_ptr->num_trans as well as png_ptr->num_trans (Matthias Benckmann)
+  Minor revisions of libpng.txt/libpng.3.
+  Check for existing data and free it if the free_me flag is set, in png_set_*()
+    and png_handle_*().
+  Only define PNG_WEIGHTED_FILTERS_SUPPORTED when PNG_FLOATING_POINT_SUPPORTED
+    is defined.
+  Changed several instances of PNG_NO_CONSOLE_ID to PNG_NO_STDIO in pngrutil.c
+    and mentioned the purposes of the two macros in libpng.txt/libpng.3.
+version 1.0.6f [April 14, 2000]
+  Revised png_set_iCCP() and png_set_rows() to avoid prematurely freeing data.
+  Add checks in png_set_text() for NULL members of the input text structure.
+  Revised libpng.txt/libpng.3.
+  Removed superfluous prototype for png_set_itxt from png.h
+  Removed "else" from pngread.c, after png_error(), and changed "0" to "length".
+  Changed several png_errors about malformed ancillary chunks to png_warnings.
+version 1.0.6g [April 24, 2000]
+  Added png_pass-* arrays to pnggccrd.c when PNG_USE_LOCAL_ARRAYS is defined.
+  Relocated paragraph about png_set_background() in libpng.3/libpng.txt
+    and other revisions (Matthias Benckmann)
+  Relocated info_ptr->free_me, png_ptr->free_me, and other info_ptr and
+    png_ptr members to restore binary compatibility with libpng-1.0.5
+    (breaks compatibility with libpng-1.0.6).
+version 1.0.6h [April 24, 2000]
+  Changed shared library so-number pattern from 2.x.y.z to xy.z (this builds
+    libpng.so.10 & libpng.so.10.6h instead of libpng.so.2 & libpng.so.2.1.0.6h)
+    This is a temporary change for test purposes.
+version 1.0.6i [May 2, 2000]
+  Rearranged some members at the end of png_info and png_struct, to put
+    unknown_chunks_num and free_me within the original size of the png_structs
+    and free_me, png_read_user_fn, and png_free_fn within the original png_info,
+    because some old applications allocate the structs directly instead of
+    using png_create_*().
+  Added documentation of user memory functions in libpng.txt/libpng.3
+  Modified png_read_png so that it will use user_allocated row_pointers
+    if present, unless free_me directs that it be freed, and added description
+    of the use of png_set_rows() and png_get_rows() in libpng.txt/libpng.3.
+  Added PNG_LEGACY_SUPPORTED macro, and #ifdef out all new (since version
+    1.00) members of png_struct and png_info, to regain binary compatibility
+    when you define this macro.  Capabilities lost in this event
+    are user transforms (new in version 1.0.0),the user transform pointer
+    (new in version 1.0.2), rgb_to_gray (new in 1.0.5), iCCP, sCAL, sPLT,
+    the high-level interface, and unknown chunks support (all new in 1.0.6).
+    This was necessary because of old applications that allocate the structs
+    directly as authors were instructed to do in libpng-0.88 and earlier,
+    instead of using png_create_*().
+  Added modes PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT which
+    can be used to detect codes that directly allocate the structs, and
+    code to check these modes in png_read_init() and png_write_init() and
+    generate a libpng error if the modes aren't set and PNG_LEGACY_SUPPORTED
+    was not defined.
+  Added makefile.intel and updated makefile.watcom (Pawel Mrochen)
+version 1.0.6j [May 3, 2000]
+  Overloaded png_read_init() and png_write_init() with macros that convert
+    calls to png_read_init_2() or png_write_init_2() that check the version
+    and structure sizes.
+version 1.0.7beta11 [May 7, 2000]
+  Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes
+    which are no longer used.
+  Eliminated the three new members of png_text when PNG_NO_iTXt_SUPPORTED
+    or PNG_LEGACY_SUPPORTED is defined.
+  Made PNG_NO_ITXT_SUPPORTED the default setting, to avoid memory overrun
+    when old applications fill the info_ptr->text structure directly.
+  Added PNGAPI macro, and added it to the definitions of all exported functions.
+  Relocated version macro definitions ahead of the includes of zlib.h and
+    pngconf.h in png.h.
+version 1.0.7beta12 [May 12, 2000]
+  Revised pngset.c to avoid a problem with expanding the png_debug macro.
+  Deleted some extraneous defines from pngconf.h
+  Made PNG_NO_CONSOLE_IO the default condition when PNG_BUILD_DLL is defined.
+  Use MSC _RPTn debugging instead of fprintf if _MSC_VER is defined.
+  Added png_access_version_number() function.
+  Check for mask&PNG_FREE_CHNK (for TEXT, SCAL, PCAL) in png_free_data().
+  Expanded libpng.3/libpng.txt information about png_data_freer().
+version 1.0.7beta14 [May 17, 2000] (beta13 was not published)
+  Changed pnggccrd.c and pngvcrd.c to handle bad adaptive filter types as
+    warnings instead of errors, as pngrutil.c does.
+  Set the PNG_INFO_IDAT valid flag in png_set_rows() so png_write_png()
+    will actually write IDATs.
+  Made the default PNG_USE_LOCAL_ARRAYS depend on PNG_DLL instead of WIN32.
+  Make png_free_data() ignore its final parameter except when freeing data
+    that can have multiple instances (text, sPLT, unknowns).
+  Fixed a new bug in png_set_rows().
+  Removed info_ptr->valid tests from png_free_data(), as in version 1.0.5.
+  Added png_set_invalid() function.
+  Fixed incorrect illustrations of png_destroy_write_struct() in example.c.
+version 1.0.7beta15 [May 30, 2000]
+  Revised the deliberately erroneous Linux setjmp code in pngconf.h to produce
+    fewer error messages.
+  Rearranged checks for Z_OK to check the most likely path first in pngpread.c
+    and pngwutil.c.
+  Added checks in pngtest.c for png_create_*() returning NULL, and mentioned
+    in libpng.txt/libpng.3 the need for applications to check this.
+  Changed names of png_default_*() functions in pngtest to pngtest_*().
+  Changed return type of png_get_x|y_offset_*() from png_uint_32 to png_int_32.
+  Fixed some bugs in the unused PNG_INCH_CONVERSIONS functions in pngget.c
+  Set each pointer to NULL after freeing it in png_free_data().
+  Worked around a problem in pngconf.h; AIX's strings.h defines an "index"
+    macro that conflicts with libpng's png_color_16.index. (Dimitri Papadapoulos)
+  Added "msvc" directory with MSVC++ project files (Simon-Pierre Cadieux).
+version 1.0.7beta16 [June 4, 2000]
+  Revised the workaround of AIX string.h "index" bug.
+  Added a check for overlength PLTE chunk in pngrutil.c.
+  Added PNG_NO_POINTER_INDEXING macro to use array-indexing instead of pointer
+    indexing in pngrutil.c and pngwutil.c to accommodate a buggy compiler.
+  Added a warning in png_decompress_chunk() when it runs out of data, e.g.
+    when it tries to read an erroneous PhotoShop iCCP chunk.
+  Added PNG_USE_DLL macro.
+  Revised the copyright/disclaimer/license notice.
+  Added contrib/msvctest directory
+version 1.0.7rc1 [June 9, 2000]
+  Corrected the definition of PNG_TRANSFORM_INVERT_ALPHA  (0x0400 not 0x0200)
+  Added contrib/visupng directory (Willem van Schaik)
+version 1.0.7beta18 [June 23, 2000]
+  Revised PNGAPI definition, and pngvcrd.c to work with __GCC__
+    and do not redefine PNGAPI if it is passed in via a compiler directive.
+  Revised visupng/PngFile.c to remove returns from within the Try block.
+  Removed leading underscores from "_PNG_H" and "_PNG_SAVE_BSD_SOURCE" macros.
+  Updated contrib/visupng/cexcept.h to version 1.0.0.
+  Fixed bugs in pngwrite.c and pngwutil.c that prevented writing iCCP chunks.
+version 1.0.7rc2 [June 28, 2000]
+  Updated license to include disclaimers required by UCITA.
+  Fixed "DJBPP" typo in pnggccrd.c introduced in beta18.
+version 1.0.7 [July 1, 2000]
+  Revised the definition of "trans_values" in libpng.3/libpng.txt
+version 1.0.8beta1 [July 8, 2000]
+  Added png_free(png_ptr, key) two places in pngpread.c to stop memory leaks.
+  Changed PNG_NO_STDIO to PNG_NO_CONSOLE_IO, several places in pngrutil.c and
+     pngwutil.c.
+  Changed PNG_EXPORT_VAR to use PNG_IMPEXP, in pngconf.h.
+  Removed unused "#include <assert.h>" from png.c
+  Added WindowsCE support.
+  Revised pnggccrd.c to work with gcc-2.95.2 and in the Cygwin environment.
+version 1.0.8beta2 [July 10, 2000]
+  Added project files to the wince directory and made further revisions
+     of pngtest.c, pngrio.c, and pngwio.c in support of WindowsCE.
+version 1.0.8beta3 [July 11, 2000]
+  Only set the PNG_FLAG_FREE_TRNS or PNG_FREE_TRNS flag in png_handle_tRNS()
+     for indexed-color input files to avoid potential double-freeing trans array
+     under some unusual conditions; problem was introduced in version 1.0.6f.
+  Further revisions to pngtest.c and files in the wince subdirectory.
+version 1.0.8beta4 [July 14, 2000]
+  Added the files pngbar.png and pngbar.jpg to the distribution.
+  Added makefile.cygwin, and cygwin support in pngconf.h
+  Added PNG_NO_ZALLOC_ZERO macro (makes png_zalloc skip zeroing memory)
+version 1.0.8rc1 [July 16, 2000]
+  Revised png_debug() macros and statements to eliminate compiler warnings.
+version 1.0.8 [July 24, 2000]
+  Added png_flush() in pngwrite.c, after png_write_IEND().
+  Updated makefile.hpux to build a shared library.
+version 1.0.9beta1 [November 10, 2000]
+  Fixed typo in scripts/makefile.hpux
+  Updated makevms.com in scripts and contrib/* and contrib/* (Martin Zinser)
+  Fixed seqence-point bug in contrib/pngminus/png2pnm (Martin Zinser)
+  Changed "cdrom.com" in documentation to "libpng.org"
+  Revised pnggccrd.c to get it all working, and updated makefile.gcmmx (Greg).
+  Changed type of "params" from voidp to png_voidp in png_read|write_png().
+  Make sure PNGAPI and PNG_IMPEXP are defined in pngconf.h.
+  Revised the 3 instances of WRITEFILE in pngtest.c.
+  Relocated "msvc" and "wince" project subdirectories into "dll" subdirectory.
+  Updated png.rc in dll/msvc project
+  Revised makefile.dec to define and use LIBPATH and INCPATH
+  Increased size of global png_libpng_ver[] array from 12 to 18 chars.
+  Made global png_libpng_ver[], png_sig[] and png_pass_*[] arrays const.
+  Removed duplicate png_crc_finish() from png_handle_bKGD() function.
+  Added a warning when application calls png_read_update_info() multiple times.
+  Revised makefile.cygwin
+  Fixed bugs in iCCP support in pngrutil.c and pngwutil.c.
+  Replaced png_set_empty_plte_permitted() with png_permit_mng_features().
+version 1.0.9beta2 [November 19, 2000]
+  Renamed the "dll" subdirectory "projects".
+  Added borland project files to "projects" subdirectory.
+  Set VS_FF_PRERELEASE and VS_FF_PATCHED flags in msvc/png.rc when appropriate.
+  Add error message in png_set_compression_buffer_size() when malloc fails.
+version 1.0.9beta3 [November 23, 2000]
+  Revised PNG_LIBPNG_BUILD_TYPE macro in png.h, used in the msvc project.
+  Removed the png_flush() in pngwrite.c that crashes some applications
+    that don't set png_output_flush_fn.
+  Added makefile.macosx and makefile.aix to scripts directory.
+version 1.0.9beta4 [December 1, 2000]
+  Change png_chunk_warning to png_warning in png_check_keyword().
+  Increased the first part of msg buffer from 16 to 18 in png_chunk_error().
+version 1.0.9beta5 [December 15, 2000]
+  Added support for filter method 64 (for PNG datastreams embedded in MNG).
+version 1.0.9beta6 [December 18, 2000]
+  Revised png_set_filter() to accept filter method 64 when appropriate.
+  Added new PNG_HAVE_PNG_SIGNATURE bit to png_ptr->mode and use it to
+    help prevent applications from using MNG features in PNG datastreams.
+  Added png_permit_mng_features() function.
+  Revised libpng.3/libpng.txt.  Changed "filter type" to "filter method".
+version 1.0.9rc1 [December 23, 2000]
+  Revised test for PNG_HAVE_PNG_SIGNATURE in pngrutil.c
+  Fixed error handling of unknown compression type in png_decompress_chunk().
+  In pngconf.h, define __cdecl when _MSC_VER is defined.
+version 1.0.9beta7 [December 28, 2000]
+  Changed PNG_TEXT_COMPRESSION_zTXt to PNG_COMPRESSION_TYPE_BASE several places.
+  Revised memory management in png_set_hIST and png_handle_hIST in a backward
+    compatible manner.  PLTE and tRNS were revised similarly.
+  Revised the iCCP chunk reader to ignore trailing garbage.
+version 1.0.9beta8 [January 12, 2001]
+  Moved pngasmrd.h into pngconf.h.
+  Improved handling of out-of-spec garbage iCCP chunks generated by PhotoShop.
+version 1.0.9beta9 [January 15, 2001]
+  Added png_set_invalid, png_permit_mng_features, and png_mmx_supported to
+    wince and msvc project module definition files.
+  Minor revision of makefile.cygwin.
+  Fixed bug with progressive reading of narrow interlaced images in pngpread.c
+version 1.0.9beta10 [January 16, 2001]
+  Do not typedef png_FILE_p in pngconf.h when PNG_NO_STDIO is defined.
+  Fixed "png_mmx_supported" typo in project definition files.
+version 1.0.9beta11 [January 19, 2001]
+  Updated makefile.sgi to make shared library.
+  Removed png_mmx_support() function and disabled PNG_MNG_FEATURES_SUPPORTED
+    by default, for the benefit of DLL forward compatibility.  These will
+    be re-enabled in version 1.2.0.
+version 1.0.9rc2 [January 22, 2001]
+  Revised cygwin support.
+version 1.0.9 [January 31, 2001]
+  Added check of cygwin's ALL_STATIC in pngconf.h
+  Added "-nommx" parameter to contrib/gregbook/rpng2-win and rpng2-x demos.
+
+Send comments/corrections/commendations to
+png-implement at ccrc.wustl.edu or to randeg at alum.rpi.edu
+
+Glenn R-P

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/png.h
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/png.h	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/png.h	Sat Jul 13 21:26:46 2002
@@ -1,125 +1,148 @@
 
 /* png.h - header file for PNG reference library
  *
- * libpng version 1.0.3 - January 14, 1999
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * libpng version 1.0.9 - January 31, 2001
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Authors and maintainers:
+ *  libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
+ *  libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
+ *  libpng versions 0.97, January 1998, through 1.0.9 - January 31, 2001: Glenn
+ *  See also "Contributing Authors", below.
  *
- * Y2K compliance in libpng:
- * =========================
- *    
- *    January 13, 1999
- *    
- *    Since the PNG Development group is an ad-hoc body, we can't make
- *    an official declaration.
- *    
- *    This is your unofficial assurance that libpng from version 0.81 and
- *    upward are Y2K compliant.  It is my belief that earlier versions were
- *    also Y2K compliant.
- *    
- *    Libpng only has three year fields.  One is a 2-byte unsigned integer
- *    that will hold years up to 65535.  The other two hold the date in text
- *    format, and will hold years up to 9999.
- *    
- *    The integer is
- *        "png_uint_16 year" in png_time_struct.
- *    
- *    The strings are
- *        "png_charp time_buffer" in png_struct and
- *        "near_time_buffer", which is a local character string in png.c.
- *    
- *    There are seven time-related functions:
- *        png.c: png_convert_to_rfc_1123() in png.c 
- *          (formerly png_convert_to_rfc_1152() in error)
- *        png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
- *        png_convert_from_time_t() in pngwrite.c
- *        png_get_tIME() in pngget.c
- *        png_handle_tIME() in pngrutil.c, called in pngread.c
- *        png_set_tIME() in pngset.c
- *        png_write_tIME() in pngwutil.c, called in pngwrite.c
- *    
- *    All handle dates properly in a Y2K environment.  The 
- *    png_convert_from_time_t() function calls gmtime() to convert from system
- *    clock time, which returns (year - 1900), which we properly convert to
- *    the full 4-digit year.  There is a possibility that applications using
- *    libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
- *    function, or incorrectly passing only a 2-digit year instead of
- *    "year - 1900" into the png_convert_from_struct_tm() function, but this
- *    is not under our control.  The libpng documentation has always stated
- *    that it works with 4-digit years, and the APIs have been documented as
- *    such.
- *    
- *    The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
- *    integer to hold the year, and can hold years as large as 65535.
- *    
- *    
- *       Glenn Randers-Pehrson
- *       libpng maintainer
- *       PNG Development Group
- * 
  * Note about libpng version numbers:
- * 
+ *
  *    Due to various miscommunications, unforeseen code incompatibilities
  *    and occasional factors outside the authors' control, version numbering
  *    on the library has not always been consistent and straightforward.
  *    The following table summarizes matters since version 0.89c, which was
  *    the first widely used release:
  *
- *    source                    png.h    png.h   shared-lib
- *    version                   string     int   version
- *    -------                   ------   -----  ----------
- *    0.89c ("1.0 beta 3")      0.89        89  1.0.89
- *    0.90  ("1.0 beta 4")      0.90        90  0.90  [should have been 2.0.90]
- *    0.95  ("1.0 beta 5")      0.95        95  0.95  [should have been 2.0.95]
- *    0.96  ("1.0 beta 6")      0.96        96  0.96  [should have been 2.0.96]
- *    0.97b ("1.00.97 beta 7")  1.00.97     97  1.0.1 [should have been 2.0.97]
- *    0.97c                     0.97        97  2.0.97
- *    0.98                      0.98        98  2.0.98
- *    0.99                      0.99        98  2.0.99
- *    0.99a-m                   0.99        99  2.0.99
- *    1.00                      1.00       100  2.1.0 [int should be 10000]
- *    1.0.0                     1.0.0      100  2.1.0 [int should be 10000]
- *    1.0.1                     1.0.1    10001  2.1.0
- *    1.0.1a-e                  1.0.1a-e 10002  2.1.0.1a-e
- *    1.0.2                     1.0.2    10002  2.1.0.2
- *    1.0.2a-c                  1.0.2a   10003  2.1.0.2a-c
- *    1.0.3                     1.0.3    10003  2.1.0.3
+ *    source                 png.h  png.h  shared-lib
+ *    version                string   int  version
+ *    -------                ------ -----  ----------
+ *    0.89c "1.0 beta 3"     0.89      89  1.0.89
+ *    0.90  "1.0 beta 4"     0.90      90  0.90  [should have been 2.0.90]
+ *    0.95  "1.0 beta 5"     0.95      95  0.95  [should have been 2.0.95]
+ *    0.96  "1.0 beta 6"     0.96      96  0.96  [should have been 2.0.96]
+ *    0.97b "1.00.97 beta 7" 1.00.97   97  1.0.1 [should have been 2.0.97]
+ *    0.97c                  0.97      97  2.0.97
+ *    0.98                   0.98      98  2.0.98
+ *    0.99                   0.99      98  2.0.99
+ *    0.99a-m                0.99      99  2.0.99
+ *    1.00                   1.00     100  2.1.0 [100 should be 10000]
+ *    1.0.0      (from here on, the   100  2.1.0 [100 should be 10000]
+ *    1.0.1       png.h string is   10001  2.1.0
+ *    1.0.1a-e    identical to the  10002  from here on, the shared library
+ *    1.0.2       source version)   10002  is 2.V where V is the source code
+ *    1.0.2a-b                      10003  version, except as noted.
+ *    1.0.3                         10003
+ *    1.0.3a-d                      10004
+ *    1.0.4                         10004
+ *    1.0.4a-f                      10005
+ *    1.0.5 (+ 2 patches)           10005
+ *    1.0.5a-d                      10006
+ *    1.0.5e-r                      10100 (not source compatible)
+ *    1.0.5s-v                      10006 (not binary compatible)
+ *    1.0.6 (+ 3 patches)           10006 (still binary incompatible)
+ *    1.0.6d-f                      10007 (still binary incompatible)
+ *    1.0.6g                        10007
+ *    1.0.6h                        10007  10.6h (testing xy.z so-numbering)
+ *    1.0.6i                        10007  10.6i
+ *    1.0.6j                        10007  2.1.0.6j (incompatible with 1.0.0)
+ *    1.0.7beta11-14        DLLNUM  10007  2.1.0.7beta11-14 (binary compatible)
+ *    1.0.7beta15-18           1    10007  2.1.0.7beta15-18 (binary compatible)
+ *    1.0.7rc1-2               1    10007  2.1.0.7rc1-2 (binary compatible)
+ *    1.0.7                    1    10007  (still compatible)
+ *    1.0.8beta1-4             1    10008  2.1.0.8beta1-4
+ *    1.0.8rc1                 1    10008  2.1.0.8rc1
+ *    1.0.8                    1    10008  2.1.0.8
+ *    1.0.9beta1-6             1    10009  2.1.0.9beta1-6
+ *    1.0.9rc1                 1    10009  2.1.0.9rc1
+ *    1.0.9beta7-10            1    10009  2.1.0.9beta7-10
+ *    1.0.9rc2                 1    10009  2.1.0.9rc2
+ *    1.0.9                    1    10009  2.1.0.9
  *
- *    Henceforth the source version will match the shared-library minor
- *    and patch numbers; the shared-library major version number will be
+ *    Henceforth the source version will match the shared-library major
+ *    and minor numbers; the shared-library major version number will be
  *    used for changes in backward compatibility, as it is intended.  The
- *    PNG_PNGLIB_VER macro, which is not used within libpng but is available
+ *    PNG_LIBPNG_VER macro, which is not used within libpng but is available
  *    for applications, is an unsigned integer of the form xyyzz corresponding
- *    to the source version x.y.z (leading zeros in y and z).
+ *    to the source version x.y.z (leading zeros in y and z).  Beta versions
+ *    were given the previous public release number plus a letter, until
+ *    version 1.0.6j; from then on they were given the upcoming public
+ *    release number plus "betaNN" or "rcN".
+ *
+ *    Binary incompatibility exists only when applications make direct access
+ *    to the info_ptr or png_ptr members through png.h, and the compiled
+ *    application is loaded with a different version of the library.
+ *
+ *    DLLNUM will change each time there are forward or backward changes
+ *    in binary compatibility (e.g., when a new feature is added).
  *
  * See libpng.txt or libpng.3 for more information.  The PNG specification
  * is available as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/>
  * and as a W3C Recommendation <http://www.w3.org/TR/REC.png.html>
+ */
+
+/*
+ * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+ *
+ * If you modify libpng you may insert additional notices immediately following
+ * this sentence.
+ *
+ * libpng versions 1.0.7, July 1, 2000, through  1.0.9, January 31, 2001, are
+ * Copyright (c) 2000, 2001 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-1.0.6
+ * with the following individuals added to the list of Contributing Authors
+ *
+ *    Simon-Pierre Cadieux
+ *    Eric S. Raymond
+ *    Gilles Vollant
+ *
+ * and with the following additions to the disclaimer:
+ *
+ *    There is no warranty against interference with your enjoyment of the
+ *    library or against infringement.  There is no warranty that our
+ *    efforts or the library will fulfill any of your particular purposes
+ *    or needs.  This library is provided with all faults, and the entire
+ *    risk of satisfactory quality, performance, accuracy, and effort is with
+ *    the user.
+ *
+ * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+ * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson
+ * Distributed according to the same disclaimer and license as libpng-0.96,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ *    Tom Lane
+ *    Glenn Randers-Pehrson
+ *    Willem van Schaik
+ *
+ * libpng versions 0.89, June 1996, through 0.96, May 1997, are
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Distributed according to the same disclaimer and license as libpng-0.88,
+ * with the following individuals added to the list of Contributing Authors:
  *
- * Contributing Authors:
  *    John Bowler
  *    Kevin Bracey
  *    Sam Bushell
- *    Andreas Dilger
  *    Magnus Holmgren
- *    Tom Lane
- *    Dave Martindale
- *    Glenn Randers-Pehrson
  *    Greg Roelofs
- *    Guy Eric Schalnat
- *    Paul Schmidt
  *    Tom Tanner
- *    Willem van Schaik
- *    Tim Wegner
  *
- * The contributing authors would like to thank all those who helped
- * with testing, bug fixes, and patience.  This wouldn't have been
- * possible without all of you.
+ * libpng versions 0.5, May 1995, through 0.88, January 1996, are
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  *
- * Thanks to Frank J. T. Wojcik for helping with the documentation.
+ * For the purposes of this copyright and license, "Contributing Authors"
+ * is defined as the following set of individuals:
  *
- * COPYRIGHT NOTICE:
+ *    Andreas Dilger
+ *    Dave Martindale
+ *    Guy Eric Schalnat
+ *    Paul Schmidt
+ *    Tim Wegner
  *
  * The PNG Reference Library is supplied "AS IS".  The Contributing Authors
  * and Group 42, Inc. disclaim all warranties, expressed or implied,
@@ -132,11 +155,14 @@
  * Permission is hereby granted to use, copy, modify, and distribute this
  * source code, or portions hereof, for any purpose, without fee, subject
  * to the following restrictions:
+ *
  * 1. The origin of this source code must not be misrepresented.
- * 2. Altered versions must be plainly marked as such and must not be
- *    misrepresented as being the original source.
- * 3. This Copyright notice may not be removed or altered from any source or
- *    altered source distribution.
+ *
+ * 2. Altered versions must be plainly marked as such and must not
+ *    be misrepresented as being the original source.
+ *
+ * 3. This Copyright notice may not be removed or altered from any
+ *    source or altered source distribution.
  *
  * The Contributing Authors and Group 42, Inc. specifically permit, without
  * fee, and encourage the use of this source code as a component to
@@ -145,13 +171,87 @@
  * appreciated.
  */
 
+/*
+ * A "png_get_copyright" function is available, for convenient use in "about"
+ * boxes and the like:
+ *
+ * printf("%s",png_get_copyright(NULL));
+ *
+ * Also, the PNG logo (in PNG format, of course) is supplied in the
+ * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+ */
 
-#ifndef _PNG_H
-#define _PNG_H
+/*
+ * Libpng is OSI Certified Open Source Software.  OSI Certified is a
+ * certification mark of the Open Source Initiative.
+ */
 
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
+/*
+ * The contributing authors would like to thank all those who helped
+ * with testing, bug fixes, and patience.  This wouldn't have been
+ * possible without all of you.
+ *
+ * Thanks to Frank J. T. Wojcik for helping with the documentation.
+ */
+
+/*
+ * Y2K compliance in libpng:
+ * =========================
+ *
+ *    January 31, 2001
+ *
+ *    Since the PNG Development group is an ad-hoc body, we can't make
+ *    an official declaration.
+ *
+ *    This is your unofficial assurance that libpng from version 0.71 and
+ *    upward through 1.0.9 are Y2K compliant.  It is my belief that earlier
+ *    versions were also Y2K compliant.
+ *
+ *    Libpng only has three year fields.  One is a 2-byte unsigned integer
+ *    that will hold years up to 65535.  The other two hold the date in text
+ *    format, and will hold years up to 9999.
+ *
+ *    The integer is
+ *        "png_uint_16 year" in png_time_struct.
+ *
+ *    The strings are
+ *        "png_charp time_buffer" in png_struct and
+ *        "near_time_buffer", which is a local character string in png.c.
+ *
+ *    There are seven time-related functions:
+ *        png.c: png_convert_to_rfc_1123() in png.c
+ *          (formerly png_convert_to_rfc_1152() in error)
+ *        png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
+ *        png_convert_from_time_t() in pngwrite.c
+ *        png_get_tIME() in pngget.c
+ *        png_handle_tIME() in pngrutil.c, called in pngread.c
+ *        png_set_tIME() in pngset.c
+ *        png_write_tIME() in pngwutil.c, called in pngwrite.c
+ *
+ *    All handle dates properly in a Y2K environment.  The
+ *    png_convert_from_time_t() function calls gmtime() to convert from system
+ *    clock time, which returns (year - 1900), which we properly convert to
+ *    the full 4-digit year.  There is a possibility that applications using
+ *    libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+ *    function, or that they are incorrectly passing only a 2-digit year
+ *    instead of "year - 1900" into the png_convert_from_struct_tm() function,
+ *    but this is not under our control.  The libpng documentation has always
+ *    stated that it works with 4-digit years, and the APIs have been
+ *    documented as such.
+ *
+ *    The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
+ *    integer to hold the year, and can hold years as large as 65535.
+ *
+ *    zlib, upon which libpng depends, is also Y2K compliant.  It contains
+ *    no date-related code.
+ *
+ *       Glenn Randers-Pehrson
+ *       libpng maintainer
+ *       PNG Development Group
+ */
+
+#ifndef PNG_H
+#define PNG_H
 
 /* This is not the place to learn how to use libpng.  The file libpng.txt
  * describes how to use libpng, and the file example.c summarizes it
@@ -159,46 +259,83 @@
  * at the actual function definitions and structure components.
  */
 
+/* Version information for png.h - this should match the version in png.c */
+#define PNG_LIBPNG_VER_STRING "1.0.9"
+
+#define PNG_LIBPNG_VER_SONUM   2
+#define PNG_LIBPNG_VER_DLLNUM  %DLLNUM%
+
+/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
+#define PNG_LIBPNG_VER_MAJOR   1
+#define PNG_LIBPNG_VER_MINOR   0
+#define PNG_LIBPNG_VER_RELEASE 9
+/* This should match the numeric part of the final component of
+ * PNG_LIBPNG_VER_STRING, omitting any leading zero: */
+
+#define PNG_LIBPNG_VER_BUILD  0
+
+#define PNG_LIBPNG_BUILD_ALPHA    1
+#define PNG_LIBPNG_BUILD_BETA     2
+#define PNG_LIBPNG_BUILD_RC       3
+#define PNG_LIBPNG_BUILD_STABLE   4
+#define PNG_LIBPNG_BUILD_TYPEMASK 7
+#define PNG_LIBPNG_BUILD_PATCH    8 /* Can be OR'ed with STABLE only */
+#define PNG_LIBPNG_BUILD_TYPE 4
+
+/* Careful here.  At one time, Guy wanted to use 082, but that would be octal.
+ * We must not include leading zeros.
+ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
+ * version 1.0.0 was mis-numbered 100 instead of 10000).  From
+ * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=release */
+#define PNG_LIBPNG_VER 10009 /* 1.0.9 */
+
+#ifndef PNG_VERSION_INFO_ONLY
+
 /* include the compression library's header */
 #include "zlib.h"
 
-/* include all user configurable info */
+/* include all user configurable info, including optional assembler routines */
 #include "pngconf.h"
 
+/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
 /* This file is arranged in several sections.  The first section contains
  * structure and type definitions.  The second section contains the external
  * library functions, while the third has the internal library functions,
  * which applications aren't expected to use directly.
  */
 
-/* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.0.3"
-
-/* Careful here.  At one time, Guy wanted to use 082, but that would be octal.
- * We must not include leading zeros.
- * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
- * version 1.0.0 was mis-numbered 100 instead of 10000).  From
- * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=bugfix */
-#define PNG_LIBPNG_VER    10003  /* 1.0.3 */
-
 /* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
 #if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
 /* Version information for C files, stored in png.c.  This had better match
  * the version above.
  */
-extern char png_libpng_ver[12];   /* need room for 99.99.99aa */
+#ifdef PNG_USE_GLOBAL_ARRAYS
+PNG_EXPORT_VAR (const char) png_libpng_ver[18];
+  /* need room for 99.99.99beta99z*/
+#else
+#define png_libpng_ver png_get_header_ver(NULL)
+#endif
 
+#ifdef PNG_USE_GLOBAL_ARRAYS
+/* This was removed in version 1.0.5c */
 /* Structures to facilitate easy interlacing.  See png.c for more details */
-extern int FARDATA png_pass_start[7];
-extern int FARDATA png_pass_inc[7];
-extern int FARDATA png_pass_ystart[7];
-extern int FARDATA png_pass_yinc[7];
-extern int FARDATA png_pass_mask[7];
-extern int FARDATA png_pass_dsp_mask[7];
-/* These aren't currently used.  If you need them, see png.c for more details
-extern int FARDATA png_pass_width[7];
-extern int FARDATA png_pass_height[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_start[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_inc[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_ystart[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_yinc[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_mask[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_dsp_mask[7];
+#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+PNG_EXPORT_VAR (const int FARDATA) png_pass_width[7];
+#endif
+/* This isn't currently used.  If you need it, see png.c for more details.
+PNG_EXPORT_VAR (const int FARDATA) png_pass_height[7];
 */
+#endif
 
 #endif /* PNG_NO_EXTERN */
 
@@ -237,17 +374,67 @@
 typedef png_color_8 FAR * png_color_8p;
 typedef png_color_8 FAR * FAR * png_color_8pp;
 
-/* png_text holds the text in a PNG file, and whether they are compressed
-   in the PNG file or not.  The "text" field points to a regular C string. */
+/*
+ * The following two structures are used for the in-core representation
+ * of sPLT chunks.
+ */
+typedef struct png_sPLT_entry_struct
+{
+   png_uint_16 red;
+   png_uint_16 green;
+   png_uint_16 blue;
+   png_uint_16 alpha;
+   png_uint_16 frequency;
+} png_sPLT_entry;
+typedef png_sPLT_entry FAR * png_sPLT_entryp;
+typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp;
+
+/*  When the depth of the sPLT palette is 8 bits, the color and alpha samples
+ *  occupy the LSB of their respective members, and the MSB of each member
+ *  is zero-filled.  The frequency member always occupies the full 16 bits.
+ */
+
+typedef struct png_sPLT_struct
+{
+   png_charp name;           /* palette name */
+   png_byte depth;           /* depth of palette samples */
+   png_sPLT_entryp entries;  /* palette entries */
+   png_int_32 nentries;      /* number of palette entries */
+} png_sPLT_t;
+typedef png_sPLT_t FAR * png_sPLT_tp;
+typedef png_sPLT_t FAR * FAR * png_sPLT_tpp;
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,
+ * and whether that contents is compressed or not.  The "key" field
+ * points to a regular zero-terminated C string.  The "text", "lang", and
+ * "lang_key" fields can be regular C strings, empty strings, or NULL pointers.
+ * However, the * structure returned by png_get_text() will always contain
+ * regular zero-terminated C strings (possibly empty), never NULL pointers,
+ * so they can be safely used in printf() and other string-handling functions.
+ */
 typedef struct png_text_struct
 {
-   int compression;        /* compression value, see PNG_TEXT_COMPRESSION_ */
+   int  compression;       /* compression value:
+                             -1: tEXt, none
+                              0: zTXt, deflate
+                              1: iTXt, none
+                              2: iTXt, deflate  */
    png_charp key;          /* keyword, 1-79 character description of "text" */
-   png_charp text;         /* comment, may be an empty string (ie "") */
-   png_size_t text_length; /* length of "text" field */
+   png_charp text;         /* comment, may be an empty string (ie "")
+                              or a NULL pointer */
+   png_size_t text_length; /* length of the text string */
+#ifdef PNG_iTXt_SUPPORTED
+   png_size_t itxt_length; /* length of the itxt string */
+   png_charp lang;         /* language code, 0-79 characters
+                              or a NULL pointer */
+   png_charp lang_key;     /* keyword translated UTF-8 string, 0 or more
+                              chars or a NULL pointer */
+#endif
 } png_text;
 typedef png_text FAR * png_textp;
 typedef png_text FAR * FAR * png_textpp;
+#endif
 
 /* Supported compression types for text in PNG files (tEXt, and zTXt).
  * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
@@ -255,13 +442,15 @@
 #define PNG_TEXT_COMPRESSION_zTXt_WR -2
 #define PNG_TEXT_COMPRESSION_NONE    -1
 #define PNG_TEXT_COMPRESSION_zTXt     0
-#define PNG_TEXT_COMPRESSION_LAST     1  /* Not a valid value */
+#define PNG_ITXT_COMPRESSION_NONE     1
+#define PNG_ITXT_COMPRESSION_zTXt     2
+#define PNG_TEXT_COMPRESSION_LAST     3  /* Not a valid value */
 
 /* png_time is a way to hold the time in an machine independent way.
  * Two conversions are provided, both from time_t and struct tm.  There
  * is no portable way to convert to either of these structures, as far
  * as I know.  If you know of a portable way, send it to me.  As a side
- * note - PNG is Year 2000 compliant!
+ * note - PNG has always been Year 2000 compliant!
  */
 typedef struct png_time_struct
 {
@@ -275,6 +464,26 @@
 typedef png_time FAR * png_timep;
 typedef png_time FAR * FAR * png_timepp;
 
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+/* png_unknown_chunk is a structure to hold queued chunks for which there is
+ * no specific support.  The idea is that we can use this to queue
+ * up private chunks for output even though the library doesn't actually
+ * know about their semantics.
+ */
+typedef struct png_unknown_chunk_t
+{
+    png_byte name[5];
+    png_byte *data;
+    png_size_t size;
+
+    /* libpng-using applications should NOT directly modify this byte. */
+    png_byte location; /* mode of operation at read time */
+}
+png_unknown_chunk;
+typedef png_unknown_chunk FAR * png_unknown_chunkp;
+typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp;
+#endif
+
 /* png_info is a structure that holds the information in a PNG file so
  * that the application can find out the characteristics of the image.
  * If you are reading the file, this structure will tell you what is
@@ -295,6 +504,24 @@
  * In any case, the order of the parameters in png_info_struct should NOT
  * be changed for as long as possible to keep compatibility with applications
  * that use the old direct-access method with png_info_struct.
+ *
+ * The following members may have allocated storage attached that should be
+ * cleaned up before the structure is discarded: palette, trans, text,
+ * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
+ * splt_palettes, scal_unit, row_pointers, and unknowns.   By default, these
+ * are automatically freed when the info structure is deallocated, if they were
+ * allocated internally by libpng.  This behavior can be changed by means
+ * of the png_data_freer() function.
+ *
+ * More allocation details: all the chunk-reading functions that
+ * change these members go through the corresponding png_set_*
+ * functions.  A function to clear these members is available: see
+ * png_free_data().  The png_set_* functions do not depend on being
+ * able to point info structure members to any of the storage they are
+ * passed (they make their own copies), EXCEPT that the png_set_text
+ * functions use the same storage passed to them in the text_ptr or
+ * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
+ * functions do not make their own copies.
  */
 typedef struct png_info_struct
 {
@@ -308,12 +535,13 @@
    png_uint_16 num_trans;   /* number of transparent palette color (tRNS) */
    png_byte bit_depth;      /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
    png_byte color_type;     /* see PNG_COLOR_TYPE_ below (from IHDR) */
+   /* The following three should have been named *_method not *_type */
    png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
    png_byte filter_type;    /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
    png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
 
    /* The following is informational only on read, and not used on writes. */
-   png_byte channels;       /* number of data channels per pixel (1, 3, 4)*/
+   png_byte channels;       /* number of data channels per pixel (1, 2, 3, 4)*/
    png_byte pixel_depth;    /* number of bits per pixel */
    png_byte spare_byte;     /* to align the data, and for future use */
    png_byte signature[8];   /* magic bytes read by libpng from start of file */
@@ -324,41 +552,42 @@
     * and initialize the appropriate fields below.
     */
 
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED) || \
-    defined(PNG_READ_GAMMA_SUPPORTED)
+#if defined(PNG_gAMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
    /* The gAMA chunk describes the gamma characteristics of the system
     * on which the image was created, normally in the range [1.0, 2.5].
     * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
     */
    float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */
-#endif /* PNG_READ_gAMA_SUPPORTED || PNG_WRITE_gAMA_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
+#if defined(PNG_sRGB_SUPPORTED)
     /* GR-P, 0.96a */
     /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
    png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
-#endif /* PNG_READ_sRGB_SUPPORTED || PNG_WRITE_sRGB_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
-    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
-   /* The tEXt and zTXt chunks contain human-readable textual data in
-    * uncompressed and compressed forms, respectively.  The data in "text"
-    * is an array of pointers to uncompressed, null-terminated C strings.
-    * Each chunk has a keyword that describes the textual data contained
-    * in that chunk.  Keywords are not required to be unique, and the text
-    * string may be empty.  Any number of text chunks may be in an image.
+#if defined(PNG_TEXT_SUPPORTED)
+   /* The tEXt, and zTXt chunks contain human-readable textual data in
+    * uncompressed, compressed, and optionally compressed forms, respectively.
+    * The data in "text" is an array of pointers to uncompressed,
+    * null-terminated C strings. Each chunk has a keyword that describes the
+    * textual data contained in that chunk.  Keywords are not required to be
+    * unique, and the text string may be empty.  Any number of text chunks may
+    * be in an image.
     */
    int num_text; /* number of comments read/to write */
    int max_text; /* current size of text array */
    png_textp text; /* array of comments read/to write */
-#endif /* PNG_READ_OR_WRITE_tEXt_OR_zTXt_SUPPORTED */
-#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
+#endif /* PNG_TEXT_SUPPORTED */
+
+#if defined(PNG_tIME_SUPPORTED)
    /* The tIME chunk holds the last time the displayed image data was
     * modified.  See the png_time struct for the contents of this struct.
     */
    png_time mod_time;
-#endif /* PNG_READ_tIME_SUPPORTED || PNG_WRITE_tIME_SUPPORTED */
-#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
+#endif
+
+#if defined(PNG_sBIT_SUPPORTED)
    /* The sBIT chunk specifies the number of significant high-order bits
     * in the pixel data.  Values are in the range [1, bit_depth], and are
     * only specified for the channels in the pixel data.  The contents of
@@ -366,9 +595,10 @@
     * (valid & PNG_INFO_sBIT) is non-zero.
     */
    png_color_8 sig_bit; /* significant bits in color channels */
-#endif /* PNG_READ_sBIT_SUPPORTED || PNG_WRITE_sBIT_SUPPORTED */
-#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED) || \
-    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
+defined(PNG_READ_BACKGROUND_SUPPORTED)
    /* The tRNS chunk supplies transparency data for paletted images and
     * other image types that don't need a full alpha channel.  There are
     * "num_trans" transparency values for a paletted image, stored in the
@@ -380,9 +610,9 @@
     */
    png_bytep trans; /* transparent values for paletted image */
    png_color_16 trans_values; /* transparent color for non-palette image */
-#endif /* PNG_READ_tRNS_SUPPORTED || PNG_WRITE_tRNS_SUPPORTED */
-#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED) || \
-    defined(PNG_READ_BACKGROUND_SUPPORTED)
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
    /* The bKGD chunk gives the suggested image background color if the
     * display program does not have its own background color and the image
     * is needs to composited onto a background before display.  The colors
@@ -390,18 +620,20 @@
     * pixel data.  Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
     */
    png_color_16 background;
-#endif /* PNG_READ_bKGD_SUPPORTED || PNG_WRITE_bKGD_SUPPORTED */
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+#endif
+
+#if defined(PNG_oFFs_SUPPORTED)
    /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
     * and downwards from the top-left corner of the display, page, or other
     * application-specific co-ordinate space.  See the PNG_OFFSET_ defines
     * below for the unit types.  Valid if (valid & PNG_INFO_oFFs) non-zero.
     */
-   png_uint_32 x_offset; /* x offset on page */
-   png_uint_32 y_offset; /* y offset on page */
+   png_int_32 x_offset; /* x offset on page */
+   png_int_32 y_offset; /* y offset on page */
    png_byte offset_unit_type; /* offset units type */
-#endif /* PNG_READ_oFFs_SUPPORTED || PNG_WRITE_oFFs_SUPPORTED */
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
    /* The pHYs chunk gives the physical pixel density of the image for
     * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
     * defines below).  Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
@@ -409,8 +641,9 @@
    png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
    png_uint_32 y_pixels_per_unit; /* vertical pixel density */
    png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
-#endif /* PNG_READ_pHYs_SUPPORTED || PNG_WRITE_pHYs_SUPPORTED */
-#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
    /* The hIST chunk contains the relative frequency or importance of the
     * various palette entries, so that a viewer can intelligently select a
     * reduced-color palette, if required.  Data is an array of "num_palette"
@@ -418,14 +651,16 @@
     * is non-zero.
     */
    png_uint_16p hist;
-#endif /* PNG_READ_hIST_SUPPORTED || PNG_WRITE_hIST_SUPPORTED */
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
    /* The cHRM chunk describes the CIE color characteristics of the monitor
     * on which the PNG was created.  This data allows the viewer to do gamut
     * mapping of the input image to ensure that the viewer sees the same
     * colors in the image as the creator.  Values are in the range
     * [0.0, 0.8].  Data valid if (valid & PNG_INFO_cHRM) non-zero.
     */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
    float x_white;
    float y_white;
    float x_red;
@@ -434,19 +669,20 @@
    float y_green;
    float x_blue;
    float y_blue;
-#endif /* PNG_READ_cHRM_SUPPORTED || PNG_WRITE_cHRM_SUPPORTED */
-#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
+#endif
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
    /* The pCAL chunk describes a transformation between the stored pixel
-    * values and original physcical data values used to create the image.
+    * values and original physical data values used to create the image.
     * The integer range [0, 2^bit_depth - 1] maps to the floating-point
     * range given by [pcal_X0, pcal_X1], and are further transformed by a
     * (possibly non-linear) transformation function given by "pcal_type"
     * and "pcal_params" into "pcal_units".  Please see the PNG_EQUATION_
-    * defines below, and the PNG-Group's Scientific Visualization extension
-    * chunks document png-scivis-19970203 for a complete description of the
-    * transformations and how they should be implemented, as well as the
-    * png-extensions document for a description of the ASCII parameter
-    * strings.  Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
+    * defines below, and the PNG-Group's PNG extensions document for a
+    * complete description of the transformations and how they should be
+    * implemented, and for a description of the ASCII parameter strings.
+    * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
     */
    png_charp pcal_purpose;  /* pCAL chunk description string */
    png_int_32 pcal_X0;      /* minimum value */
@@ -455,11 +691,81 @@
    png_charpp pcal_params;  /* ASCII strings containing parameter values */
    png_byte pcal_type;      /* equation type (see PNG_EQUATION_ below) */
    png_byte pcal_nparams;   /* number of parameters given in pcal_params */
-#endif /* PNG_READ_pCAL_SUPPORTED || PNG_WRITE_pCAL_SUPPORTED */
+#endif
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_uint_32 free_me;     /* flags items libpng is responsible for freeing */
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+   /* storage for unknown chunks that the library doesn't recognize. */
+   png_unknown_chunkp unknown_chunks;
+   png_size_t unknown_chunks_num;
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+   /* iCCP chunk data. */
+   png_charp iccp_name;     /* profile name */
+   png_charp iccp_profile;  /* International Color Consortium profile data */
+                            /* Note to maintainer: should be png_bytep */
+   png_uint_32 iccp_proflen;  /* ICC profile data length */
+   png_byte iccp_compression; /* Always zero */
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+   /* data on sPLT chunks (there may be more than one). */
+   png_sPLT_tp splt_palettes;
+   png_uint_32 splt_palettes_num;
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+   /* The sCAL chunk describes the actual physical dimensions of the
+    * subject matter of the graphic.  The chunk contains a unit specification
+    * a byte value, and two ASCII strings representing floating-point
+    * values.  The values are width and height corresponsing to one pixel
+    * in the image.  This external representation is converted to double
+    * here.  Data values are valid if (valid & PNG_INFO_sCAL) is non-zero.
+    */
+   png_byte scal_unit;         /* unit of physical scale */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   double scal_pixel_width;    /* width of one pixel */
+   double scal_pixel_height;   /* height of one pixel */
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_charp scal_s_width;     /* string containing height */
+   png_charp scal_s_height;    /* string containing width */
+#endif
+#endif
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+   /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) non-zero */
+   /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
+   png_bytepp row_pointers;        /* the image bits */
+#endif
+
+#if defined(PNG_FIXED_POINT_SUPPORTED) && defined(PNG_gAMA_SUPPORTED)
+   png_fixed_point int_gamma; /* gamma of image, if (valid & PNG_INFO_gAMA) */
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED) && defined(PNG_FIXED_POINT_SUPPORTED)
+   png_fixed_point int_x_white;
+   png_fixed_point int_y_white;
+   png_fixed_point int_x_red;
+   png_fixed_point int_y_red;
+   png_fixed_point int_x_green;
+   png_fixed_point int_y_green;
+   png_fixed_point int_x_blue;
+   png_fixed_point int_y_blue;
+#endif
+
 } png_info;
+
 typedef png_info FAR * png_infop;
 typedef png_info FAR * FAR * png_infopp;
 
+/* Maximum positive integer used in PNG is (2^31)-1 */
+#define PNG_MAX_UINT ((png_uint_32)0x7fffffffL)
+
 /* These describe the color_type field in png_info. */
 /* color type masks */
 #define PNG_COLOR_MASK_PALETTE    1
@@ -472,13 +778,17 @@
 #define PNG_COLOR_TYPE_RGB        (PNG_COLOR_MASK_COLOR)
 #define PNG_COLOR_TYPE_RGB_ALPHA  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
 #define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
+/* aliases */
+#define PNG_COLOR_TYPE_RGBA  PNG_COLOR_TYPE_RGB_ALPHA
+#define PNG_COLOR_TYPE_GA  PNG_COLOR_TYPE_GRAY_ALPHA
 
-/* This is for compression type. PNG 1.0 only defines the single type. */
+/* This is for compression type. PNG 1.0-1.2 only define the single type. */
 #define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
 #define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
 
-/* This is for filter type. PNG 1.0 only defines the single type. */
+/* This is for filter type. PNG 1.0-1.2 only define the single type. */
 #define PNG_FILTER_TYPE_BASE      0 /* Single row per-byte filtering */
+#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
 #define PNG_FILTER_TYPE_DEFAULT   PNG_FILTER_TYPE_BASE
 
 /* These are for the interlacing type.  These values should NOT be changed. */
@@ -498,19 +808,29 @@
 #define PNG_EQUATION_HYPERBOLIC   3 /* Hyperbolic sine transformation */
 #define PNG_EQUATION_LAST         4 /* Not a valid value */
 
+/* These are for the sCAL chunk.  These values should NOT be changed. */
+#define PNG_SCALE_UNKNOWN         0 /* unknown unit (image scale) */
+#define PNG_SCALE_METER           1 /* meters per pixel */
+#define PNG_SCALE_RADIAN          2 /* radians per pixel */
+#define PNG_SCALE_LAST            3 /* Not a valid value */
+
 /* These are for the pHYs chunk.  These values should NOT be changed. */
 #define PNG_RESOLUTION_UNKNOWN    0 /* pixels/unknown unit (aspect ratio) */
 #define PNG_RESOLUTION_METER      1 /* pixels/meter */
 #define PNG_RESOLUTION_LAST       2 /* Not a valid value */
 
 /* These are for the sRGB chunk.  These values should NOT be changed. */
-#define PNG_sRGB_INTENT_SATURATION 0
-#define PNG_sRGB_INTENT_PERCEPTUAL 1
-#define PNG_sRGB_INTENT_ABSOLUTE   2
-#define PNG_sRGB_INTENT_RELATIVE   3
+#define PNG_sRGB_INTENT_PERCEPTUAL 0
+#define PNG_sRGB_INTENT_RELATIVE   1
+#define PNG_sRGB_INTENT_SATURATION 2
+#define PNG_sRGB_INTENT_ABSOLUTE   3
 #define PNG_sRGB_INTENT_LAST       4 /* Not a valid value */
 
+/* This is for text chunks */
+#define PNG_KEYWORD_MAX_LENGTH     79
 
+/* Maximum number of entries in PLTE/sPLT/tRNS arrays */
+#define PNG_MAX_PALETTE_LENGTH	   256
 
 /* These determine if an ancillary chunk's data has been successfully read
  * from the PNG header, or if the application has filled in the corresponding
@@ -529,6 +849,10 @@
 #define PNG_INFO_tIME 0x0200
 #define PNG_INFO_pCAL 0x0400
 #define PNG_INFO_sRGB 0x0800   /* GR-P, 0.96a */
+#define PNG_INFO_iCCP 0x1000   /* ESR, 1.0.6 */
+#define PNG_INFO_sPLT 0x2000   /* ESR, 1.0.6 */
+#define PNG_INFO_sCAL 0x4000   /* ESR, 1.0.6 */
+#define PNG_INFO_IDAT 0x8000L  /* ESR, 1.0.6 */
 
 /* This is used for the transformation routines, as some of them
  * change these values for the row.  It also should enable using
@@ -556,26 +880,57 @@
 typedef struct png_struct_def png_struct;
 typedef png_struct FAR * png_structp;
 
-typedef void (*png_error_ptr) PNGARG((png_structp, png_const_charp));
-typedef void (*png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t));
-typedef void (*png_flush_ptr) PNGARG((png_structp));
-typedef void (*png_read_status_ptr) PNGARG((png_structp, png_uint_32, int));
-typedef void (*png_write_status_ptr) PNGARG((png_structp, png_uint_32, int));
+typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp));
+typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t));
+typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp));
+typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32,
+   int));
+typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32,
+   int));
+
 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-typedef void (*png_progressive_info_ptr) PNGARG((png_structp, png_infop));
-typedef void (*png_progressive_end_ptr) PNGARG((png_structp, png_infop));
-typedef void (*png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
+typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop));
+typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop));
+typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
    png_uint_32, int));
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
-    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
-typedef void (*png_user_transform_ptr) PNGARG((png_structp,
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
+typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp,
     png_row_infop, png_bytep));
-#endif /* PNG_READ|WRITE_USER_TRANSFORM_SUPPORTED */
+#endif
+
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp));
+#endif
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp));
+#endif
+
+/* Transform masks for the high-level interface */
+#define PNG_TRANSFORM_IDENTITY       0x0000    /* read and write */
+#define PNG_TRANSFORM_STRIP_16       0x0001    /* read only */
+#define PNG_TRANSFORM_STRIP_ALPHA    0x0002    /* read only */
+#define PNG_TRANSFORM_PACKING        0x0004    /* read and write */
+#define PNG_TRANSFORM_PACKSWAP       0x0008    /* read and write */
+#define PNG_TRANSFORM_EXPAND         0x0010    /* read only */
+#define PNG_TRANSFORM_INVERT_MONO    0x0020    /* read and write */
+#define PNG_TRANSFORM_SHIFT          0x0040    /* read and write */
+#define PNG_TRANSFORM_BGR            0x0080    /* read and write */
+#define PNG_TRANSFORM_SWAP_ALPHA     0x0100    /* read and write */
+#define PNG_TRANSFORM_SWAP_ENDIAN    0x0200    /* read and write */
+#define PNG_TRANSFORM_INVERT_ALPHA   0x0400    /* read and write */
+#define PNG_TRANSFORM_STRIP_FILLER   0x0800    /* WRITE only */
+
+/* Flags for MNG supported features */
+#define PNG_FLAG_MNG_EMPTY_PLTE     0x01
+#define PNG_FLAG_MNG_FILTER_64      0x04
+#define PNG_ALL_MNG_FEATURES        0x05
 
 typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t));
-typedef void (*png_free_ptr) PNGARG((png_structp, png_structp));
+typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp));
 
 /* The structure that holds the information to read and write PNG files.
  * The only people who need to care about what is inside of this are the
@@ -586,19 +941,33 @@
 
 struct png_struct_def
 {
+#ifdef PNG_SETJMP_SUPPORTED
    jmp_buf jmpbuf;            /* used in png_error */
-
+#endif
    png_error_ptr error_fn;    /* function for printing errors and aborting */
    png_error_ptr warning_fn;  /* function for printing warnings */
    png_voidp error_ptr;       /* user supplied struct for error functions */
    png_rw_ptr write_data_fn;  /* function for writing output data */
    png_rw_ptr read_data_fn;   /* function for reading input data */
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
-    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+   png_voidp io_ptr;          /* ptr to application struct for I/O functions*/
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
    png_user_transform_ptr read_user_transform_fn; /* user read transform */
+#endif
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
    png_user_transform_ptr write_user_transform_fn; /* user write transform */
 #endif
-   png_voidp io_ptr;          /* ptr to application struct for I/O functions*/
+
+/* These were added in libpng-1.0.2 */
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+   png_voidp user_transform_ptr; /* user supplied struct for user transform */
+   png_byte user_transform_depth;    /* bit depth of user transformed pixels */
+   png_byte user_transform_channels; /* channels in user transformed pixels */
+#endif
+#endif
 
    png_uint_32 mode;          /* tells us where we are in the PNG file */
    png_uint_32 flags;         /* flags indicating various things to libpng */
@@ -649,45 +1018,61 @@
    png_byte sig_bytes;        /* magic bytes read/written from start of file */
 
 #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+#ifdef PNG_LEGACY_SUPPORTED
+   png_byte filler;           /* filler byte for pixel expansion */
+#else
    png_uint_16 filler;           /* filler bytes for pixel expansion */
-#endif /* PNG_READ_FILLER_SUPPORTED */
+#endif
+#endif
+
 #if defined(PNG_READ_bKGD_SUPPORTED)
    png_byte background_gamma_type;
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
    float background_gamma;
+#  endif
    png_color_16 background;   /* background color in screen gamma space */
-#if defined(PNG_READ_GAMMA_SUPPORTED)
-   png_color_16 background_1; /* background normalized to gamma 1.0 */
-#endif /* PNG_READ_GAMMA && PNG_READ_bKGD_SUPPORTED */
+#  if defined(PNG_READ_GAMMA_SUPPORTED)
+     png_color_16 background_1; /* background normalized to gamma 1.0 */
+#  endif /* PNG_READ_GAMMA && PNG_READ_bKGD_SUPPORTED */
 #endif /* PNG_READ_bKGD_SUPPORTED */
+
 #if defined(PNG_WRITE_FLUSH_SUPPORTED)
    png_flush_ptr output_flush_fn;/* Function for flushing output */
    png_uint_32 flush_dist;    /* how many rows apart to flush, 0 - no flush */
    png_uint_32 flush_rows;    /* number of rows written since last flush */
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+#endif
+
 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
    int gamma_shift;      /* number of "insignificant" bits 16-bit gamma */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
    float gamma;          /* file gamma value */
-   float screen_gamma;   /* screen gamma value (display_gamma/viewing_gamma */
-#endif /* PNG_READ_GAMMA_SUPPORTED */
+   float screen_gamma;   /* screen gamma value (display_exponent) */
+#endif
+#endif
+
 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
-   png_bytep gamma_table;     /* gamma table for 8 bit depth files */
+   png_bytep gamma_table;     /* gamma table for 8-bit depth files */
    png_bytep gamma_from_1;    /* converts from 1.0 to screen */
    png_bytep gamma_to_1;      /* converts from file to 1.0 */
-   png_uint_16pp gamma_16_table; /* gamma table for 16 bit depth files */
+   png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
    png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
    png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
-#endif /* PNG_READ_GAMMA_SUPPORTED || PNG_WRITE_GAMMA_SUPPORTED */
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined (PNG_READ_sBIT_SUPPORTED)
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_sBIT_SUPPORTED)
    png_color_8 sig_bit;       /* significant bits in each available channel */
-#endif /* PNG_READ_GAMMA_SUPPORTED || PNG_READ_sBIT_SUPPORTED */
+#endif
+
 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
    png_color_8 shift;         /* shift for significant bit tranformation */
-#endif /* PNG_READ_SHIFT_SUPPORTED || PNG_WRITE_SHIFT_SUPPORTED */
+#endif
+
 #if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
  || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
    png_bytep trans;           /* transparency values for paletted files */
    png_color_16 trans_values; /* transparency values for non-paletted files */
-#endif /* PNG_READ|WRITE_tRNS_SUPPORTED||PNG_READ_EXPAND|BACKGROUND_SUPPORTED */
+#endif
+
    png_read_status_ptr read_row_fn;   /* called after each row is decoded */
    png_write_status_ptr write_row_fn; /* called after each row is encoded */
 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
@@ -706,13 +1091,16 @@
    png_size_t current_buffer_size;   /* amount of data now in current_buffer */
    int process_mode;                 /* what push library is currently doing */
    int cur_palette;                  /* current push library palette index */
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
-   png_size_t current_text_size;     /* current size of text input data */
-   png_size_t current_text_left;     /* how much text left to read in input */
-   png_charp current_text;           /* current text chunk buffer */
-   png_charp current_text_ptr;       /* current location in current_text */
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_READ_tEXt/zTXt_SUPPORTED */
+
+#  if defined(PNG_READ_TEXT_SUPPORTED)
+     png_size_t current_text_size;   /* current size of text input data */
+     png_size_t current_text_left;   /* how much text left to read in input */
+     png_charp current_text;         /* current text chunk buffer */
+     png_charp current_text_ptr;     /* current location in current_text */
+#  endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_READ_TEXT_SUPPORTED */
+
 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
 #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
 /* for the Borland special 64K segment handler */
    png_bytepp offset_table_ptr;
@@ -720,14 +1108,17 @@
    png_uint_16 offset_table_number;
    png_uint_16 offset_table_count;
    png_uint_16 offset_table_count_free;
-#endif /* __TURBOC__&&!_Windows&&!__FLAT__ */
+#endif
+
 #if defined(PNG_READ_DITHER_SUPPORTED)
    png_bytep palette_lookup;         /* lookup table for dithering */
    png_bytep dither_index;           /* index translation for palette files */
-#endif /* PNG_READ_DITHER_SUPPORTED */
+#endif
+
 #if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_READ_hIST_SUPPORTED)
    png_uint_16p hist;                /* histogram */
 #endif
+
 #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
    png_byte heuristic_method;        /* heuristic for row filter selection */
    png_byte num_prev_filters;        /* number of weights for previous rows */
@@ -736,31 +1127,73 @@
    png_uint_16p inv_filter_weights;  /* 1/weight(s) for previous line(s) */
    png_uint_16p filter_costs;        /* relative filter calculation cost */
    png_uint_16p inv_filter_costs;    /* 1/relative filter calculation cost */
-#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+#endif
+
 #if defined(PNG_TIME_RFC1123_SUPPORTED)
    png_charp time_buffer;            /* String to hold RFC 1123 time text */
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
+#endif
+
 #ifdef PNG_USER_MEM_SUPPORTED
    png_voidp mem_ptr;                /* user supplied struct for mem functions */
    png_malloc_ptr malloc_fn;         /* function for allocating memory */
    png_free_ptr free_fn;             /* function for freeing memory */
-#endif /* PNG_USER_MEM_SUPPORTED */
+#endif
+
+/* New members added in libpng-1.0.6 */
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_uint_32 free_me;       /* flags items libpng is responsible for freeing */
+#endif
+
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+   png_voidp user_chunk_ptr;
+   png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+   int num_chunk_list;
+   png_bytep chunk_list;
+#endif
+
 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
    png_byte rgb_to_gray_status;
-   png_byte rgb_to_gray_red_coeff;
-   png_byte rgb_to_gray_green_coeff;
-   png_byte rgb_to_gray_blue_coeff;
+   png_uint_16 rgb_to_gray_red_coeff;
+   png_uint_16 rgb_to_gray_green_coeff;
+   png_uint_16 rgb_to_gray_blue_coeff;
+#endif
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED) || \
+    defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+/* Note to maintainer: change this to png_uint_32 at next opportunity */
+   png_byte mng_features_permitted;
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   png_fixed_point int_gamma;
 #endif
+
+   png_byte filter_type;
+
 };
 
+
+/* This prevents a compiler error in png_get_copyright() in png.c if png.c
+and png.h are both at * version 1.0.9
+ */
+typedef png_structp version_1_0_9;
+
 typedef png_struct FAR * FAR * png_structpp;
 
 /* Here are the function definitions most commonly used.  This is not
  * the place to find out how to use libpng.  See libpng.txt for the
  * full explanation, see example.c for the summary.  This just provides
- * a simple one line of the use of each function.
+ * a simple one line description of the use of each function.
  */
 
+/* Returns the version number of the library */
+extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void));
+
 /* Tell lib we have already handled the first <num_bytes> magic bytes.
  * Handling more than 8 bytes from the beginning of the file is an error.
  */
@@ -790,6 +1223,15 @@
    PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
    png_error_ptr error_fn, png_error_ptr warn_fn));
 
+extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size)
+   PNGARG((png_structp png_ptr));
+
+extern PNG_EXPORT(void,png_set_compression_buffer_size)
+   PNGARG((png_structp png_ptr, png_uint_32 size));
+
+/* Reset the compression stream */
+extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr));
+
 #ifdef PNG_USER_MEM_SUPPORTED
 extern PNG_EXPORT(png_structp,png_create_read_struct_2)
    PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
@@ -824,6 +1266,8 @@
 extern void png_info_init PNGARG((png_infop info_ptr));
 
 /* Writes all the PNG information before the image. */
+extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
 extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr,
    png_infop info_ptr));
 
@@ -834,8 +1278,10 @@
 #if defined(PNG_TIME_RFC1123_SUPPORTED)
 extern PNG_EXPORT(png_charp,png_convert_to_rfc1123)
    PNGARG((png_structp png_ptr, png_timep ptime));
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
+#endif
 
+#if !defined(_WIN32_WCE)
+/* "time.h" functions are not supported on WindowsCE */
 #if defined(PNG_WRITE_tIME_SUPPORTED)
 /* convert from a struct tm to png_time */
 extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime,
@@ -845,125 +1291,143 @@
 extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime,
    time_t ttime));
 #endif /* PNG_WRITE_tIME_SUPPORTED */
+#endif /* _WIN32_WCE */
 
 #if defined(PNG_READ_EXPAND_SUPPORTED)
-/* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha if available. */
+/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
 extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_EXPAND_SUPPORTED */
+extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr));
+#endif
 
 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
 /* Use blue, green, red order for pixels. */
 extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_BGR_SUPPORTED || PNG_WRITE_BGR_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
-/* Expand the grayscale to 24 bit RGB if necessary. */
+/* Expand the grayscale to 24-bit RGB if necessary. */
 extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
 /* Reduce RGB to grayscale. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
 extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr,
-   int error_action, float red, float green ));
+   int error_action, double red, double green ));
+#endif
+extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr,
+   int error_action, png_fixed_point red, png_fixed_point green ));
 extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp
    png_ptr));
-#endif /* PNG_READ_RGB_TO_GRAY_SUPPORTED */
+#endif
 
 extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth,
    png_colorp palette));
 
 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
 extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_STRIP_ALPHA_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
     defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
 extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_SWAP_ALPHA_SUPPORTED || PNG_WRITE_SWAP_ALPHA_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
     defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
 extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED || PNG_WRITE_INVERT_ALPHA_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
 /* Add a filler byte to 24-bit RGB images. */
 extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr,
    png_uint_32 filler, int flags));
-
 /* The values of the PNG_FILLER_ defines should NOT be changed */
 #define PNG_FILLER_BEFORE 0
 #define PNG_FILLER_AFTER 1
 #endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
 
 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-/* Swap bytes in 16 bit depth files. */
+/* Swap bytes in 16-bit depth files. */
 extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_SWAP_SUPPORTED || PNG_WRITE_SWAP_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
-/* Use 1 byte per pixel in 1, 2, or 4 bit depth files. */
+/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
 extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_PACK_SUPPORTED || PNG_WRITE_PACK_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
 /* Swap packing order of pixels in bytes. */
 extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_PACKSWAP_SUPPORTED || PNG_WRITE_PACKSWAP_SUPPOR */
+#endif
 
 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
 /* Converts files to legal bit depths. */
 extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr,
    png_color_8p true_bits));
-#endif /* PNG_READ_SHIFT_SUPPORTED || PNG_WRITE_SHIFT_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
     defined(PNG_WRITE_INTERLACING_SUPPORTED)
 /* Have the code handle the interlacing.  Returns the number of passes. */
 extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_INTERLACING_SUPPORTED || PNG_WRITE_INTERLACING_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
-/* Invert monocrome files */
+/* Invert monochrome files */
 extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_INVERT_SUPPORTED || PNG_WRITE_INVERT_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
 /* Handle alpha and tRNS by replacing with a background color. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
 extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr,
    png_color_16p background_color, int background_gamma_code,
    int need_expand, double background_gamma));
+#endif
 #define PNG_BACKGROUND_GAMMA_UNKNOWN 0
 #define PNG_BACKGROUND_GAMMA_SCREEN  1
 #define PNG_BACKGROUND_GAMMA_FILE    2
 #define PNG_BACKGROUND_GAMMA_UNIQUE  3
-#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_16_TO_8_SUPPORTED)
-/* strip the second byte of information from a 16 bit depth file. */
+/* strip the second byte of information from a 16-bit depth file. */
 extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_16_TO_8_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_DITHER_SUPPORTED)
 /* Turn on dithering, and reduce the palette to the number of colors available. */
 extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr,
    png_colorp palette, int num_palette, int maximum_colors,
    png_uint_16p histogram, int full_dither));
-#endif /* PNG_READ_DITHER_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_GAMMA_SUPPORTED)
-/* Handle gamma correction. Screen_gamma=(display_gamma/viewing_gamma) */
+/* Handle gamma correction. Screen_gamma=(display_exponent) */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
 extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr,
    double screen_gamma, double default_file_gamma));
-#endif /* PNG_READ_GAMMA_SUPPORTED */
+#endif
+#endif
+
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */
+/* Deprecated and will be removed.  Use png_permit_mng_features() instead. */
+extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr,
+   int empty_plte_permitted));
+#endif
 
 #if defined(PNG_WRITE_FLUSH_SUPPORTED)
 /* Set how many lines between output flushes - 0 for no flushing */
 extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows));
-
 /* Flush the current PNG output buffer */
 extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr));
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+#endif
 
 /* optional update palette with requested transformations */
 extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr));
@@ -1114,9 +1578,11 @@
  * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
  * to the UNWEIGHTED method, but with added encoding time/computation.
  */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
 extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr,
    int heuristic_method, int num_weights, png_doublep filter_weights,
    png_doublep filter_costs));
+#endif
 #endif /*  PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
 
 /* Heuristic used for row filter selection.  These defines should NOT be
@@ -1160,7 +1626,7 @@
 
 #if !defined(PNG_NO_STDIO)
 /* Initialize the input/output for the PNG file to the default functions. */
-extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, FILE *fp));
+extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp));
 #endif
 
 /* Replace the (error and abort), and warning functions with user
@@ -1202,21 +1668,40 @@
 /* Replace the default memory allocation functions with user supplied one(s). */
 extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr,
    png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn));
-
 /* Return the user pointer associated with the memory functions */
 extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr));
-#endif /* PNG_USER_MEM_SUPPORTED */
+#endif
 
-#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
 extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp
    png_ptr, png_user_transform_ptr read_user_transform_fn));
 #endif
 
-#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
 extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp
    png_ptr, png_user_transform_ptr write_user_transform_fn));
 #endif
 
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp
+   png_ptr, png_voidp user_transform_ptr, int user_transform_depth,
+   int user_transform_channels));
+/* Return the user pointer associated with the user transform functions */
+extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr)
+   PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr,
+   png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
+extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp
+   png_ptr));
+#endif
+
 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
 /* Sets the function callbacks for the push reader, and a pointer to a
  * user-defined structure available to the callback functions.
@@ -1247,12 +1732,40 @@
 /* frees a pointer allocated by png_malloc() */
 extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr));
 
+/* Free data that was allocated internally */
+extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 free_me, int num));
+#ifdef PNG_FREE_ME_SUPPORTED
+/* Reassign responsibility for freeing existing data, whether allocated
+ * by libpng or by the application */
+extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int freer, png_uint_32 mask));
+#endif
+/* assignments for png_data_freer */
+#define PNG_DESTROY_WILL_FREE_DATA 1
+#define PNG_SET_WILL_FREE_DATA 1
+#define PNG_USER_WILL_FREE_DATA 2
+/* Flags for png_ptr->free_me and info_ptr->free_me */
+#define PNG_FREE_HIST 0x0008
+#define PNG_FREE_ICCP 0x0010
+#define PNG_FREE_SPLT 0x0020
+#define PNG_FREE_ROWS 0x0040
+#define PNG_FREE_PCAL 0x0080
+#define PNG_FREE_SCAL 0x0100
+#define PNG_FREE_UNKN 0x0200
+#define PNG_FREE_LIST 0x0400
+#define PNG_FREE_PLTE 0x1000
+#define PNG_FREE_TRNS 0x2000
+#define PNG_FREE_TEXT 0x4000
+#define PNG_FREE_ALL  0x7fff
+#define PNG_FREE_MUL  0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
+
 #ifdef PNG_USER_MEM_SUPPORTED
 extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr,
    png_uint_32 size));
 extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr,
    png_voidp ptr));
-#endif /* PNG_USER_MEM_SUPPORTED */
+#endif
 
 extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr,
    png_voidp s1, png_voidp s2, png_uint_32 size));
@@ -1301,6 +1814,17 @@
 extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr,
 png_infop info_ptr));
 
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+/* Returns row_pointers, which is an array of pointers to scanlines that was
+returned from png_read_png(). */
+extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+/* Set row_pointers, which is an array of pointers to scanlines for use
+by png_write_png(). */
+extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_bytepp row_pointers));
+#endif
+
 /* Returns number of color channels in image. */
 extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr,
 png_infop info_ptr));
@@ -1343,17 +1867,19 @@
 png_ptr, png_infop info_ptr));
 
 /* Returns pixel aspect ratio, computed from pHYs chunk data.  */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
 extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp
 png_ptr, png_infop info_ptr));
+#endif
 
 /* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
-extern PNG_EXPORT(png_uint_32, png_get_x_offset_pixels) PNGARG((png_structp
+extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp
 png_ptr, png_infop info_ptr));
-extern PNG_EXPORT(png_uint_32, png_get_y_offset_pixels) PNGARG((png_structp
+extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp
 png_ptr, png_infop info_ptr));
-extern PNG_EXPORT(png_uint_32, png_get_x_offset_microns) PNGARG((png_structp
+extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp
 png_ptr, png_infop info_ptr));
-extern PNG_EXPORT(png_uint_32, png_get_y_offset_microns) PNGARG((png_structp
+extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp
 png_ptr, png_infop info_ptr));
 
 #endif /* PNG_EASY_ACCESS_SUPPORTED */
@@ -1365,88 +1891,115 @@
 #if defined(PNG_READ_bKGD_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_color_16p *background));
-#endif /* PNG_READ_bKGD_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED)
+#if defined(PNG_bKGD_SUPPORTED)
 extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_color_16p background));
-#endif /* PNG_READ_bKGD_SUPPORTED || PNG_WRITE_bKGD_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
 extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr,
    png_infop info_ptr, double *white_x, double *white_y, double *red_x,
    double *red_y, double *green_x, double *green_y, double *blue_x,
    double *blue_y));
-#endif /* PNG_READ_cHRM_SUPPORTED */
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point
+   *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y,
+   png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point
+   *int_blue_x, png_fixed_point *int_blue_y));
+#endif
+#endif
 
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
 extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr,
    png_infop info_ptr, double white_x, double white_y, double red_x,
    double red_y, double green_x, double green_y, double blue_x, double blue_y));
-#endif /* PNG_READ_cHRM_SUPPORTED || PNG_WRITE_cHRM_SUPPORTED */
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y,
+   png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
+   int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
+   png_fixed_point int_blue_y));
+#endif
+#endif
 
 #if defined(PNG_READ_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
 extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr,
    png_infop info_ptr, double *file_gamma));
-#endif /* PNG_READ_gAMA_SUPPORTED */
+#endif
+extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_fixed_point *int_file_gamma));
+#endif
 
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
 extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr,
    png_infop info_ptr, double file_gamma));
-#endif /* PNG_READ_gAMA_SUPPORTED || PNG_WRITE_gAMA_SUPPORTED */
+#endif
+extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_fixed_point int_file_gamma));
+#endif
 
 #if defined(PNG_READ_hIST_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_16p *hist));
-#endif /* PNG_READ_hIST_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
+#if defined(PNG_hIST_SUPPORTED)
 extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_16p hist));
-#endif /* PNG_READ_hIST_SUPPORTED || PNG_WRITE_hIST_SUPPORTED */
+#endif
 
 extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_32 *width, png_uint_32 *height,
-   int *bit_depth, int *color_type, int *interlace_type,
-   int *compression_type, int *filter_type));
+   int *bit_depth, int *color_type, int *interlace_method,
+   int *compression_method, int *filter_method));
 
 extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
-   int color_type, int interlace_type, int compression_type, int filter_type));
+   int color_type, int interlace_method, int compression_method,
+   int filter_method));
 
 #if defined(PNG_READ_oFFs_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr,
-   png_infop info_ptr, png_uint_32 *offset_x, png_uint_32 *offset_y,
+   png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
    int *unit_type));
-#endif /* PNG_READ_oFFs_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+#if defined(PNG_oFFs_SUPPORTED)
 extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr,
-   png_infop info_ptr, png_uint_32 offset_x, png_uint_32 offset_y,
+   png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y,
    int unit_type));
-#endif /* PNG_READ_oFFs_SUPPORTED || PNG_WRITE_oFFs_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_pCAL_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
    int *type, int *nparams, png_charp *units, png_charpp *params));
-#endif /* PNG_READ_pCAL_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
+#if defined(PNG_pCAL_SUPPORTED)
 extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1,
    int type, int nparams, png_charp units, png_charpp params));
-#endif /* PNG_READ_pCAL_SUPPORTED || PNG_WRITE_pCAL_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_pHYs_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
-#endif /* PNG_READ_pHYs_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+#if defined(PNG_pHYs_SUPPORTED)
 extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
-#endif /* PNG_READ_pHYs_SUPPORTED || PNG_WRITE_pHYs_SUPPORTED */
+#endif
 
 extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_colorp *palette, int *num_palette));
@@ -1457,58 +2010,153 @@
 #if defined(PNG_READ_sBIT_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_color_8p *sig_bit));
-#endif /* PNG_READ_sBIT_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
+#if defined(PNG_sBIT_SUPPORTED)
 extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_color_8p sig_bit));
-#endif /* PNG_READ_sBIT_SUPPORTED || PNG_WRITE_sBIT_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_sRGB_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr,
    png_infop info_ptr, int *intent));
-#endif /* PNG_READ_sRGB_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
+#if defined(PNG_sRGB_SUPPORTED)
 extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr,
    png_infop info_ptr, int intent));
 extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr,
    png_infop info_ptr, int intent));
-#endif /* PNG_READ_sRGB_SUPPORTED || PNG_WRITE_sRGB_SUPPORTED */
+#endif
+
+#if defined(PNG_READ_iCCP_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charpp name, int *compression_type,
+   png_charpp profile, png_uint_32 *proflen));
+   /* Note to maintainer: profile should be png_bytepp */
+#endif
 
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
-/* png_get_text also returns the number of text chunks in text_ptr */
+#if defined(PNG_iCCP_SUPPORTED)
+extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charp name, int compression_type,
+   png_charp profile, png_uint_32 proflen));
+   /* Note to maintainer: profile should be png_bytep */
+#endif
+
+#if defined(PNG_READ_sPLT_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_sPLT_tpp entries));
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_sPLT_tp entries, int nentries));
+#endif
+
+#if defined(PNG_READ_TEXT_SUPPORTED)
+/* png_get_text also returns the number of text chunks in *num_text */
 extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_textp *text_ptr, int *num_text));
-#endif /* PNG_READ_tEXt_SUPPORTED || PNG_READ_zTXt_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
-    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+/*
+ *  Note while png_set_text() will accept a structure whose text,
+ *  language, and  translated keywords are NULL pointers, the structure
+ *  returned by png_get_text will always contain regular
+ *  zero-terminated C strings.  They might be empty strings but
+ *  they will never be NULL pointers.
+ */
+
+#if defined(PNG_TEXT_SUPPORTED)
 extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_textp text_ptr, int num_text));
-#endif /* PNG_READ_OR_WRITE_tEXt_OR_zTXt_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_tIME_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_timep *mod_time));
-#endif /* PNG_READ_tIME_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
+#if defined(PNG_tIME_SUPPORTED)
 extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_timep mod_time));
-#endif /* PNG_READ_tIME_SUPPORTED || PNG_WRITE_tIME_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_tRNS_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_bytep *trans, int *num_trans,
    png_color_16p *trans_values));
-#endif /* PNG_READ_tRNS_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED)
+#if defined(PNG_tRNS_SUPPORTED)
 extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_bytep trans, int num_trans,
    png_color_16p trans_values));
-#endif /* PNG_READ_tRNS_SUPPORTED || PNG_WRITE_tRNS_SUPPORTED */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+#endif
+
+#if defined(PNG_READ_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int *unit, double *width, double *height));
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight));
+#endif
+#endif
+#endif /* PNG_READ_sCAL_SUPPORTED */
+
+#if defined(PNG_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int unit, double width, double height));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int unit, png_charp swidth, png_charp sheight));
+#endif
+#endif /* PNG_READ_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+/* provide a list of chunks and how they are to be handled, if the built-in
+   handling or default unknown chunk handling is not desired.  Any chunks not
+   listed will be handled in the default manner.  The IHDR and IEND chunks
+   must not be listed.
+      keep = 0: follow default behavour
+           = 1: do not keep
+           = 2: keep only if safe-to-copy
+           = 3: keep even if unsafe-to-copy
+*/
+extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp
+   png_ptr, int keep, png_bytep chunk_list, int num_chunks));
+extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns));
+extern PNG_EXPORT(void, png_set_unknown_chunk_location)
+   PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location));
+extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp
+   png_ptr, png_infop info_ptr, png_unknown_chunkpp entries));
+#endif
+
+/* Png_free_data() will turn off the "valid" flag for anything it frees.
+   If you need to turn it off for a chunk that your application has freed,
+   you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */
+extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int mask));
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+/* The "params" pointer is currently not used and is for future expansion. */
+extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr,
+                        png_infop info_ptr,
+                        int transforms,
+                        png_voidp params));
+extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr,
+                        png_infop info_ptr,
+                        int transforms,
+                        png_voidp params));
+#endif
 
 /* Define PNG_DEBUG at compile time for debugging information.  Higher
  * numbers for PNG_DEBUG mean more debugging information.  This has
@@ -1517,19 +2165,38 @@
  */
 #ifdef PNG_DEBUG
 #if (PNG_DEBUG > 0)
+#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
+#include <crtdbg.h>
+#if (PNG_DEBUG > 1)
+#define png_debug(l,m)  _RPT0(_CRT_WARN,m)
+#define png_debug1(l,m,p1)  _RPT1(_CRT_WARN,m,p1)
+#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m,p1,p2)
+#endif
+#else /* PNG_DEBUG_FILE || !_MSC_VER */
 #ifndef PNG_DEBUG_FILE
 #define PNG_DEBUG_FILE stderr
 #endif /* PNG_DEBUG_FILE */
-
-#define png_debug(l,m)        if (PNG_DEBUG > l) \
-                                 fprintf(PNG_DEBUG_FILE,"%s"m,(l==1 ? "\t" : \
-                                    (l==2 ? "\t\t":(l>2 ? "\t\t\t":""))))
-#define png_debug1(l,m,p1)    if (PNG_DEBUG > l) \
-                                 fprintf(PNG_DEBUG_FILE,"%s"m,(l==1 ? "\t" : \
-                                    (l==2 ? "\t\t":(l>2 ? "\t\t\t":""))),p1)
-#define png_debug2(l,m,p1,p2) if (PNG_DEBUG > l) \
-                                 fprintf(PNG_DEBUG_FILE,"%s"m,(l==1 ? "\t" : \
-                                    (l==2 ? "\t\t":(l>2 ? "\t\t\t":""))),p1,p2)
+#if (PNG_DEBUG > 1)
+#define png_debug(l,m) \
+{ \
+     int num_tabs=l; \
+     fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
+       (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
+}
+#define png_debug1(l,m,p1) \
+{ \
+     int num_tabs=l; \
+     fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
+       (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
+}
+#define png_debug2(l,m,p1,p2) \
+{ \
+     int num_tabs=l; \
+     fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
+       (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
+}
+#endif /* (PNG_DEBUG > 1) */
+#endif /* _MSC_VER */
 #endif /* (PNG_DEBUG > 0) */
 #endif /* PNG_DEBUG */
 #ifndef png_debug
@@ -1542,20 +2209,28 @@
 #define png_debug2(l, m, p1, p2)
 #endif
 
+extern PNG_EXPORT(png_bytep,png_sig_bytes) PNGARG((void));
+
 extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr));
 extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr));
 
-#ifdef PNG_NO_EXTERN
-/* this only gets included in png.c */
-png_charp
-png_get_header_version(png_structp png_ptr)
-{
-   if(png_ptr == NULL)
-     /* silence compiler warning about unused png_ptr */ ;
-   return("\n libpng version 1.0.3 - January 14, 1999 (header)\n");
-}
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp
+   png_ptr, png_uint_32 mng_features_permitted));
+#endif
+
+#if 0 /* delay these until version 1.2.0 */
+/* png.c, pnggccrd.c, or pngvcrd.c */
+extern PNG_EXPORT(int,png_mmx_support) PNGARG((void));
 #endif
 
+/* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */
+
+#define PNG_HEADER_VERSION_STRING \
+   " libpng version 1.0.9 - January 31, 2001 (header)\n"
+
 #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
 /* With these routines we avoid an integer divide, which will be slower on
  * most machines.  However, it does take more operations than the corresponding
@@ -1572,14 +2247,14 @@
  /* fg and bg should be in `gamma 1.0' space; alpha is the opacity          */
 
 #  define png_composite(composite, fg, alpha, bg)                            \
-     { png_uint_16 temp = ((png_uint_16)(fg) * (png_uint_16)(alpha) +        \
-                        (png_uint_16)(bg)*(png_uint_16)(255 -                \
+     { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \
+                        +        (png_uint_16)(bg)*(png_uint_16)(255 -       \
                         (png_uint_16)(alpha)) + (png_uint_16)128);           \
        (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
 
 #  define png_composite_16(composite, fg, alpha, bg)                         \
-     { png_uint_32 temp = ((png_uint_32)(fg) * (png_uint_32)(alpha) +        \
-                        (png_uint_32)(bg)*(png_uint_32)(65535L -             \
+     { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \
+                        + (png_uint_32)(bg)*(png_uint_32)(65535L -           \
                         (png_uint_32)(alpha)) + (png_uint_32)32768L);        \
        (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
 
@@ -1608,25 +2283,19 @@
 /* Various modes of operation.  Note that after an init, mode is set to
  * zero automatically when the structure is created.
  */
-#define PNG_BEFORE_IHDR       0x00
-#define PNG_HAVE_IHDR         0x01
-#define PNG_HAVE_PLTE         0x02
-#define PNG_HAVE_IDAT         0x04
-#define PNG_AFTER_IDAT        0x08
-#define PNG_HAVE_IEND         0x10
-#define PNG_HAVE_gAMA         0x20
-#define PNG_HAVE_cHRM         0x40
-#define PNG_HAVE_sRGB         0x80
-
-/* push model modes */
-#define PNG_READ_SIG_MODE   0
-#define PNG_READ_CHUNK_MODE 1
-#define PNG_READ_IDAT_MODE  2
-#define PNG_SKIP_MODE       3
-#define PNG_READ_tEXt_MODE  4
-#define PNG_READ_zTXt_MODE  5
-#define PNG_READ_DONE_MODE  6
-#define PNG_ERROR_MODE      7
+#define PNG_HAVE_IHDR               0x01
+#define PNG_HAVE_PLTE               0x02
+#define PNG_HAVE_IDAT               0x04
+#define PNG_AFTER_IDAT              0x08
+#define PNG_HAVE_IEND               0x10
+#define PNG_HAVE_gAMA               0x20
+#define PNG_HAVE_cHRM               0x40
+#define PNG_HAVE_sRGB               0x80
+#define PNG_HAVE_CHUNK_HEADER      0x100
+#define PNG_WROTE_tIME             0x200
+#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
+#define PNG_BACKGROUND_IS_GRAY     0x800
+#define PNG_HAVE_PNG_SIGNATURE    0x1000
 
 /* flags for the transformations the PNG library does on the image data */
 #define PNG_BGR                0x0001
@@ -1644,7 +2313,7 @@
 #define PNG_EXPAND             0x1000
 #define PNG_GAMMA              0x2000
 #define PNG_GRAY_TO_RGB        0x4000
-#define PNG_FILLER             0x8000
+#define PNG_FILLER             0x8000L
 #define PNG_PACKSWAP          0x10000L
 #define PNG_SWAP_ALPHA        0x20000L
 #define PNG_STRIP_ALPHA       0x40000L
@@ -1677,12 +2346,18 @@
 #define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200
 #define PNG_FLAG_CRC_CRITICAL_USE         0x0400
 #define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800
-#define PNG_FLAG_FREE_PALETTE             0x1000
-#define PNG_FLAG_FREE_TRANS               0x2000
+#define PNG_FLAG_FREE_PLTE                0x1000
+#define PNG_FLAG_FREE_TRNS                0x2000
 #define PNG_FLAG_FREE_HIST                0x4000
-#define PNG_FLAG_HAVE_CHUNK_HEADER        0x8000L
-#define PNG_FLAG_WROTE_tIME              0x10000L
-#define PNG_FLAG_BACKGROUND_IS_GRAY      0x20000L
+#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000L
+#define PNG_FLAG_KEEP_UNSAFE_CHUNKS       0x10000L
+#define PNG_FLAG_LIBRARY_MISMATCH         0x20000L
+
+/* For use in png_set_keep_unknown, png_handle_as_unknown */
+#define HANDLE_CHUNK_AS_DEFAULT   0
+#define HANDLE_CHUNK_NEVER        1
+#define HANDLE_CHUNK_IF_SAFE      2
+#define HANDLE_CHUNK_ALWAYS       3
 
 #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
                                      PNG_FLAG_CRC_ANCILLARY_NOWARN)
@@ -1701,32 +2376,63 @@
 /* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
 #if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
 /* place to hold the signature string for a PNG file. */
-extern png_byte FARDATA png_sig[8];
+#ifdef PNG_USE_GLOBAL_ARRAYS
+   PNG_EXPORT_VAR (const png_byte FARDATA) png_sig[8];
+#else
+#define png_sig png_sig_bytes(NULL)
+#endif
+#endif /* PNG_NO_EXTERN */
 
 /* Constant strings for known chunk types.  If you need to add a chunk,
- * add a string holding the name here.  See png.c for more details.  We
- * can't selectively include these, since we still check for chunk in the
- * wrong locations with these labels.
- */
-extern png_byte FARDATA png_IHDR[5];
-extern png_byte FARDATA png_IDAT[5];
-extern png_byte FARDATA png_IEND[5];
-extern png_byte FARDATA png_PLTE[5];
-extern png_byte FARDATA png_bKGD[5];
-extern png_byte FARDATA png_cHRM[5];
-extern png_byte FARDATA png_gAMA[5];
-extern png_byte FARDATA png_hIST[5];
-extern png_byte FARDATA png_oFFs[5];
-extern png_byte FARDATA png_pCAL[5];
-extern png_byte FARDATA png_pHYs[5];
-extern png_byte FARDATA png_sBIT[5];
-extern png_byte FARDATA png_sRGB[5];
-extern png_byte FARDATA png_tEXt[5];
-extern png_byte FARDATA png_tIME[5];
-extern png_byte FARDATA png_tRNS[5];
-extern png_byte FARDATA png_zTXt[5];
+ * define the name here, and add an invocation of the macro in png.c and
+ * wherever it's needed.
+ */
+#define PNG_IHDR const png_byte png_IHDR[5] = { 73,  72,  68,  82, '\0'}
+#define PNG_IDAT const png_byte png_IDAT[5] = { 73,  68,  65,  84, '\0'}
+#define PNG_IEND const png_byte png_IEND[5] = { 73,  69,  78,  68, '\0'}
+#define PNG_PLTE const png_byte png_PLTE[5] = { 80,  76,  84,  69, '\0'}
+#define PNG_bKGD const png_byte png_bKGD[5] = { 98,  75,  71,  68, '\0'}
+#define PNG_cHRM const png_byte png_cHRM[5] = { 99,  72,  82,  77, '\0'}
+#define PNG_gAMA const png_byte png_gAMA[5] = {103,  65,  77,  65, '\0'}
+#define PNG_hIST const png_byte png_hIST[5] = {104,  73,  83,  84, '\0'}
+#define PNG_iCCP const png_byte png_iCCP[5] = {105,  67,  67,  80, '\0'}
+#define PNG_iTXt const png_byte png_iTXt[5] = {105,  84,  88, 116, '\0'}
+#define PNG_oFFs const png_byte png_oFFs[5] = {111,  70,  70, 115, '\0'}
+#define PNG_pCAL const png_byte png_pCAL[5] = {112,  67,  65,  76, '\0'}
+#define PNG_sCAL const png_byte png_sCAL[5] = {115,  67,  65,  76, '\0'}
+#define PNG_pHYs const png_byte png_pHYs[5] = {112,  72,  89, 115, '\0'}
+#define PNG_sBIT const png_byte png_sBIT[5] = {115,  66,  73,  84, '\0'}
+#define PNG_sPLT const png_byte png_sPLT[5] = {115,  80,  76,  84, '\0'}
+#define PNG_sRGB const png_byte png_sRGB[5] = {115,  82,  71,  66, '\0'}
+#define PNG_tEXt const png_byte png_tEXt[5] = {116,  69,  88, 116, '\0'}
+#define PNG_tIME const png_byte png_tIME[5] = {116,  73,  77,  69, '\0'}
+#define PNG_tRNS const png_byte png_tRNS[5] = {116,  82,  78,  83, '\0'}
+#define PNG_zTXt const png_byte png_zTXt[5] = {122,  84,  88, 116, '\0'}
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+PNG_EXPORT_VAR (const png_byte FARDATA) png_IHDR[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_IDAT[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_IEND[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_PLTE[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_bKGD[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_cHRM[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_gAMA[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_hIST[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_iCCP[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_iTXt[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_oFFs[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_pCAL[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sCAL[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_pHYs[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sBIT[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sPLT[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sRGB[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_tEXt[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_tIME[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_tRNS[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_zTXt[5];
+#endif /* PNG_USE_GLOBAL_ARRAYS */
 
-#endif /* PNG_NO_EXTERN */
 
 /* Inline macros to do direct reads of bytes from the input buffer.  These
  * require that you are using an architecture that uses PNG byte ordering
@@ -1737,33 +2443,43 @@
  * values, which is almost certainly true.
  */
 #if defined(PNG_READ_BIG_ENDIAN_SUPPORTED)
-#if defined(PNG_READ_pCAL_SUPPORTED)
-#define png_get_int_32(buf) ( *((png_int_32p) (buf)))
-#endif /* PNG_READ_pCAL_SUPPORTED */
-#define png_get_uint_32(buf) ( *((png_uint_32p) (buf)))
-#define png_get_uint_16(buf) ( *((png_uint_16p) (buf)))
+#  if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED)
+#    define png_get_int_32(buf) ( *((png_int_32p) (buf)))
+#  endif
+#  define png_get_uint_32(buf) ( *((png_uint_32p) (buf)))
+#  define png_get_uint_16(buf) ( *((png_uint_16p) (buf)))
 #else
-#if defined(PNG_READ_pCAL_SUPPORTED)
+#  if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED)
 PNG_EXTERN png_int_32 png_get_int_32 PNGARG((png_bytep buf));
-#endif /* PNG_READ_pCAL_SUPPORTED */
+#  endif
 PNG_EXTERN png_uint_32 png_get_uint_32 PNGARG((png_bytep buf));
 PNG_EXTERN png_uint_16 png_get_uint_16 PNGARG((png_bytep buf));
-#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
+#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */
 
 /* Initialize png_ptr struct for reading, and allocate any other memory.
- * (old interface - NOT DLL EXPORTED).
+ * (old interface - DEPRECATED - use png_create_read_struct instead).
  */
-extern void png_read_init PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr));
+#define png_read_init(png_ptr) png_read_init_2(png_ptr, \
+    PNG_LIBPNG_VER_STRING,  sizeof(png_struct), sizeof(png_info));
+extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr,
+    png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
+    png_info_size));
 
 /* Initialize png_ptr struct for writing, and allocate any other memory.
- * (old interface - NOT DLL EXPORTED).
+ * (old interface - DEPRECATED - use png_create_write_struct instead).
  */
-extern void png_write_init PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr));
+#define png_write_init(png_ptr) png_write_init_2(png_ptr, \
+    PNG_LIBPNG_VER_STRING, sizeof(png_struct), sizeof(png_info));
+extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr,
+    png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
+    png_info_size));
 
-/* allocate memory for an internal libpng struct */
+/* Allocate memory for an internal libpng struct */
 PNG_EXTERN png_voidp png_create_struct PNGARG((int type));
 
-/* free memory from internal libpng struct */
+/* Free memory from internal libpng struct */
 PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr));
 
 PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr
@@ -1771,17 +2487,17 @@
 PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr,
    png_free_ptr free_fn));
 
-/* free any memory that info_ptr points to and reset struct. */
+/* Free any memory that info_ptr points to and reset struct. */
 PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
    png_infop info_ptr));
 
 /* Function to allocate memory for zlib. */
 PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size));
 
-/* function to free memory for zlib */
+/* Function to free memory for zlib */
 PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr));
 
-/* reset the CRC variable */
+/* Reset the CRC variable */
 PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr));
 
 /* Write the "data" buffer to whatever output you are using. */
@@ -1792,14 +2508,22 @@
 PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
    png_size_t length));
 
-/* read bytes into buf, and update png_ptr->crc */
+/* Read bytes into buf, and update png_ptr->crc */
 PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
    png_size_t length));
 
-/* read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
+/* Decompress data in a chunk that uses compression */
+#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
+    defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_sPLT_SUPPORTED)
+PNG_EXTERN png_charp png_decompress_chunk PNGARG((png_structp png_ptr,
+   int comp_type, png_charp chunkdata, png_size_t chunklength,
+   png_size_t prefix_length, png_size_t *data_length));
+#endif
+
+/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
 PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip));
 
-/* read the CRC from the file and compare it to the libpng calculated CRC */
+/* Read the CRC from the file and compare it to the libpng calculated CRC */
 PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr));
 
 /* Calculate the CRC over a section of data.  Note that we are only
@@ -1823,7 +2547,7 @@
 PNG_EXTERN void png_save_int_32 PNGARG((png_bytep buf, png_int_32 i));
 #endif
 
-/* Place a 16 bit number into a buffer in PNG byte order.
+/* Place a 16-bit number into a buffer in PNG byte order.
  * The parameter is declared unsigned int, not png_uint_16,
  * just to avoid potential problems on pre-ANSI C compilers.
  */
@@ -1839,8 +2563,8 @@
  */
 PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width,
    png_uint_32 height,
-   int bit_depth, int color_type, int compression_type, int filter_type,
-   int interlace_type));
+   int bit_depth, int color_type, int compression_method, int filter_method,
+   int interlace_method));
 
 PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette,
    png_uint_32 num_pal));
@@ -1851,8 +2575,14 @@
 PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr));
 
 #if defined(PNG_WRITE_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
 PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma));
 #endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, png_fixed_point
+    file_gamma));
+#endif
+#endif
 
 #if defined(PNG_WRITE_sBIT_SUPPORTED)
 PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit,
@@ -1860,17 +2590,38 @@
 #endif
 
 #if defined(PNG_WRITE_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
 PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr,
    double white_x, double white_y,
    double red_x, double red_y, double green_x, double green_y,
    double blue_x, double blue_y));
 #endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr,
+   png_fixed_point int_white_x, png_fixed_point int_white_y,
+   png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
+   int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
+   png_fixed_point int_blue_y));
+#endif
+#endif
 
 #if defined(PNG_WRITE_sRGB_SUPPORTED)
 PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr,
    int intent));
 #endif
 
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr,
+   png_charp name, int compression_type,
+   png_charp profile, int proflen));
+   /* Note to maintainer: profile should be png_bytep */
+#endif
+
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr,
+   png_sPLT_tp palette));
+#endif
+
 #if defined(PNG_WRITE_tRNS_SUPPORTED)
 PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans,
    png_color_16p values, int number, int color_type));
@@ -1886,8 +2637,8 @@
    int num_hist));
 #endif
 
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) || \
-    defined(PNG_WRITE_pCAL_SUPPORTED)
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
 PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
    png_charp key, png_charpp new_key));
 #endif
@@ -1902,6 +2653,12 @@
    png_charp text, png_size_t text_len, int compression));
 #endif
 
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr,
+   int compression, png_charp key, png_charp lang, png_charp lang_key,
+   png_charp text));
+#endif
+
 #if defined(PNG_WRITE_oFFs_SUPPORTED)
 PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
    png_uint_32 x_offset, png_uint_32 y_offset, int unit_type));
@@ -1924,6 +2681,18 @@
    png_timep mod_time));
 #endif
 
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
+PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr,
+   int unit, double width, double height));
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr,
+   int unit, png_charp width, png_charp height));
+#endif
+#endif
+#endif
+
 /* Called when finished processing a row of data */
 PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
 
@@ -1940,10 +2709,15 @@
 
 #if defined(PNG_READ_INTERLACING_SUPPORTED)
 /* expand an interlaced row */
+/* OLD interface:
 PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
    png_bytep row, int pass, png_uint_32 transformations));
+ */
+PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr));
 #endif
 
+/* GRR TO DO (2.0 or whenever):  simplify other internal calling interfaces */
+
 #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
 /* grab pixels out of a row for an interlaced pass */
 PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
@@ -2095,13 +2869,8 @@
 PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr,
    png_uint_32 length));
 
-#if defined(PNG_READ_gAMA_SUPPORTED)
-PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
-   png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_sBIT_SUPPORTED)
-PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
+#if defined(PNG_READ_bKGD_SUPPORTED)
+PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
    png_uint_32 length));
 #endif
 
@@ -2110,23 +2879,23 @@
    png_uint_32 length));
 #endif
 
-#if defined(PNG_READ_sRGB_SUPPORTED)
-PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
+#if defined(PNG_READ_gAMA_SUPPORTED)
+PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
    png_uint_32 length));
 #endif
 
-#if defined(PNG_READ_tRNS_SUPPORTED)
-PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
+#if defined(PNG_READ_hIST_SUPPORTED)
+PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
    png_uint_32 length));
 #endif
 
-#if defined(PNG_READ_bKGD_SUPPORTED)
-PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
+#if defined(PNG_READ_iCCP_SUPPORTED)
+extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
    png_uint_32 length));
-#endif
+#endif /* PNG_READ_iCCP_SUPPORTED */
 
-#if defined(PNG_READ_hIST_SUPPORTED)
-PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
+#if defined(PNG_READ_iTXt_SUPPORTED)
+PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
    png_uint_32 length));
 #endif
 
@@ -2145,8 +2914,23 @@
    png_uint_32 length));
 #endif
 
-#if defined(PNG_READ_tIME_SUPPORTED)
-PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
+#if defined(PNG_READ_sBIT_SUPPORTED)
+PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_sCAL_SUPPORTED)
+PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_sPLT_SUPPORTED)
+extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
    png_uint_32 length));
 #endif
 
@@ -2155,11 +2939,26 @@
    png_uint_32 length));
 #endif
 
+#if defined(PNG_READ_tIME_SUPPORTED)
+PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_tRNS_SUPPORTED)
+PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
 #if defined(PNG_READ_zTXt_SUPPORTED)
 PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
    png_uint_32 length));
 #endif
 
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+PNG_EXTERN int png_handle_as_unknown PNGARG((png_structp png_ptr, png_bytep
+   chunk_name));
+#endif
+
 PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_32 length));
 
@@ -2214,14 +3013,30 @@
 PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
    png_infop info_ptr));
 #endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+#endif
 
 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
 
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info,
+   png_bytep row));
+PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info,
+   png_bytep row));
+#endif
+
+/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
+
 #endif /* PNG_INTERNAL */
 
 #ifdef __cplusplus
 }
 #endif
 
+#endif /* PNG_VERSION_INFO_ONLY */
 /* do not put anything past this line */
-#endif /* _PNG_H */
+#endif /* PNG_H */

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/libpng.3
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/libpng.3	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/libpng.3	Sat Jul 13 21:26:47 2002
@@ -1,416 +1,740 @@
-.TH LIBPNG 3 "January 14, 1999"
+.TH LIBPNG 3 "January 31, 2001"
 .SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.0.3 - January 14, 1999
+libpng \- Portable Network Graphics (PNG) Reference Library 1.0.9
 .SH SYNOPSIS
+\fI\fB
 
-#include <png.h>
+\fB#include <png.h>\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_access_version_number \fI(void\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_check_sig (png_bytep \fP\fIsig\fP\fB, int \fInum\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_chunk_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_chunk_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_convert_from_struct_tm (png_timep \fP\fIptime\fP\fB, struct tm FAR * \fIttime\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_convert_from_time_t (png_timep \fP\fIptime\fP\fB, time_t \fIttime\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_charp png_convert_to_rfc1123 (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fIptime\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_infop png_create_info_struct (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_read_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_read_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_write_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_write_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug(int \fP\fIlevel\fP\fB, png_const_charp \fImessage\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug1(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fIp1\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug2(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fP\fIp1\fP\fB, \fIp2\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_info_struct (png_structp \fP\fIpng_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_read_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fP\fIinfo_ptr_ptr\fP\fB, png_infopp \fIend_info_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_write_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free_chunk_list (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free_default(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fInum\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_bit_depth (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fI*background\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_channels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fI*white_x\fP\fB, double \fP\fI*white_y\fP\fB, double \fP\fI*red_x\fP\fB, double \fP\fI*red_y\fP\fB, double \fP\fI*green_x\fP\fB, double \fP\fI*green_y\fP\fB, double \fP\fI*blue_x\fP\fB, double \fI*blue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*white_x\fP\fB, png_uint_32 \fP\fI*white_y\fP\fB, png_uint_32 \fP\fI*red_x\fP\fB, png_uint_32 \fP\fI*red_y\fP\fB, png_uint_32 \fP\fI*green_x\fP\fB, png_uint_32 \fP\fI*green_y\fP\fB, png_uint_32 \fP\fI*blue_x\fP\fB, png_uint_32 \fI*blue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_color_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_compression_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_copyright (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_error_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_filter_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fI*file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fI*int_file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_header_ver (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_header_version (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fI*hist\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charpp \fP\fIname\fP\fB, int \fP\fI*compression_type\fP\fB, png_charpp \fP\fIprofile\fP\fB, png_uint_32 \fI*proflen\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*width\fP\fB, png_uint_32 \fP\fI*height\fP\fB, int \fP\fI*bit_depth\fP\fB, int \fP\fI*color_type\fP\fB, int \fP\fI*interlace_type\fP\fB, int \fP\fI*compression_type\fP\fB, int \fI*filter_type\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_image_height (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_image_width (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_interlace_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_io_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_libpng_ver (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_mem_ptr(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*offset_x\fP\fB, png_uint_32 \fP\fI*offset_y\fP\fB, int \fI*unit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fI*purpose\fP\fB, png_int_32 \fP\fI*X0\fP\fB, png_int_32 \fP\fI*X1\fP\fB, int \fP\fI*type\fP\fB, int \fP\fI*nparams\fP\fB, png_charp \fP\fI*units\fP\fB, png_charpp \fI*params\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*res_x\fP\fB, png_uint_32 \fP\fI*res_y\fP\fB, int \fI*unit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBfloat png_get_pixel_aspect_ratio (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_progressive_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fI*palette\fP\fB, int \fI*num_palette\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_rgb_to_gray_status (png_structp \fIpng_ptr)
+
+\fBpng_uint_32 png_get_rowbytes (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_bytepp png_get_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fI*sig_bit\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_bytep png_get_signature (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fI*splt_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fI*intent\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fI*text_ptr\fP\fB, int \fI*num_text\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fI*mod_time\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fI*trans\fP\fB, int \fP\fI*num_trans\fP\fB, png_color_16p \fI*trans_values\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkpp \fIunknowns\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_user_chunk_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_user_transform_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_valid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIflag\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_x_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_x_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_x_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_y_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_y_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_y_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_compression_buffer_size (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_info_init (png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_init_io (png_structp \fP\fIpng_ptr\fP\fB, FILE \fI*fp\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_malloc (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_malloc_default(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoidp png_memcpy (png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_size_t \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_memcpy_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoidp png_memset (png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_size_t \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_memset_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_permit_empty_plte (png_structp \fP\fIpng_ptr\fP\fB, int \fIempty_plte_permitted\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_process_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_size\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_progressive_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIold_row\fP\fB, png_bytep \fInew_row\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_infop \fIend_info_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_read_init (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_read_init_2 (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP
+
+\fBvoid png_read_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fIdisplay_row\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_bytepp \fP\fIdisplay_row\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_update_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_background (png_structp \fP\fIpng_ptr\fP\fB, png_color_16p \fP\fIbackground_color\fP\fB, int \fP\fIbackground_gamma_code\fP\fB, int \fP\fIneed_expand\fP\fB, double \fIbackground_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_bgr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fIbackground\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwhite_x\fP\fB, png_uint_32 \fP\fIwhite_y\fP\fB, png_uint_32 \fP\fIred_x\fP\fB, png_uint_32 \fP\fIred_y\fP\fB, png_uint_32 \fP\fIgreen_x\fP\fB, png_uint_32 \fP\fIgreen_y\fP\fB, png_uint_32 \fP\fIblue_x\fP\fB, png_uint_32 \fIblue_y\fP\fB);\fP
 
-int png_check_sig (png_bytep sig, int num);
+\fI\fB
 
-void png_chunk_error (png_structp png_ptr, png_const_charp
-error);
+\fBvoid png_set_compression_level (png_structp \fP\fIpng_ptr\fP\fB, int \fIlevel\fP\fB);\fP
 
-void png_chunk_warning (png_structp png_ptr, png_const_charp
-message);
+\fI\fB
 
-void png_convert_from_struct_tm (png_timep ptime, struct tm FAR
-* ttime);
+\fBvoid png_set_compression_mem_level (png_structp \fP\fIpng_ptr\fP\fB, int \fImem_level\fP\fB);\fP
 
-void png_convert_from_time_t (png_timep ptime, time_t ttime);
+\fI\fB
 
-png_charp png_convert_to_rfc1123 (png_structp png_ptr,
-png_timep ptime);
+\fBvoid png_set_compression_method (png_structp \fP\fIpng_ptr\fP\fB, int \fImethod\fP\fB);\fP
 
-png_infop png_create_info_struct (png_structp png_ptr);
+\fI\fB
 
-png_structp png_create_read_struct (png_const_charp
-user_png_ver, voidp error_ptr, png_error_ptr error_fn,
-png_error_ptr warn_fn);
+\fBvoid png_set_compression_strategy (png_structp \fP\fIpng_ptr\fP\fB, int \fIstrategy\fP\fB);\fP
 
-png_structp png_create_read_struct_2(png_const_charp user_png_ver,
-png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr
-warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn,
-png_free_ptr free_fn)
+\fI\fB
 
-png_structp png_create_write_struct (png_const_charp
-user_png_ver, voidp error_ptr, png_error_ptr error_fn,
-png_error_ptr warn_fn);
+\fBvoid png_set_compression_window_bits (png_structp \fP\fIpng_ptr\fP\fB, int \fIwindow_bits\fP\fB);\fP
 
-png_structp png_create_write_struct_2(png_const_charp
-user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
-png_error_ptr warn_fn, png_voidp mem_ptr,
-png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+\fI\fB
 
-int png_debug(int level, png_const_charp message)
+\fBvoid png_set_crc_action (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcrit_action\fP\fB, int \fIancil_action\fP\fB);\fP
 
-int png_debug1(int level, png_const_charp message, p1)
+\fI\fB
 
-int png_debug2(int level, png_const_charp message, p1, p2)
+\fBvoid png_set_dither (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fP\fInum_palette\fP\fB, int \fP\fImaximum_colors\fP\fB, png_uint_16p \fP\fIhistogram\fP\fB, int \fIfull_dither\fP\fB);\fP
 
-void png_destroy_info_struct (png_structp png_ptr, png_infopp
-info_ptr_ptr);
+\fI\fB
 
-void png_destroy_read_struct (png_structpp png_ptr_ptr,
-png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr);
+\fBvoid png_set_error_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarning_fn\fP\fB);\fP
 
-void png_destroy_write_struct (png_structpp png_ptr_ptr,
-png_infopp info_ptr_ptr);
+\fI\fB
 
-void png_error (png_structp png_ptr, png_const_charp error);
+\fBvoid png_set_expand (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_free (png_structp png_ptr, png_voidp ptr);
+\fI\fB
 
-void png_free_default(png_structp png_ptr, png_voidp ptr)
+\fBvoid png_set_filler (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP
 
-png_byte png_get_bit_depth (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-png_uint_32 png_get_bKGD (png_structp png_ptr, png_infop
-info_ptr, png_color_16p *background);
+\fBvoid png_set_filter (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fImethod\fP\fB, int \fIfilters\fP\fB);\fP
 
-png_byte png_get_channels (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-png_uint_32 png_get_cHRM (png_structp png_ptr, png_infop
-info_ptr, double *white_x, double *white_y, double *red_x,
-double *red_y, double *green_x, double *green_y, double
-*blue_x, double *blue_y);
+\fBvoid png_set_filter_heuristics (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIheuristic_method\fP\fB, int \fP\fInum_weights\fP\fB, png_doublep \fP\fIfilter_weights\fP\fB, png_doublep \fIfilter_costs\fP\fB);\fP
 
-png_byte png_get_color_type (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-png_byte png_get_compression_type (png_structp png_ptr,
-png_infop info_ptr);
+\fBvoid png_set_flush (png_structp \fP\fIpng_ptr\fP\fB, int \fInrows\fP\fB);\fP
 
-png_byte png_get_copyright (png_structp png_ptr);
+\fI\fB
 
-png_voidp png_get_error_ptr (png_structp png_ptr);
+\fBvoid png_set_gamma (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIscreen_gamma\fP\fB, double \fIdefault_file_gamma\fP\fB);\fP
 
-png_byte png_get_filter_type (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-png_uint_32 png_get_gAMA (png_structp png_ptr, png_infop
-info_ptr, double *file_gamma);
+\fBvoid png_set_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP
 
-png_byte png_get_header_version (png_structp png_ptr);
+\fI\fB
 
-png_uint_32 png_get_hIST (png_structp png_ptr, png_infop
-info_ptr, png_uint_16p *hist);
+\fBvoid png_set_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIfile_gamma\fP\fB);\fP
 
-png_uint_32 png_get_IHDR (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 *width, png_uint_32 *height, int
-*bit_depth, int *color_type, int *interlace_type, int
-*compression_type, int *filter_type);
+\fI\fB
 
-png_uint_32 png_get_image_height (png_structp png_ptr,
-png_infop info_ptr);
+\fBvoid png_set_gray_1_2_4_to_8(png_structp \fIpng_ptr\fP\fB);\fP
 
-png_uint_32 png_get_image_width (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-png_byte png_get_interlace_type (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_set_gray_to_rgb (png_structp \fIpng_ptr\fP\fB);\fP
 
-png_voidp png_get_io_ptr (png_structp png_ptr);
+\fI\fB
 
-png_voidp png_get_mem_ptr(png_structp png_ptr)
+\fBvoid png_set_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fIhist\fP\fB);\fP
 
-png_uint_32 png_get_oFFs (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 *offset_x, png_uint_32 *offset_y, int
-*unit_type);
+\fI\fB
 
-png_uint_32 png_get_pCAL (png_structp png_ptr, png_infop
-info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
-int *type, int *nparams, png_charp *units, png_charpp *params);
+\fBvoid png_set_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_charp \fP\fIprofile\fP\fB, png_uint_32 \fIproflen\fP\fB);\fP
 
-png_uint_32 png_get_pHYs (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int
-*unit_type);
+\fI\fB
 
-float png_get_pixel_aspect_ratio (png_structp png_ptr,
-png_infop info_ptr);
+\fBint png_set_interlace_handling (png_structp \fIpng_ptr\fP\fB);\fP
 
-png_uint_32 png_get_pixels_per_meter (png_structp png_ptr,
-png_infop info_ptr);
+\fI\fB
 
-png_voidp png_get_progressive_ptr (png_structp png_ptr);
+\fBvoid png_set_invalid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fImask\fP\fB);\fP
 
-png_uint_32 png_get_PLTE (png_structp png_ptr, png_infop
-info_ptr, png_colorp *palette, int *num_palette);
+\fI\fB
 
-png_byte png_get_rgb_to_gray_status (png_structp png_ptr)
+\fBvoid png_set_invert_alpha (png_structp \fIpng_ptr\fP\fB);\fP
 
-png_uint_32 png_get_rowbytes (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-png_uint_32 png_get_sBIT (png_structp png_ptr, png_infop
-info_ptr, png_color_8p *sig_bit);
+\fBvoid png_set_invert_mono (png_structp \fIpng_ptr\fP\fB);\fP
 
-png_bytep png_get_signature (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-png_uint_32 png_get_sRGB (png_structp png_ptr, png_infop
-info_ptr, int *intent);
+\fBvoid png_set_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIinterlace_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fIfilter_type\fP\fB);\fP
 
-png_uint_32 png_get_text (png_structp png_ptr, png_infop
-info_ptr, png_textp *text_ptr, int *num_text);
+\fI\fB
 
-png_uint_32 png_get_tIME (png_structp png_ptr, png_infop
-info_ptr, png_timep *mod_time);
+\fBvoid png_set_keep_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIkeep\fP\fB, png_bytep \fP\fIchunk_list\fP\fB, int \fInum_chunks\fP\fB);\fP
 
-png_uint_32 png_get_tRNS (png_structp png_ptr, png_infop
-info_ptr, png_bytep *trans, int *num_trans, png_color_16p
-*trans_values);
+\fI\fB
 
-png_uint_32 png_get_valid (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 flag);
+\fBvoid png_set_mem_fn(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
 
-png_uint_32 png_get_x_offset_microns (png_structp png_ptr,
-png_infop info_ptr);
+\fI\fB
 
-png_uint_32 png_get_x_offset_pixels (png_structp png_ptr,
-png_infop info_ptr);
+\fBvoid png_set_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIoffset_x\fP\fB, png_uint_32 \fP\fIoffset_y\fP\fB, int \fIunit_type\fP\fB);\fP
 
-png_uint_32 png_get_x_pixels_per_meter (png_structp png_ptr,
-png_infop info_ptr);
+\fI\fB
 
-png_uint_32 png_get_y_offset_microns (png_structp png_ptr,
-png_infop info_ptr);
+\fBvoid png_set_packing (png_structp \fIpng_ptr\fP\fB);\fP
 
-png_uint_32 png_get_y_offset_pixels (png_structp png_ptr,
-png_infop info_ptr);
+\fI\fB
 
-png_uint_32 png_get_y_pixels_per_meter (png_structp png_ptr,
-png_infop info_ptr);
+\fBvoid png_set_packswap (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_info_init (png_infop info_ptr);
+\fI\fB
 
-void png_init_io (png_structp png_ptr, FILE *fp);
+\fBvoid png_set_palette_to_rgb(png_structp \fIpng_ptr\fP\fB);\fP
 
-png_voidp png_malloc (png_structp png_ptr, png_uint_32 size);
+\fI\fB
 
-png_voidp png_malloc_default(png_structp png_ptr,
-png_uint_32 size)
+\fBvoid png_set_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP
 
-voidp png_memcpy (png_voidp s1, png_voidp s2, png_size_t size);
+\fI\fB
 
-png_voidp png_memcpy_check (png_structp png_ptr, png_voidp s1,
-png_voidp s2, png_uint_32 size);
+\fBvoid png_set_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIres_x\fP\fB, png_uint_32 \fP\fIres_y\fP\fB, int \fIunit_type\fP\fB);\fP
 
-voidp png_memset (png_voidp s1, int value, png_size_t size);
+\fI\fB
 
-png_voidp png_memset_check (png_structp png_ptr, png_voidp
-s1, int value, png_uint_32 size);
+\fBvoid png_set_progressive_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIprogressive_ptr\fP\fB, png_progressive_info_ptr \fP\fIinfo_fn\fP\fB, png_progressive_row_ptr \fP\fIrow_fn\fP\fB, png_progressive_end_ptr \fIend_fn\fP\fB);\fP
 
-void png_process_data (png_structp png_ptr, png_infop info_ptr,
-png_bytep buffer, png_size_t buffer_size);
+\fI\fB
 
-void png_progressive_combine_row (png_structp png_ptr,
-png_bytep old_row, png_bytep new_row);
+\fBvoid png_set_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP
 
-void png_read_destroy (png_structp png_ptr, png_infop info_ptr,
-png_infop end_info_ptr);
+\fI\fB
 
-void png_read_end (png_structp png_ptr, png_infop info_ptr);
+\fBvoid png_set_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fIread_data_fn\fP\fB);\fP
 
-void png_read_image (png_structp png_ptr, png_bytepp image);
+\fI\fB
 
-void png_read_info (png_structp png_ptr, png_infop info_ptr);
+\fBvoid png_set_read_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_read_status_ptr \fIread_row_fn\fP\fB);\fP
 
-void png_read_row (png_structp png_ptr, png_bytep row,
-png_bytep display_row);
+\fI\fB
 
-void png_read_rows (png_structp png_ptr, png_bytepp row,
-png_bytepp display_row, png_uint_32 num_rows);
+\fBvoid png_set_read_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIread_user_transform_fn\fP\fB);\fP
 
-void png_read_update_info (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-void png_set_background (png_structp png_ptr, png_color_16p
-background_color, int background_gamma_code, int need_expand,
-double background_gamma);
+\fBvoid png_set_rgb_to_gray (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIerror_action\fP\fB, double \fP\fIred\fP\fB, double \fIgreen\fP\fB);\fP
 
-void png_set_bgr (png_structp png_ptr);
+\fI\fB
 
-void png_set_bKGD (png_structp png_ptr, png_infop info_ptr,
-png_color_16p background);
+\fBvoid png_set_rgb_to_gray_fixed (png_structp \fP\fIpng_ptr\fP\fB, int error_action png_fixed_point \fP\fIred\fP\fB, png_fixed_point \fIgreen\fP\fB);\fP
 
-void png_set_cHRM (png_structp png_ptr, png_infop info_ptr,
-double white_x, double white_y, double red_x, double red_y,
-double green_x, double green_y, double blue_x, double blue_y);
+\fI\fB
 
-void png_set_compression_level (png_structp png_ptr, int
-level);
+\fBvoid png_set_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytepp \fIrow_pointers\fP\fB);\fP
 
-void png_set_compression_mem_level (png_structp png_ptr, int
-mem_level);
+\fI\fB
 
-void png_set_compression_method (png_structp png_ptr, int
-method);
+\fBvoid png_set_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fIsig_bit\fP\fB);\fP
 
-void png_set_compression_strategy (png_structp png_ptr, int
-strategy);
+\fI\fB
 
-void png_set_compression_window_bits (png_structp png_ptr, int
-window_bits);
+\fBvoid png_set_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, double \fP\fIwidth\fP\fB, double \fIheight\fP\fB);\fP
 
-void png_set_crc_action (png_structp png_ptr, int crit_action,
-int ancil_action);
+\fI\fB
 
-void png_set_dither (png_structp png_ptr, png_colorp palette,
-int num_palette, int maximum_colors, png_uint_16p histogram,
-int full_dither);
+\fBvoid png_set_shift (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fItrue_bits\fP\fB);\fP
 
-void png_set_error_fn (png_structp png_ptr, png_voidp
-error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn);
+\fI\fB
 
-void png_set_expand (png_structp png_ptr);
+\fBvoid png_set_sig_bytes (png_structp \fP\fIpng_ptr\fP\fB, int \fInum_bytes\fP\fB);\fP
 
-void png_set_filler (png_structp png_ptr, png_uint_32 filler,
-int flags);
+\fI\fB
 
-void png_set_filter (png_structp png_ptr, int method, int
-filters);
+\fBvoid png_set_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fP\fIsplt_ptr\fP\fB, int \fInum_spalettes\fP\fB);\fP
 
-void png_set_filter_heuristics (png_structp png_ptr, int
-heuristic_method, int num_weights, png_doublep filter_weights,
-png_doublep filter_costs);
+\fI\fB
 
-void png_set_flush (png_structp png_ptr, int nrows);
+\fBvoid png_set_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP
 
-void png_set_gamma (png_structp png_ptr, double screen_gamma,
-double default_file_gamma);
+\fI\fB
 
-void png_set_gAMA (png_structp png_ptr, png_infop info_ptr,
-double file_gamma);
+\fBvoid png_set_sRGB_gAMA_and_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP
 
-void png_set_gray_to_rgb (png_structp png_ptr);
+\fI\fB
 
-void png_set_hIST (png_structp png_ptr, png_infop info_ptr,
-png_uint_16p hist);
+\fBvoid png_set_strip_16 (png_structp \fIpng_ptr\fP\fB);\fP
 
-int png_set_interlace_handling (png_structp png_ptr);
+\fI\fB
 
-void png_set_invert_alpha (png_structp png_ptr);
+\fBvoid png_set_strip_alpha (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_set_invert_mono (png_structp png_ptr);
+\fI\fB
 
-void png_set_IHDR (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 width, png_uint_32 height, int bit_depth, int
-color_type, int interlace_type, int compression_type, int
-filter_type);
+\fBvoid png_set_swap (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr,
-png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+\fI\fB
 
-void png_set_oFFs (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 offset_x, png_uint_32 offset_y, int unit_type);
+\fBvoid png_set_swap_alpha (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_set_packing (png_structp png_ptr);
+\fI\fB
 
-void png_set_packswap (png_structp png_ptr);
+\fBvoid png_set_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fItext_ptr\fP\fB, int \fInum_text\fP\fB);\fP
 
-void png_set_pCAL (png_structp png_ptr, png_infop info_ptr,
-png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int
-nparams, png_charp units, png_charpp params);
+\fI\fB
 
-void png_set_pHYs (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 res_x, png_uint_32 res_y, int unit_type);
+\fBvoid png_set_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP
 
-void png_set_progressive_read_fn (png_structp png_ptr,
-png_voidp progressive_ptr, png_progressive_info_ptr info_fn,
-png_progressive_row_ptr row_fn, png_progressive_end_ptr
-end_fn);
+\fI\fB
 
-void png_set_PLTE (png_structp png_ptr, png_infop info_ptr,
-png_colorp palette, int num_palette);
+\fBvoid png_set_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fP\fInum_trans\fP\fB, png_color_16p \fItrans_values\fP\fB);\fP
 
-void png_set_read_fn (png_structp png_ptr, png_voidp io_ptr,
-png_rw_ptr read_data_fn);
+\fI\fB
 
-void png_set_read_status_fn (png_structp png_ptr, png_read_status_ptr
-read_row_fn);
+\fBvoid png_set_tRNS_to_alpha(png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_set_read_user_transform_fn (png_structp png_ptr,
-png_user_transform_ptr read_user_transform_fn);
+\fI\fB
 
-void png_set_rgb_to_gray (png_structp png_ptr, int error_action);
+\fBpng_uint_32 png_set_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkp \fP\fIunknowns\fP\fB, int \fP\fInum\fP\fB, int \fIlocation\fP\fB);\fP
 
-void png_set_sBIT (png_structp png_ptr, png_infop info_ptr,
-png_color_8p sig_bit);
+\fI\fB
 
-void png_set_shift (png_structp png_ptr, png_color_8p
-true_bits);
+\fBvoid png_set_unknown_chunk_location(png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fIchunk\fP\fB, int \fIlocation\fP\fB);\fP
 
-void png_set_sig_bytes (png_structp png_ptr, int num_bytes);
+\fI\fB
 
-void png_set_sRGB (png_structp png_ptr, png_infop info_ptr, int
-intent);
+\fBvoid png_set_read_user_chunk_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_chunk_ptr\fP\fB, png_user_chunk_ptr \fIread_user_chunk_fn\fP\fB);\fP
 
-void png_set_sRGB_gAMA_and_cHRM (png_structp png_ptr, png_infop
-info_ptr, int intent);
+\fI\fB
 
-void png_set_strip_16 (png_structp png_ptr);
+\fBvoid png_set_user_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_transform_ptr\fP\fB, int \fP\fIuser_transform_depth\fP\fB, int \fIuser_transform_channels\fP\fB);\fP
 
-void png_set_strip_alpha (png_structp png_ptr);
+\fI\fB
 
-void png_set_swap (png_structp png_ptr);
+\fBvoid png_set_write_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fP\fIwrite_data_fn\fP\fB, png_flush_ptr \fIoutput_flush_fn\fP\fB);\fP
 
-void png_set_swap_alpha (png_structp png_ptr);
+\fI\fB
 
-void png_set_text (png_structp png_ptr, png_infop info_ptr,
-png_textp text_ptr, int num_text);
+\fBvoid png_set_write_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_write_status_ptr \fIwrite_row_fn\fP\fB);\fP
 
-void png_set_tIME (png_structp png_ptr, png_infop info_ptr,
-png_timep mod_time);
+\fI\fB
 
-void png_set_tRNS (png_structp png_ptr, png_infop info_ptr,
-png_bytep trans, int num_trans, png_color_16p trans_values);
+\fBvoid png_set_write_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIwrite_user_transform_fn\fP\fB);\fP
 
-void png_set_write_fn (png_structp png_ptr, png_voidp io_ptr,
-png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn);
+\fI\fB
 
-void png_set_write_status_fn (png_structp png_ptr, png_write_status_ptr
-write_row_fn);
+\fBvoid png_set_compression_buffer_size(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
 
-void png_set_write_user_transform_fn (png_structp png_ptr,
-png_user_transform_ptr write_user_transform_fn);
+\fI\fB
 
-int png_sig_cmp (png_bytep sig, png_size_t start, png_size_t
-num_to_check);
+\fBint png_sig_cmp (png_bytep \fP\fIsig\fP\fB, png_size_t \fP\fIstart\fP\fB, png_size_t \fInum_to_check\fP\fB);\fP
 
-void png_start_read_image (png_structp png_ptr);
+\fI\fB
 
-void png_warning (png_structp png_ptr, png_const_charp
-message);
+\fBvoid png_start_read_image (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_write_chunk (png_structp png_ptr, png_bytep
-chunk_name, png_bytep data, png_size_t length);
+\fI\fB
 
-void png_write_chunk_data (png_structp png_ptr, png_bytep data,
-png_size_t length);
+\fBvoid png_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP
 
-void png_write_chunk_end (png_structp png_ptr);
+\fI\fB
 
-void png_write_chunk_start (png_structp png_ptr, png_bytep
-chunk_name, png_uint_32 length);
+\fBvoid png_write_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
 
-void png_write_destroy (png_structp png_ptr);
+\fI\fB
 
-void png_write_destroy_info (png_infop info_ptr);
+\fBvoid png_write_chunk_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
 
-void png_write_end (png_structp png_ptr, png_infop info_ptr);
+\fI\fB
 
-void png_write_flush (png_structp png_ptr);
+\fBvoid png_write_chunk_end (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_write_image (png_structp png_ptr, png_bytepp image);
+\fI\fB
 
-void png_write_info (png_structp png_ptr, png_infop info_ptr);
+\fBvoid png_write_chunk_start (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_write_row (png_structp png_ptr, png_bytep row);
+\fI\fB
 
-void png_write_rows (png_structp png_ptr, png_bytepp row,
-png_uint_32 num_rows);
+\fBvoid png_write_destroy (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_destroy_info (png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_flush (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_write_init (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_write_init_2 (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_info_before_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP
+
+\fI\fB
 
 .SH DESCRIPTION
 The
@@ -423,10 +747,10 @@
 .SH LIBPNG.TXT
 libpng.txt - A description on how to use and modify libpng
 
- libpng version 1.0.3 - January 14, 1999
+ libpng version 1.0.9 - January 31, 2001
  Updated and distributed by Glenn Randers-Pehrson
- <randeg at alumni.rpi.edu>
- Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ <randeg at alum.rpi.edu>
+ Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson
  For conditions of distribution and use, see copyright
  notice in png.h.
 
@@ -442,8 +766,8 @@
  Schalnat, Group 42, Inc.
 
  Updated/rewritten per request in the libpng FAQ
- Copyright (c) 1995 Frank J. T. Wojcik
- December 18, 1995 && January 20, 1996
+ Copyright (c) 1995, 1996 Frank J. T. Wojcik
+ December 18, 1995 & January 20, 1996
 
 .SH I. Introduction
 
@@ -458,13 +782,21 @@
 
 Libpng was written as a companion to the PNG specification, as a way
 of reducing the amount of time and effort it takes to support the PNG
-file format in application programs.  The PNG specification is available
+file format in application programs.
+
+The PNG-1.2 specification is available at <http://www.libpng.org/pub/png>
+and at <ftp://ftp.uu.net/graphics/png/documents/>.
+
+The PNG-1.0 specification is available
 as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/> and as a
 W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some
 additional chunks are described in the special-purpose public chunks
-documents at <ftp://ftp.uu.net/graphics/png/documents/>.  Other information
+documents at <ftp://ftp.uu.net/graphics/png/documents/>.
+
+Other information
 about PNG, and the latest version of libpng, can be found at the PNG home
-page, <http://www.cdrom.com/pub/png/>.
+page, <http://www.libpng.org/pub/png/>
+and at <ftp://ftp.uu.net/graphics/png/>.
 
 Most users will not have to modify the library significantly; advanced
 users may want to modify it more.  All attempts were made to make it as
@@ -482,7 +814,7 @@
 
 Libpng uses zlib for its compression and decompression of PNG files.
 Further information about zlib, and the latest version of zlib, can
-be found at the zlib home page, <http://www.cdrom.com/pub/infozip/zlib/>.
+be found at the zlib home page, <http://www.info-zip.org/pub/infozip/zlib/>.
 The zlib compression utility is a general purpose utility that is
 useful for more than PNG files, and can be used without libpng.
 See the documentation delivered with zlib for more details.
@@ -507,9 +839,20 @@
 PNG file.  At one time, the fields of png_info were intended to be
 directly accessible to the user.  However, this tended to cause problems
 with applications using dynamically loaded libraries, and as a result
-a set of interface functions for png_info was developed.  The fields
-of png_info are still available for older applications, but it is
-suggested that applications use the new interfaces if at all possible.
+a set of interface functions for png_info (the png_get_*() and png_set_*()
+functions) was developed.  The fields of png_info are still available for
+older applications, but it is suggested that applications use the new
+interfaces if at all possible.
+
+Applications that do make direct access to the members of png_struct (except
+for png_ptr->jmpbuf) must be recompiled whenever the library is updated,
+and applications that make direct access to the members of png_info must
+be recompiled if they were compiled or loaded with libpng version 1.0.6,
+in which the members were in a different order.  In version 1.0.7, the
+members of the png_info structure reverted to the old order, as they were
+in versions 0.97c through 1.0.5.  Starting with version 2.0.0, both
+structures are going to be hidden, and the contents of the structures will
+only be accessible through the png_get/png_set functions.
 
 The png.h header file is an invaluable reference for programming with libpng.
 And while I'm on the topic, make sure you include the libpng header file:
@@ -518,22 +861,23 @@
 
 .SH III. Reading
 
-Reading PNG files:
-
 We'll now walk you through the possible functions to call when reading
-in a PNG file, briefly explaining the syntax and purpose of each one.
-See example.c and png.h for more detail.  While Progressive reading
-is covered in the next section, you will still need some of the
-functions discussed in this section to read a PNG file.
+in a PNG file sequentially, briefly explaining the syntax and purpose
+of each one.  See example.c and png.h for more detail.  While
+progressive reading is covered in the next section, you will still
+need some of the functions discussed in this section to read a PNG
+file.
+
+.SS Setup
 
 You will want to do the I/O initialization(*) before you get into libpng,
 so if it doesn't work, you don't have much to undo.  Of course, you
 will also want to insure that you are, in fact, dealing with a PNG
 file.  Libpng provides a simple check to see if a file is a PNG file.
-To use it, pass in the first 1 to 8 bytes of the file, and it will
-return true or false (1 or 0) depending on whether the bytes could be
-part of a PNG file.  Of course, the more bytes you pass in, the
-greater the accuracy of the prediction.
+To use it, pass in the first 1 to 8 bytes of the file to the function
+png_sig_cmp(), and it will return 0 if the bytes match the corresponding
+bytes of the PNG signature, or nonzero otherwise.  Of course, the more bytes
+you pass in, the greater the accuracy of the prediction.
 
 If you are intending to keep the file pointer open for use in libpng,
 you must ensure you don't read more than 8 bytes from the beginning
@@ -549,13 +893,13 @@
     FILE *fp = fopen(file_name, "rb");
     if (!fp)
     {
-        return;
+        return (ERROR);
     }
     fread(header, 1, number, fp);
     is_png = !png_sig_cmp(header, 0, number);
     if (!is_png)
     {
-        return;
+        return (NOT_PNG);
     }
 
 
@@ -567,19 +911,21 @@
 use by the error functions, if necessary (the pointer and functions can
 be NULL if the default error handlers are to be used).  See the section
 on Changes to Libpng below regarding the old initialization functions.
+The structure allocation functions quietly return NULL if they fail to
+create the structure, so your application should check for that.
 
     png_structp png_ptr = png_create_read_struct
        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
         user_error_fn, user_warning_fn);
     if (!png_ptr)
-        return;
+        return (ERROR);
 
     png_infop info_ptr = png_create_info_struct(png_ptr);
     if (!info_ptr)
     {
         png_destroy_read_struct(&png_ptr,
            (png_infopp)NULL, (png_infopp)NULL);
-        return;
+        return (ERROR);
     }
 
     png_infop end_info = png_create_info_struct(png_ptr);
@@ -587,7 +933,7 @@
     {
         png_destroy_read_struct(&png_ptr, &info_ptr,
           (png_infopp)NULL);
-        return;
+        return (ERROR);
     }
 
 If you want to use your own memory allocation routines,
@@ -606,24 +952,29 @@
 
 When libpng encounters an error, it expects to longjmp back
 to your routine.  Therefore, you will need to call setjmp and pass
-your png_ptr->jmpbuf.  If you read the file from different
+your png_jmpbuf(png_ptr).  If you read the file from different
 routines, you will need to update the jmpbuf field every time you enter
-a new routine that will call a png_ function.
+a new routine that will call a png_*() function.
 
 See your documentation of setjmp/longjmp for your compiler for more
-handling in the Customizing Libpng section below for more information on
-the libpng error handling.  If an error occurs, and libpng longjmp's
+information on setjmp/longjmp.  See the discussion on libpng error
+handling in the Customizing Libpng section below for more information
+on the libpng error handling.  If an error occurs, and libpng longjmp's
 back to your setjmp, you will want to call png_destroy_read_struct() to
 free any memory.
 
-    if (setjmp(png_ptr->jmpbuf))
+    if (setjmp(png_jmpbuf(png_ptr)))
     {
         png_destroy_read_struct(&png_ptr, &info_ptr,
            &end_info);
         fclose(fp);
-        return;
+        return (ERROR);
     }
 
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
 Now you need to set up the input code.  The default for libpng is to
 use the C function fread().  If you use this, you will need to pass a
 valid FILE * in the function png_init_io().  Be sure that the file is
@@ -640,12 +991,48 @@
 
     png_set_sig_bytes(png_ptr, number);
 
+.SS Setting up callback code
+
+You can set up a callback function to handle any unknown chunks in the
+input stream. You must supply the function
+
+    read_chunk_callback(png_ptr ptr,
+         png_unknown_chunkp chunk);
+    {
+       /* The unknown chunk structure contains your
+          chunk data: */
+           png_byte name[5];
+           png_byte *data;
+           png_size_t size;
+       /* Note that libpng has already taken care of the
+          CRC handling */
+
+       /* put your code here.  Return one of the following: */
+
+       return (-n); /* chunk had an error */
+       return (0); /* did not recognize */
+       return (n); /* success */
+    }
+
+(You can give your function another name that you like instead of
+"read_chunk_callback")
+
+To inform libpng about your function, use
+
+    png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr,
+        read_chunk_callback);
+
+This names not only the callback function, but also a user pointer that
+you can retrieve with
+
+    png_get_user_chunk_ptr(png_ptr);
+
 At this point, you can set up a callback function that will be
 called after each row has been read, which you can use to control
 a progress meter or the like.  It's demonstrated in pngtest.c.
 You must supply a function
 
-    void read_row_callback(png_ptr, png_uint_32 row, int pass);
+    void read_row_callback(png_ptr ptr, png_uint_32 row, int pass);
     {
       /* put your code here */
     }
@@ -656,44 +1043,111 @@
 
     png_set_read_status_fn(png_ptr, read_row_callback);
 
-In PNG files, the alpha channel in an image is the level of opacity.
-If you need the alpha channel in an image to be the level of transparency
-instead of opacity, you can invert the alpha channel (or the tRNS chunk
-data) after it's read, so that 0 is fully opaque and 255 (in 8-bit or
-paletted images) or 65535 (in 16-bit images) is fully transparent, with
+.SS Unknown-chunk handling
 
-    png_set_invert_alpha(png_ptr);
+Now you get to set the way the library processes unknown chunks in the
+input PNG stream. Both known and unknown chunks will be read.  Normal
+behavior is that known chunks will be parsed into information in
+various info_ptr members; unknown chunks will be discarded. To change
+this, you can call:
+
+    png_set_keep_unknown_chunks(png_ptr, info_ptr, keep,
+        chunk_list, num_chunks);
+    keep       - 0: do not keep
+                 1: keep only if safe-to-copy
+                 2: keep even if unsafe-to-copy
+    chunk_list - list of chunks affected (a byte string,
+                 five bytes per chunk, NULL or '\0' if
+                 num_chunks is 0)
+    num_chunks - number of chunks affected; if 0, all
+                 unknown chunks are affected
+
+Unknown chunks declared in this way will be saved as raw data onto a
+list of png_unknown_chunk structures.  If a chunk that is normally
+known to libpng is named in the list, it will be handled as unknown,
+according to the "keep" directive.  If a chunk is named in successive
+instances of png_set_keep_unknown_chunks(), the final instance will
+take precedence.
+
+.SS The high-level read interface
+
+At this point there are two ways to proceed; through the high-level
+read interface, or through a sequence of low-level read operations.
+You can use the high-level interface if (a) you are willing to read
+the entire image into memory, and (b) the input transformations
+you want to do are limited to the following set:
+
+    PNG_TRANSFORM_IDENTITY      No transformation
+    PNG_TRANSFORM_STRIP_16      Strip 16-bit samples to 8 bits
+    PNG_TRANSFORM_STRIP_ALPHA   Discard the alpha channel
+    PNG_TRANSFORM_PACKING       Expand 1, 2 and 4-bit samples to bytes
+    PNG_TRANSFORM_PACKSWAP      Change order of packed pixels to LSB first
+    PNG_TRANSFORM_EXPAND        Perform set_expand()
+    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
+    PNG_TRANSFORM_SHIFT         Normalize pixels to the sBIT depth
+    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA to BGRA
+    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA to AG
+    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity to transparency
+    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples
+
+(This excludes setting a background color, doing gamma transformation,
+dithering, and setting filler.)  If this is the case, simply do this:
+
+    png_read_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the logical OR of
+some set of transformation flags.  This call is equivalent to png_read_info(),
+followed the set of transformations indicated by the transform mask,
+then png_read_image(), and finally png_read_end().
 
-This has to appear here rather than later with the other transformations
-because the tRNS chunk data must be modified in the case of paletted images.
-If your image is not a paletted image, the tRNS data (which in such cases
-represents a single color to be rendered as transparent) won't be changed.
+(The final parameter of this call is not yet used.  Someday it might point
+to transformation parameters required by some future input transform.)
 
-Finally, you can write your own transformation function if none of
-the existing ones meets your needs.  This is done by setting a callback
+After you have called png_read_png(), you can retrieve the image data
 with
 
-    png_set_read_user_transform_fn(png_ptr,
-       read_transform_fn);
+   row_pointers = png_get_rows(png_ptr, info_ptr);
 
-You must supply the function
+where row_pointers is an array of pointers to the pixel data for each row:
 
-    void read_transform_fn(png_ptr ptr, row_info_ptr
-       row_info, png_bytep data)
+   png_bytep row_pointers[height];
 
-See pngtest.c for a working example.  Your function will be called
-after all of the other transformations have been processed.
+If you know your image size and pixel size ahead of time, you can allocate
+row_pointers prior to calling png_read_png() with
+
+   row_pointers = png_malloc(png_ptr, height*sizeof(png_bytep));
+   for (int i=0; i<height, i++)
+      row_pointers[i]=png_malloc(png_ptr, width*pixel_size);
+   png_set_rows(png_ptr, info_ptr, &row_pointers);
+
+Alternatively you could allocate your image in one big block and define
+row_pointers[i] to point into the proper places in your block.
+
+If you use png_set_rows(), the application is responsible for freeing
+row_pointers (and row_pointers[i], if they were separately allocated).
 
-You are now ready to read all the file information up to the actual
-image data.  You do this with a call to png_read_info().
+If you don't allocate row_pointers ahead of time, png_read_png() will
+do it, and it'll be free'ed when you call png_destroy_*().
+
+.SS The low-level read interface
+
+If you are going the low-level route, you are now ready to read all
+the file information up to the actual image data.  You do this with a
+call to png_read_info().
 
     png_read_info(png_ptr, info_ptr);
 
-Functions are used to get the information from the info_ptr:
+This will process all chunks up to but not including the image data.
+
+.SS Querying the info structure
+
+Functions are used to get the information from the info_ptr once it
+has been read.  Note that these fields may not be completely filled
+in until png_read_end() has read the chunk data following the image.
 
     png_get_IHDR(png_ptr, info_ptr, &width, &height,
        &bit_depth, &color_type, &interlace_type,
-       &compression_type, &filter_type);
+       &compression_type, &filter_method);
 
     width          - holds the width of the image
                      in pixels (up to 2^31).
@@ -721,15 +1175,18 @@
                      PNG_COLOR_MASK_COLOR
                      PNG_COLOR_MASK_ALPHA
 
-    filter_type    - (must be PNG_FILTER_TYPE_BASE
-                     for PNG 1.0)
+    filter_method  - (must be PNG_FILTER_TYPE_BASE
+                     for PNG 1.0, and can also be
+                     PNG_INTRAPIXEL_DIFFERENCING if
+                     the PNG datastream is embedded in
+                     a MNG-1.0 datastream)
     compression_type - (must be PNG_COMPRESSION_TYPE_BASE
                      for PNG 1.0)
     interlace_type - (PNG_INTERLACE_NONE or
                      PNG_INTERLACE_ADAM7)
     Any or all of interlace_type, compression_type, of
-                     filter_type can be
-    NULL if you are not interested in their values.
+                     filter_method can be NULL if you are
+                     not interested in their values.
 
     channels = png_get_channels(png_ptr, info_ptr);
     channels       - number of channels of info for the
@@ -759,7 +1216,7 @@
                          info_ptr);
     color_type       = png_get_color_type(png_ptr,
                          info_ptr);
-    filter_type      = png_get_filter_type(png_ptr,
+    filter_method    = png_get_filter_type(png_ptr,
                          info_ptr);
     compression_type = png_get_compression_type(png_ptr,
                          info_ptr);
@@ -792,6 +1249,16 @@
                      implies specific values of gAMA and
                      cHRM.
 
+    png_get_iCCP(png_ptr, info_ptr, &name, &compression_type,
+                      &profile, &proflen);
+    name            - The profile name.
+    compression     - The compression type; always PNG_COMPRESSION_TYPE_BASE
+                      for PNG 1.0.  You may give NULL to this argument
+                      to ignore it.
+    profile         - International Color Consortium color profile
+                      data. May contain NULs.
+    proflen         - length of profile data in bytes.
+
     png_get_sBIT(png_ptr, info_ptr, &sig_bit);
     sig_bit        - the number of significant bits for
                      (PNG_INFO_sBIT) each of the gray,
@@ -803,15 +1270,16 @@
                      &trans_values);
     trans          - array of transparent entries for
                      palette (PNG_INFO_tRNS)
-    trans_values   - transparent pixel for non-paletted
-                     images (PNG_INFO_tRNS)
+    trans_values   - graylevel or color sample values of
+                     the single transparent color for
+                     non-paletted images (PNG_INFO_tRNS)
     num_trans      - number of transparent entries
                      (PNG_INFO_tRNS)
 
     png_get_hIST(png_ptr, info_ptr, &hist);
                      (PNG_INFO_hIST)
     hist           - histogram of palette (array of
-                     png_color_16)
+                     png_uint_16)
 
     png_get_tIME(png_ptr, info_ptr, &mod_time);
     mod_time       - time image was last modified
@@ -819,17 +1287,43 @@
 
     png_get_bKGD(png_ptr, info_ptr, &background);
     background     - background color (PNG_VALID_bKGD)
+                     valid 16-bit red, green and blue
+                     values, regardless of color_type
 
-    num_text = png_get_text(png_ptr, info_ptr, &text_ptr);
+    num_comments   = png_get_text(png_ptr, info_ptr,
+                     &text_ptr, &num_text);
+    num_comments   - number of comments
     text_ptr       - array of png_text holding image
                      comments
-    text_ptr[i]->key   - keyword for comment.
-    text_ptr[i]->text  - text comments for current
-                         keyword.
-    text_ptr[i]->compression - type of compression used
-                     on "text" PNG_TEXT_COMPRESSION_NONE
-                     or PNG_TEXT_COMPRESSION_zTXt
-    num_text       - number of comments
+    text_ptr[i].compression - type of compression used
+                 on "text" PNG_TEXT_COMPRESSION_NONE
+                           PNG_TEXT_COMPRESSION_zTXt
+                           PNG_ITXT_COMPRESSION_NONE
+                           PNG_ITXT_COMPRESSION_zTXt
+    text_ptr[i].key   - keyword for comment.  Must contain
+                         1-79 characters.
+    text_ptr[i].text  - text comments for current
+                         keyword.  Can be empty.
+    text_ptr[i].text_length - length of text string,
+                 after decompression, 0 for iTXt
+    text_ptr[i].itxt_length - length of itxt string,
+                 after decompression, 0 for tEXt/zTXt
+    text_ptr[i].lang  - language of comment (empty
+                         string for unknown).
+    text_ptr[i].translated_keyword  - keyword in UTF-8
+                         (empty string for unknown).
+    num_text       - number of comments (same as num_comments;
+                     you can put NULL here to avoid the duplication)
+    Note while png_set_text() will accept text, language, and
+    translated keywords that can be NULL pointers, the structure
+    returned by png_get_text will always contain regular
+    zero-terminated C strings.  They might be empty strings but
+    they will never be NULL pointers.
+
+    num_spalettes = png_get_sPLT(png_ptr, info_ptr, &palette_ptr);
+    palette_ptr    - array of palette structures holding
+                     contents of one or more sPLT chunks read.
+    num_spalettes  - number of sPLT chunks read.
 
     png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,
                      &unit_type);
@@ -848,6 +1342,30 @@
     unit_type      - PNG_RESOLUTION_UNKNOWN,
                      PNG_RESOLUTION_METER
 
+    png_get_sCAL(png_ptr, info_ptr, &unit, &width, &height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are doubles)
+
+    png_get_sCAL_s(png_ptr, info_ptr, &unit, &width, &height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are strings like "2.54")
+
+    num_unknown_chunks = png_get_unknown_chunks(png_ptr, info_ptr,
+                            &unknowns)
+    unknowns          - array of png_unknown_chunk structures holding
+                        unknown chunks
+    unknowns[i].name  - name of unknown chunk
+    unknowns[i].data  - data of unknown chunk
+    unknowns[i].size  - size of unknown chunk's data
+    unknowns[i].location - position of chunk in file
+
+    The value of "i" corresponds to the order in which the chunks were read
+    from the PNG file or inserted with the png_set_unknown_chunks() function.
+
 The data from the pHYs chunk can be retrieved in several convenient
 forms:
 
@@ -857,6 +1375,12 @@
                   info_ptr)
     res_x_and_y = png_get_pixels_per_meter(png_ptr,
                   info_ptr)
+    res_x = png_get_x_pixels_per_inch(png_ptr,
+                  info_ptr)
+    res_y = png_get_y_pixels_per_inch(png_ptr,
+                  info_ptr)
+    res_x_and_y = png_get_pixels_per_inch(png_ptr,
+                  info_ptr)
     aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,
                   info_ptr)
 
@@ -864,6 +1388,18 @@
        the data is not present or if res_x is 0;
        res_x_and_y is 0 if res_x != res_y)
 
+The data from the oFFs chunk can be retrieved in several convenient
+forms:
+
+    x_offset = png_get_x_offset_microns(png_ptr, info_ptr);
+    y_offset = png_get_y_offset_microns(png_ptr, info_ptr);
+    x_offset = png_get_x_offset_inches(png_ptr, info_ptr);
+    y_offset = png_get_y_offset_inches(png_ptr, info_ptr);
+
+   (Each of these returns 0 [signifying "unknown" if both
+       x and y are 0] if the data is not present or if the chunk
+       is present but the unit is the pixel)
+
 For more information, see the png_info definition in png.h and the
 PNG specification for chunk contents.  Be careful with trusting
 rowbytes, as some of the transformations could increase the space
@@ -882,14 +1418,17 @@
 Keywords should be limited to 79 Latin-1 characters without leading or
 trailing spaces, but non-consecutive spaces are allowed within the
 keyword.  It is possible to have the same keyword any number of times.
-The text_ptr is an array of png_text structures, each holding pointer
-to a keyword and a pointer to a text string.  Only the text string may
-be null.  The keyword/text pairs are put into the array in the order
-that they are received.  However, some or all of the text chunks may be
-after the image, so, to make sure you have read all the text chunks,
-don't mess with these until after you read the stuff after the image.
-This will be mentioned again below in the discussion that goes with
-png_read_end().
+The text_ptr is an array of png_text structures, each holding a
+pointer to a language string, a pointer to a keyword and a pointer to
+a text string.  The text string, language code, and translated
+keyword may be empty or NULL pointers.  The keyword/text
+pairs are put into the array in the order that they are received.
+However, some or all of the text chunks may be after the image, so, to
+make sure you have read all the text chunks, don't mess with these
+until after you read the stuff after the image.  This will be
+mentioned again below in the discussion that goes with png_read_end().
+
+.SS Input transformations
 
 After you've read the header information, you can set up the library
 to handle any special transformations of the image data.  The various
@@ -928,14 +1467,19 @@
 grayscale images with bit depths of 2 or 4 or if there is a multiple-image
 viewing application that wishes to treat all images in the same way.
 
-    if (color_type == PNG_COLOR_TYPE_PALETTE &&
-        bit_depth <= 8) png_set_expand(png_ptr);
+    if (color_type == PNG_COLOR_TYPE_PALETTE)
+        png_set_palette_to_rgb(png_ptr);
 
     if (color_type == PNG_COLOR_TYPE_GRAY &&
-        bit_depth < 8) png_set_expand(png_ptr);
+        bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
 
     if (png_get_valid(png_ptr, info_ptr,
-        PNG_INFO_tRNS)) png_set_expand(png_ptr);
+        PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
+
+These three functions are actually aliases for png_set_expand(), added
+in libpng version 1.0.4, with the function names expanded to improve code
+readability.  In some future version they may actually do different
+things.
 
 PNG can have files with 16 bits per channel.  If you only can handle
 8 bits per channel, this will strip the pixels down to 8 bit.
@@ -943,17 +1487,6 @@
     if (bit_depth == 16)
         png_set_strip_16(png_ptr);
 
-The png_set_background() function tells libpng to composite images
-with alpha or simple transparency against the supplied background
-color.  If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),
-you may use this color, or supply another color more suitable for
-the current display (e.g., the background color from a web page).  You
-need to tell libpng whether the color is in the gamma space of the
-display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file
-(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one
-that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't
-know why anyone would use this, but it's here).
-
 If, for some reason, you don't need the alpha channel on an image,
 and you want to remove it rather than combining it with the background
 (but the image author certainly had in mind that you *would* combine
@@ -962,6 +1495,15 @@
     if (color_type & PNG_COLOR_MASK_ALPHA)
         png_set_strip_alpha(png_ptr);
 
+In PNG files, the alpha channel in an image
+is the level of opacity.  If you need the alpha channel in an image to
+be the level of transparency instead of opacity, you can invert the
+alpha channel (or the tRNS chunk data) after it's read, so that 0 is
+fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit
+images) is fully transparent, with
+
+    png_set_invert_alpha(png_ptr);
+
 PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
 they can, resulting in, for example, 8 pixels per byte for 1 bit
 files.  This code expands to 1 pixel per byte without changing the
@@ -1015,14 +1557,12 @@
           png_set_gray_to_rgb(png_ptr);
 
 Conversely, you can convert an RGB or RGBA image to grayscale or grayscale
-with alpha.  This is intended for conversion of images that really are
-gray (red == green == blue), so the function simply strips out the red
-and blue channels, leaving the green channel in the gray position.
+with alpha.
 
     if (color_type == PNG_COLOR_TYPE_RGB ||
         color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-          png_set_rgb_to_gray(png_ptr, error_action,
-             float red_weight, float green_weight);
+          png_set_rgb_to_gray_fixed(png_ptr, error_action,
+             int red_weight, int green_weight);
 
     error_action = 1: silently do the conversion
     error_action = 2: issue a warning if the original
@@ -1033,10 +1573,10 @@
                       image has any pixel where
                       red != green or red != blue
 
-    red_weight:       weight of red component
-                      (NULL -> default 54/256)
-    green_weight:     weight of green component
-                      (NULL -> default 183/256)
+    red_weight:       weight of red component times 100000
+    green_weight:     weight of green component times 100000
+                      If either weight is negative, default
+                      weights (21268, 71514) are used.
 
 If you have set error_action = 1 or 2, you can
 later check whether the image really was gray, after processing
@@ -1046,13 +1586,13 @@
 will be silently converted to grayscale, using the green channel
 data, regardless of the error_action setting.
 
-With 0.0<=red_weight+green_weight<=1.0,
+With red_weight+green_weight<=100000,
 the normalized graylevel is computed:
 
-    int rw = red_weight * 256;
-    int gw = green_weight * 256;
-    int bw = 256 - (rw + gw);
-    gray = (rw*red + gw*green + bw*blue)/256;
+    int rw = red_weight * 65536;
+    int gw = green_weight * 65536;
+    int bw = 65536 - (rw + gw);
+    gray = (rw*red + gw*green + bw*blue)/65536;
 
 The default values approximate those recommended in the Charles
 Poynton's Color FAQ, <http://www.inforamp.net/~poynton/>
@@ -1062,16 +1602,17 @@
 
 Libpng approximates this with
 
-    Y = 0.211 * R    + 0.715 * G    + 0.074 * B
+    Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
 
 which can be expressed with integers as
 
-    Y = (54 * R + 183 * G + 19 * B)/256
+    Y = (6969 * R + 23434 * G + 2365 * B)/32768
 
 The calculation is done in a linear colorspace, if the image gamma
 is known.
 
-If you have a grayscale and you are using png_set_expand() to change to
+If you have a grayscale and you are using png_set_expand_depth() or
+png_set_expand() to change to
 a higher bit-depth, you must either supply the background color as a gray
 value at the original file bit-depth (need_expand = 1) or else supply the
 background color as an RGB triplet at the final, expanded bit depth
@@ -1089,20 +1630,31 @@
         png_set_background(png_ptr, &my_background,
           PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
 
+The png_set_background() function tells libpng to composite images
+with alpha or simple transparency against the supplied background
+color.  If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),
+you may use this color, or supply another color more suitable for
+the current display (e.g., the background color from a web page).  You
+need to tell libpng whether the color is in the gamma space of the
+display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file
+(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one
+that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't
+know why anyone would use this, but it's here).
+
 To properly display PNG images on any kind of system, the application needs
 to know what the display gamma is.  Ideally, the user will know this, and
 the application will allow them to set it.  One method of allowing the user
-to set the display gamma separately for each system is to check for the
-DISPLAY_GAMMA and VIEWING_GAMMA environment variables or for a SCREEN_GAMMA
-environment variable, which will hopefully be correctly set.
-
-Note that display_gamma is the gamma of your display, while screen_gamma is
-the overall gamma correction required to produce pleasing results,
-which depends on the lighting conditions in the surrounding environment.
-Screen_gamma is display_gamma/viewing_gamma, where viewing_gamma is
-the amount of additional gamma correction needed to compensate for
-a (viewing_gamma=1.25) environment.  In a dim or brightly lit room, no
-compensation other than the display_gamma is needed (viewing_gamma=1.0).
+to set the display gamma separately for each system is to check for a
+SCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully be
+correctly set.
+
+Note that display_gamma is the overall gamma correction required to produce
+pleasing results, which depends on the lighting conditions in the surrounding
+environment.  In a dim or brightly lit room, no compensation other than
+the physical gamma exponent of the monitor is needed, while in a dark room
+a slightly smaller exponent is better.
+
+   double gamma, screen_gamma;
 
    if (/* We have a user-defined screen
        gamma value */)
@@ -1114,7 +1666,7 @@
    else if ((gamma_str = getenv("SCREEN_GAMMA"))
       != NULL)
    {
-      screen_gamma = atof(gamma_str);
+      screen_gamma = (double)atof(gamma_str);
    }
    /* If we don't have another value */
    else
@@ -1157,7 +1709,7 @@
       if (png_get_valid(png_ptr, info_ptr,
          PNG_INFO_PLTE))
       {
-         png_color_16p histogram;
+         png_uint_16p histogram;
 
          png_get_hIST(png_ptr, info_ptr,
             &histogram);
@@ -1196,6 +1748,38 @@
     if (bit_depth < 8)
        png_set_packswap(png_ptr);
 
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs.  This is done by setting a callback
+with
+
+    png_set_read_user_transform_fn(png_ptr,
+       read_transform_fn);
+
+You must supply the function
+
+    void read_transform_fn(png_ptr ptr, row_info_ptr
+       row_info, png_bytep data)
+
+See pngtest.c for a working example.  Your function will be called
+after all of the other transformations have been processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function, and you can inform libpng that your transform
+function will change the number of channels or bit depth with the
+function
+
+    png_set_user_transform_info(png_ptr, user_ptr,
+       user_depth, user_channels);
+
+The user's application, not libpng, is responsible for allocating and
+freeing any memory required for the user structure.
+
+You can retrieve the pointer via the function
+png_get_user_transform_ptr().  For example:
+
+    voidp read_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
+
 The last thing to handle is interlacing; this is covered in detail below,
 but you must call the function here if you want libpng to handle expansion
 of the interlaced image.
@@ -1219,6 +1803,8 @@
 array of pointers to each row, as it will be needed for some
 of the functions below.
 
+.SS Reading image data
+
 After you've allocated memory, you can read the image data.
 The simplest way to do this is in one function call.  If you are
 allocating enough memory to hold the whole image, you can just
@@ -1248,13 +1834,13 @@
 where row_pointers is the same as in the png_read_image() call.
 
 If you are doing this just one row at a time, you can do this with
-row_pointers:
+a single row_pointer instead of an array of row_pointers:
 
-    png_bytep row_pointers = row;
-    png_read_row(png_ptr, &row_pointers, NULL);
+    png_bytep row_pointer = row;
+    png_read_row(png_ptr, row_pointer, NULL);
 
-If the file is interlaced (info_ptr->interlace_type != 0), things get
-somewhat harder.  The only current (PNG Specification version 1.0)
+If the file is interlaced (interlace_type != 0 in the IHDR chunk), things
+get somewhat harder.  The only current (PNG Specification version 1.2)
 interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7)
 is a somewhat complicated 2D interlace scheme, known as Adam7, that
 breaks down an image into seven smaller images of varying size, based
@@ -1327,12 +1913,14 @@
     png_read_rows(png_ptr, NULL, row_pointers,
        number_of_rows);
 
-After you are finished reading the image, you can finish reading
-the file.  If you are interested in comments or time, which may be
-stored either before or after the image data, you should pass the
-separate png_info struct if you want to keep the comments from
-before and after the image separate.  If you are not interested, you
-can pass NULL.
+.SS Finishing a sequential read
+
+After you are finished reading the image through either the high- or
+low-level interfaces, you can finish reading the file.  If you are
+interested in comments or time, which may be stored either before or
+after the image data, you should pass the separate png_info struct if
+you want to keep the comments from before and after the image
+separate.  If you are not interested, you can pass NULL.
 
    png_read_end(png_ptr, end_info);
 
@@ -1341,10 +1929,87 @@
    png_destroy_read_struct(&png_ptr, &info_ptr,
        &end_info);
 
-For a more compact example of reading a PNG image, see the file example.c.
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
+
+    png_free_data(png_ptr, info_ptr, mask, n)
+    mask - identifies data to be freed, a mask
+           containing the logical OR of one or
+           more of
+             PNG_FREE_PLTE, PNG_FREE_TRNS,
+             PNG_FREE_HIST, PNG_FREE_ICCP,
+             PNG_FREE_PCAL, PNG_FREE_ROWS,
+             PNG_FREE_SCAL, PNG_FREE_SPLT,
+             PNG_FREE_TEXT, PNG_FREE_UNKN,
+           or simply PNG_FREE_ALL
+    n    - sequence number of item to be freed
+           (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user and not by libpng,  and will in those
+cases do nothing.  The "n" parameter is ignored if only one item
+of the selected data type, such as PLTE, is allowed.  If "n" is not
+-1, and multiple items are allowed for the data type identified in
+the mask, such as text or sPLT, only the n'th item is freed.
+
+The default behavior is only to free data that was allocated internally
+by libpng.  This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+    png_data_freer(png_ptr, info_ptr, freer, mask)
+    mask   - which data elements are affected
+             same choices as in png_free_data()
+    freer  - one of
+               PNG_DESTROY_WILL_FREE_DATA
+               PNG_SET_WILL_FREE_DATA
+               PNG_USER_WILL_FREE_DATA
+
+This function only affects data that has already been allocated.
+You can call this function after reading the PNG data but before calling
+any png_set_*() functions, to control whether the user or the png_set_*()
+function is responsible for freeing any existing data that might be present,
+and again after the png_set_*() functions to control whether the user
+or png_destroy_*() is supposed to free the data.  When the user assumes
+responsibility for libpng-allocated data, the application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it (the png_zalloc() function is the same
+as png_malloc() except that it also zeroes the newly-allocated memory).
+
+If you allocated your row_pointers in a single block, as suggested above in
+the description of the high level read interface, you must not transfer
+responsibility for freeing it to the png_set_rows or png_read_destroy function,
+because they would also try to free the individual row_pointers[i].
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key.  Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
+
+The png_free_data() function will turn off the "valid" flag for anything
+it frees.  If you need to turn the flag off for a chunk that was freed by your
+application instead of by libpng, you can use
+
+    png_set_invalid(png_ptr, info_ptr, mask);
+    mask - identifies the chunks to be made invalid,
+           containing the logical OR of one or
+           more of
+             PNG_INFO_gAMA, PNG_INFO_sBIT,
+             PNG_INFO_cHRM, PNG_INFO_PLTE,
+             PNG_INFO_tRNS, PNG_INFO_bKGD,
+             PNG_INFO_hIST, PNG_INFO_pHYs,
+             PNG_INFO_oFFs, PNG_INFO_tIME,
+             PNG_INFO_pCAL, PNG_INFO_sRGB,
+             PNG_INFO_iCCP, PNG_INFO_sPLT,
+             PNG_INFO_sCAL, PNG_INFO_IDAT
 
+For a more compact example of reading a PNG image, see the file example.c.
 
-Reading PNG files progressively:
+.SS Reading PNG files progressively
 
 The progressive reader is slightly different then the non-progressive
 reader.  Instead of calling png_read_info(), png_read_rows(), and
@@ -1370,20 +2035,20 @@
         (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
          user_error_fn, user_warning_fn);
     if (!png_ptr)
-        return -1;
+        return (ERROR);
     info_ptr = png_create_info_struct(png_ptr);
     if (!info_ptr)
     {
         png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
            (png_infopp)NULL);
-        return -1;
+        return (ERROR);
     }
 
-    if (setjmp(png_ptr->jmpbuf))
+    if (setjmp(png_jmpbuf(png_ptr)))
     {
         png_destroy_read_struct(&png_ptr, &info_ptr,
            (png_infopp)NULL);
-        return -1;
+        return (ERROR);
     }
 
     /* This one's new.  You can provide functions
@@ -1413,11 +2078,11 @@
  int
  process_data(png_bytep buffer, png_uint_32 length)
  {
-    if (setjmp(png_ptr->jmpbuf))
+    if (setjmp(png_jmpbuf(png_ptr)))
     {
         png_destroy_read_struct(&png_ptr, &info_ptr,
            (png_infopp)NULL);
-        return -1;
+        return (ERROR);
     }
 
     /* This one's new also.  Simply give it a chunk
@@ -1521,6 +2186,8 @@
 importance is repeated here, so you won't have to constantly look
 back up in the reading section to understand writing.
 
+.SS Setup
+
 You will want to do the I/O initialization before you get into libpng,
 so if it doesn't work, you don't have anything to undo. If you are not
 using the standard I/O functions, you will need to replace them with
@@ -1529,7 +2196,7 @@
     FILE *fp = fopen(file_name, "wb");
     if (!fp)
     {
-       return;
+       return (ERROR);
     }
 
 Next, png_struct and png_info need to be allocated and initialized.
@@ -1544,19 +2211,19 @@
        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
         user_error_fn, user_warning_fn);
     if (!png_ptr)
-       return;
+       return (ERROR);
 
     png_infop info_ptr = png_create_info_struct(png_ptr);
     if (!info_ptr)
     {
        png_destroy_write_struct(&png_ptr,
          (png_infopp)NULL);
-       return;
+       return (ERROR);
     }
 
 If you want to use your own memory allocation routines,
 define PNG_USER_MEM_SUPPORTED and use
-png_create_write_struct_2() instead of png_create_read_struct():
+png_create_write_struct_2() instead of png_create_write_struct():
 
     png_structp png_ptr = png_create_write_struct_2
        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
@@ -1566,23 +2233,27 @@
 After you have these structures, you will need to set up the
 error handling.  When libpng encounters an error, it expects to
 longjmp() back to your routine.  Therefore, you will need to call
-setjmp() and pass the png_ptr->jmpbuf.  If you
+setjmp() and pass the png_jmpbuf(png_ptr).  If you
 write the file from different routines, you will need to update
-the jmpbuf field every time you enter a new routine that will
-call a png_ function.  See your documentation of setjmp/longjmp
+the png_jmpbuf(png_ptr) every time you enter a new routine that will
+call a png_*() function.  See your documentation of setjmp/longjmp
 for your compiler for more information on setjmp/longjmp.  See
 the discussion on libpng error handling in the Customizing Libpng
 section below for more information on the libpng error handling.
 
-    if (setjmp(png_ptr->jmpbuf))
+    if (setjmp(png_jmpbuf(png_ptr)))
     {
-        png_destroy_write_struct(&png_ptr, &info_ptr);
-        fclose(fp);
-        return;
+       png_destroy_write_struct(&png_ptr, &info_ptr);
+       fclose(fp);
+       return (ERROR);
     }
     ...
     return;
 
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
 Now you need to set up the output code.  The default for libpng is to
 use the C function fwrite().  If you use this, you will need to pass a
 valid FILE * in the function png_init_io().  Be sure that the file is
@@ -1592,6 +2263,8 @@
 
     png_init_io(png_ptr, fp);
 
+.SS Write callbacks
+
 At this point, you can set up a callback function that will be
 called after each row has been written, which you can use to control
 a progress meter or the like.  It's demonstrated in pngtest.c.
@@ -1616,24 +2289,40 @@
 have no special needs in this area, let the library do what it wants by
 not calling this function at all, as it has been tuned to deliver a good
 speed/compression ratio. The second parameter to png_set_filter() is
-the filter method, for which the only valid value is '0' (as of the
-October 1996 PNG specification, version 1.0).  The third parameter is a
-flag that indicates which filter type(s) are to be tested for each
-scanline.  See the Compression Library for details on the specific filter
+the filter method, for which the only valid values are 0 (as of the
+July 1999 PNG specification, version 1.2) or 64 (if you are writing
+a PNG datastream that is to be embedded in a MNG datastream).  The third
+parameter is a flag that indicates which filter type(s) are to be tested
+for each scanline.  See the PNG specification for details on the specific filter
 types.
 
 
     /* turn on or off filtering, and/or choose
-       specific filters */
+       specific filters.  You can use either a single PNG_FILTER_VALUE_NAME
+       or the logical OR of one or more PNG_FILTER_NAME masks. */
     png_set_filter(png_ptr, 0,
-       PNG_FILTER_NONE | PNG_FILTER_SUB |
-       PNG_FILTER_PAETH);
+       PNG_FILTER_NONE  | PNG_FILTER_VALUE_NONE |
+       PNG_FILTER_SUB   | PNG_FILTER_VALUE_SUB  |
+       PNG_FILTER_UP    | PNG_FILTER_VALUE_UP   |
+       PNG_FILTER_AVE   | PNG_FILTER_VALUE_AVE  |
+       PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|
+       PNG_ALL_FILTERS);
+
+If an application
+wants to start and stop using particular filters during compression,
+it should start out with all of the filters (to ensure that the previous
+row of pixels will be stored in case it's needed later), and then add
+and remove them after the start of compression.
+
+If you are writing a PNG datastream that is to be embedded in a MNG
+datastream, the second parameter can be either 0 or 64.
 
-The png_set_compression_???() functions interface to the zlib compression
+The png_set_compression_*() functions interface to the zlib compression
 library, and should mostly be ignored unless you really know what you are
 doing.  The only generally useful call is png_set_compression_level()
 which changes how much time zlib spends on trying to compress the image
-data.  See the Compression Library for details on the compression levels.
+data.  See the Compression Library (zlib.h and algorithm.txt, distributed
+with zlib) for details on the compression levels.
 
     /* set the zlib compression level */
     png_set_compression_level(png_ptr,
@@ -1645,11 +2334,16 @@
         Z_DEFAULT_STRATEGY);
     png_set_compression_window_bits(png_ptr, 15);
     png_set_compression_method(png_ptr, 8);
+    png_set_compression_buffer_size(png_ptr, 8192)
+
+extern PNG_EXPORT(void,png_set_zbuf_size)
+
+.SS Setting the contents of info for output
 
 You now need to fill in the png_info structure with all the data you
 wish to write before the actual image.  Note that the only thing you
 are allowed to write after the image is the text chunks and the time
-chunk (as of PNG Specification 1.0, anyway).  See png_write_end() and
+chunk (as of PNG Specification 1.2, anyway).  See png_write_end() and
 the latest PNG specification for more information on that.  If you
 wish to write them before the image, fill them in now, and flag that
 data as being valid.  If you want to wait until after the data, don't
@@ -1661,7 +2355,7 @@
 
     png_set_IHDR(png_ptr, info_ptr, width, height,
        bit_depth, color_type, interlace_type,
-       compression_type, filter_type)
+       compression_type, filter_method)
     width          - holds the width of the image
                      in pixels (up to 2^31).
     height         - holds the height of the image
@@ -1693,7 +2387,11 @@
                      PNG_INTERLACE_ADAM7
     compression_type - (must be
                      PNG_COMPRESSION_TYPE_DEFAULT)
-    filter_type    - (must be PNG_FILTER_TYPE_DEFAULT)
+    filter_method  - (must be PNG_FILTER_TYPE_DEFAULT
+                     or, if you are writing a PNG to
+                     be embedded in a MNG datastream,
+                     can also be
+                     PNG_INTRAPIXEL_DIFFERENCING)
 
     png_set_PLTE(png_ptr, info_ptr, palette,
        num_palette);
@@ -1717,10 +2415,10 @@
                      Color Consortium
                      (http://www.color.org).
                      It can be one of
-                     PNG_SRGB_INTENT_SATURATION,
-                     PNG_SRGB_INTENT_PERCEPTUAL,
-                     PNG_SRGB_INTENT_ABSOLUTE, or
-                     PNG_SRGB_INTENT_RELATIVE.
+                     PNG_sRGB_INTENT_SATURATION,
+                     PNG_sRGB_INTENT_PERCEPTUAL,
+                     PNG_sRGB_INTENT_ABSOLUTE, or
+                     PNG_sRGB_INTENT_RELATIVE.
 
 
     png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,
@@ -1734,6 +2432,16 @@
                      that are consistent with sRGB to be
                      written.
 
+    png_set_iCCP(png_ptr, info_ptr, name, compression_type,
+                      profile, proflen);
+    name            - The profile name.
+    compression     - The compression type; always PNG_COMPRESSION_TYPE_BASE
+                      for PNG 1.0.  You may give NULL to this argument
+                      to ignore it.
+    profile         - International Color Consortium color profile
+                      data. May contain NULs.
+    proflen         - length of profile data in bytes.
+
     png_set_sBIT(png_ptr, info_ptr, sig_bit);
     sig_bit        - the number of significant bits for
                      (PNG_INFO_sBIT) each of the gray, red,
@@ -1745,15 +2453,16 @@
        trans_values);
     trans          - array of transparent entries for
                      palette (PNG_INFO_tRNS)
-    trans_values   - transparent pixel for non-paletted
-                     images (PNG_INFO_tRNS)
+    trans_values   - graylevel or color sample values of
+                     the single transparent color for
+                     non-paletted images (PNG_INFO_tRNS)
     num_trans      - number of transparent entries
                      (PNG_INFO_tRNS)
 
     png_set_hIST(png_ptr, info_ptr, hist);
                     (PNG_INFO_hIST)
     hist           - histogram of palette (array of
-                     png_color_16)
+                     png_uint_16)
 
     png_set_tIME(png_ptr, info_ptr, mod_time);
     mod_time       - time image was last modified
@@ -1765,13 +2474,30 @@
     png_set_text(png_ptr, info_ptr, text_ptr, num_text);
     text_ptr       - array of png_text holding image
                      comments
-    text_ptr[i]->key   - keyword for comment.
-    text_ptr[i]->text  - text comments for current
-                         keyword.
-    text_ptr[i]->compression - type of compression used
-         on "text" PNG_TEXT_COMPRESSION_NONE or
-         PNG_TEXT_COMPRESSION_zTXt
-    num_text    - number of comments in text_ptr
+    text_ptr[i].compression - type of compression used
+                 on "text" PNG_TEXT_COMPRESSION_NONE
+                           PNG_TEXT_COMPRESSION_zTXt
+                           PNG_ITXT_COMPRESSION_NONE
+                           PNG_ITXT_COMPRESSION_zTXt
+    text_ptr[i].key   - keyword for comment.  Must contain
+                 1-79 characters.
+    text_ptr[i].text  - text comments for current
+                         keyword.  Can be NULL or empty.
+    text_ptr[i].text_length - length of text string,
+                 after decompression, 0 for iTXt
+    text_ptr[i].itxt_length - length of itxt string,
+                 after decompression, 0 for tEXt/zTXt
+    text_ptr[i].lang  - language of comment (NULL or
+                         empty for unknown).
+    text_ptr[i].translated_keyword  - keyword in UTF-8 (NULL
+                         or empty for unknown).
+    num_text       - number of comments
+
+    png_set_sPLT(png_ptr, info_ptr, &palette_ptr, num_spalettes);
+    palette_ptr    - array of png_sPLT_struct structures to be
+                     added to the list of palettes in the info
+                     structure.
+    num_spalettes  - number of palette structures to be added.
 
     png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,
         unit_type);
@@ -1790,30 +2516,52 @@
     unit_type   - PNG_RESOLUTION_UNKNOWN,
                   PNG_RESOLUTION_METER
 
-In PNG files, the alpha channel in an image is the level of opacity.
-If your data is supplied as a level of transparency, you can invert the
-alpha channel before you write it, so that 0 is fully transparent and 255
-(in 8-bit or paletted images) or 65535 (in 16-bit images) is fully opaque,
-with
-
-    png_set_invert_alpha(png_ptr);
-
-This must appear here instead of later with the other transformations
-because in the case of paletted images the tRNS chunk data has to
-be inverted before the tRNS chunk is written.  If your image is not a
-paletted image, the tRNS data (which in such cases represents a single
-color to be rendered as transparent) won't be changed.
+    png_set_sCAL(png_ptr, info_ptr, unit, width, height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                  (width and height are doubles)
+
+    png_set_sCAL_s(png_ptr, info_ptr, unit, width, height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are strings like "2.54")
+
+    png_set_unknown_chunks(png_ptr, info_ptr, &unknowns, num_unknowns)
+    unknowns          - array of png_unknown_chunk structures holding
+                        unknown chunks
+    unknowns[i].name  - name of unknown chunk
+    unknowns[i].data  - data of unknown chunk
+    unknowns[i].size  - size of unknown chunk's data
+    unknowns[i].location - position to write chunk in file
+                           0: do not write chunk
+                           PNG_HAVE_IHDR: before PLTE
+                           PNG_HAVE_PLTE: before IDAT
+                           PNG_AFTER_IDAT: after IDAT
+    The "location" member is set automatically according to
+    what part of the output file has already been written.
+    You can change its value after calling png_set_unknown_chunks()
+    as demonstrated in pngtest.c.  Within each of the "locations",
+    the chunks are sequenced according to their position in the
+    structure (that is, the value of "i", which is the order in which
+    the chunk was either read from the input file or defined with
+    png_set_unknown_chunks).
 
 A quick word about text and num_text.  text is an array of png_text
 structures.  num_text is the number of valid structures in the array.
-If you want, you can use max_text to hold the size of the array, but
-libpng ignores it for writing (it does use it for reading).  Each
-png_text structure holds a keyword-text value, and a compression type.
+Each png_text structure holds a language code, a keyword, a text value,
+and a compression type.
+
 The compression types have the same valid numbers as the compression
 types of the image data.  Currently, the only valid number is zero.
 However, you can store text either compressed or uncompressed, unlike
 images, which always have to be compressed.  So if you don't want the
 text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.
+Because tEXt and zTXt chunks don't have a language field, if you
+specify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt
+any language code or translated keyword will not be written out.
+
 Until text gets around 1000 bytes, it is not worth compressing it.
 After the text has been written out to the file, the compression type
 is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,
@@ -1856,7 +2604,7 @@
 is compressed anyway, so the compression would be meaningless.
 
 PNG supports modification time via the png_time structure.  Two
-conversion routines are proved, png_convert_from_time_t() for
+conversion routines are provided, png_convert_from_time_t() for
 time_t and png_convert_from_struct_tm() for struct tm.  The
 time_t routine uses gmtime().  You don't have to use either of
 these, but if you wish to fill in the png_time structure directly,
@@ -1879,9 +2627,79 @@
 png_convert_to_rfc1123(png_timep) is provided to convert from PNG
 time to an RFC 1123 format string.
 
-You are now ready to write all the file information up to the actual
-image data.  You do this with a call to png_write_info().
+.SS Writing unknown chunks
 
+You can use the png_set_unknown_chunks function to queue up chunks
+for writing.  You give it a chunk name, raw data, and a size; that's
+all there is to it.  The chunks will be written by the next following
+png_write_info_before_PLTE, png_write_info, or png_write_end function.
+Any chunks previously read into the info structure's unknown-chunk
+list will also be written out in a sequence that satisfies the PNG
+specification's ordering rules.
+
+.SS The high-level write interface
+
+At this point there are two ways to proceed; through the high-level
+write interface, or through a sequence of low-level write operations.
+You can use the high-level interface if your image data is present
+in the info structure.  All defined output
+transformations are permitted, enabled by the following masks.
+
+    PNG_TRANSFORM_IDENTITY      No transformation
+    PNG_TRANSFORM_PACKING       Pack 1, 2 and 4-bit samples
+    PNG_TRANSFORM_PACKSWAP      Change order of packed pixels to LSB first
+    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
+    PNG_TRANSFORM_SHIFT         Normalize pixels to the sBIT depth
+    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA to BGRA
+    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA to AG
+    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity to transparency
+    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples
+    PNG_TRANSFORM_STRIP_FILLER  Strip out filler bytes.
+
+If you have valid image data in the info structure (you can use
+png_set_rows() to put image data in the info structure), simply do this:
+
+    png_write_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the logical OR of some set of
+transformation flags.  This call is equivalent to png_write_info(),
+followed the set of transformations indicated by the transform mask,
+then png_write_image(), and finally png_write_end().
+
+(The final parameter of this call is not yet used.  Someday it might point
+to transformation parameters required by some future output transform.)
+
+.SS The low-level write interface
+
+If you are going the low-level route instead, you are now ready to
+write all the file information up to the actual image data.  You do
+this with a call to png_write_info().
+
+    png_write_info(png_ptr, info_ptr);
+
+Note that there is one transformation you may need to do before
+png_write_info().  In PNG files, the alpha channel in an image is the
+level of opacity.  If your data is supplied as a level of
+transparency, you can invert the alpha channel before you write it, so
+that 0 is fully transparent and 255 (in 8-bit or paletted images) or
+65535 (in 16-bit images) is fully opaque, with
+
+    png_set_invert_alpha(png_ptr);
+
+This must appear before png_write_info() instead of later with the
+other transformations because in the case of paletted images the tRNS
+chunk data has to be inverted before the tRNS chunk is written.  If
+your image is not a paletted image, the tRNS data (which in such cases
+represents a single color to be rendered as transparent) won't need to
+be changed, and you can safely do this transformation after your
+png_write_info() call.
+
+If you need to write a private chunk that you want to appear before
+the PLTE chunk when PLTE is present, you can write the PNG info in
+two steps, and insert code to write your own chunk between them:
+
+    png_write_info_before_PLTE(png_ptr, info_ptr);
+    png_set_unknown_chunks(png_ptr, info_ptr, ...);
     png_write_info(png_ptr, info_ptr);
 
 After you've written the file information, you can set up the library
@@ -1895,14 +2713,15 @@
 data.  For example, don't swap red and blue on grayscale data.
 
 PNG files store RGB pixels packed into 3 or 6 bytes.  This code tells
-the library to expand the input data to 4 or 8 bytes per pixel
-(or expand 1 or 2-byte grayscale data to 2 or 4 bytes per pixel).
+the library to strip input data that has 4 or 8 bytes per pixel down
+to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2
+bytes per pixel).
 
     png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
 
-where the 0 is the value that will be put in the 4th byte, and the
-location is either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending
-upon whether the filler byte is stored XRGB or RGBX.
+where the 0 is unused, and the location is either PNG_FILLER_BEFORE or
+PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel
+is stored XRGB or RGBX.
 
 PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
 they can, resulting in, for example, 8 pixels per byte for 1 bit files.
@@ -1913,7 +2732,7 @@
 
 PNG files reduce possible bit depths to 1, 2, 4, 8, and 16.  If your
 data is of another bit depth, you can write an sBIT chunk into the
-file so that decoders can get the original data if desired.
+file so that decoders can recover the original data if desired.
 
     /* Set the true bit depth of the image data */
     if (color_type & PNG_COLOR_MASK_COLOR)
@@ -1978,7 +2797,21 @@
        row_info, png_bytep data)
 
 See pngtest.c for a working example.  Your function will be called
-before any of the other transformations have been processed.
+before any of the other transformations are processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function.
+
+    png_set_user_transform_info(png_ptr, user_ptr, 0, 0);
+
+The user_channels and user_depth parameters of this function are ignored
+when writing; you can set them to zero as shown.
+
+You can retrieve the pointer via the function png_get_user_transform_ptr().
+For example:
+
+    voidp write_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
 
 It is possible to have libpng flush any pending output, either manually,
 or automatically after a certain number of lines have been written.  To
@@ -2002,8 +2835,10 @@
 only degrade the compression performance by a few percent over images
 that do not use flushing.
 
+.SS Writing the image data
+
 That's it for the transformations.  Now you can write the image data.
-The simplest way to do this is in one function call.  If have the
+The simplest way to do this is in one function call.  If you have the
 whole image in memory, you can just call png_write_image() and libpng
 will write the image.  You will need to pass in an array of pointers to
 each row.  This function automatically handles interlacing, so you don't
@@ -2028,15 +2863,15 @@
 row_pointers is the same as in the png_write_image() call.
 
 If you are just writing one row at a time, you can do this with
-row_pointers:
+a single row_pointer instead of an array of row_pointers:
 
     png_bytep row_pointer = row;
 
-    png_write_row(png_ptr, &row_pointer);
+    png_write_row(png_ptr, row_pointer);
 
 When the file is interlaced, things can get a good deal more
-complicated.  The only currently (as of February 1998 -- PNG Specification
-version 1.0, dated October 1996) defined interlacing scheme for PNG files
+complicated.  The only currently (as of the PNG Specification
+version 1.2, dated July 1999) defined interlacing scheme for PNG files
 is the "Adam7" interlace scheme, that breaks down an
 image into seven smaller images of varying size.  libpng will build
 these images for you, or you can do them yourself.  If you want to
@@ -2065,6 +2900,8 @@
 you may want to read about interlacing in the PNG specification,
 and only update the rows that are actually used.
 
+.SS Finishing a sequential write
+
 After you are finished writing the image, you should finish writing
 the file.  If you are interested in writing comments or time, you should
 pass an appropriately filled png_info pointer.  If you are not interested,
@@ -2076,32 +2913,120 @@
 
     png_destroy_write_struct(&png_ptr, &info_ptr);
 
-You must free any data you allocated for info_ptr, such as comments,
-palette, or histogram, before the call to png_destroy_write_struct();
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
 
+    png_free_data(png_ptr, info_ptr, mask, n)
+    mask  - identifies data to be freed, a mask
+            containing the logical OR of one or
+            more of
+              PNG_FREE_PLTE, PNG_FREE_TRNS,
+              PNG_FREE_HIST, PNG_FREE_ICCP,
+              PNG_FREE_PCAL, PNG_FREE_ROWS,
+              PNG_FREE_SCAL, PNG_FREE_SPLT,
+              PNG_FREE_TEXT, PNG_FREE_UNKN,
+            or simply PNG_FREE_ALL
+    n     - sequence number of item to be freed
+            (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user  and not by libpng,  and will in those
+cases do nothing.  The "n" parameter is ignored if only one item
+of the selected data type, such as PLTE, is allowed.  If "n" is not
+-1, and multiple items are allowed for the data type identified in
+the mask, such as text or sPLT, only the n'th item is freed.
+
+If you allocated data such as a palette that you passed
+in to libpng with png_set_*, you must not free it until just before the call to
+png_destroy_write_struct().
+
+The default behavior is only to free data that was allocated internally
+by libpng.  This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+    png_data_freer(png_ptr, info_ptr, freer, mask)
+    mask   - which data elements are affected
+             same choices as in png_free_data()
+    freer  - one of
+               PNG_DESTROY_WILL_FREE_DATA
+               PNG_SET_WILL_FREE_DATA
+               PNG_USER_WILL_FREE_DATA
+
+For example, to transfer responsibility for some data from a read structure
+to a write structure, you could use
+
+    png_data_freer(read_ptr, read_info_ptr,
+       PNG_USER_WILL_FREE_DATA,
+       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+    png_data_freer(write_ptr, write_info_ptr,
+       PNG_DESTROY_WILL_FREE_DATA,
+       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+
+thereby briefly reassigning responsibility for freeing to the user but
+immediately afterwards reassigning it once more to the write_destroy
+function.  Having done this, it would then be safe to destroy the read
+structure and continue to use the PLTE, tRNS, and hIST data in the write
+structure.
+
+This function only affects data that has already been allocated.
+You can call this function before calling after the png_set_*() functions
+to control whether the user or png_destroy_*() is supposed to free the data.
+When the user assumes responsibility for libpng-allocated data, the
+application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it.
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key.  Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
 For a more compact example of writing a PNG image, see the file example.c.
 
-
 .SH V. Modifying/Customizing libpng:
 
-There are two issues here.  The first is changing how libpng does
+There are three issues here.  The first is changing how libpng does
 standard things like memory allocation, input/output, and error handling.
 The second deals with more complicated things like adding new chunks,
 adding new transformations, and generally changing how libpng works.
+Both of those are compile-time issues; that is, they are generally
+determined at the time the code is written, and there is rarely a need
+to provide the user with a means of changing them.  The third is a
+run-time issue:  choosing between and/or tuning one or more alternate
+versions of computationally intensive routines; specifically, optimized
+assembly-language (and therefore compiler- and platform-dependent)
+versions.
+
+Memory allocation, input/output, and error handling
 
 All of the memory allocation, input/output, and error handling in libpng
-goes through callbacks that are user settable.  The default routines are
-in pngmem.c, pngrio.c, pngwio.c, and pngerror.c respectively.  To change
-these functions, call the appropriate png_set_???_fn() function.
-
-Memory allocation is done through the functions png_large_malloc(),
-png_malloc(), png_realloc(), png_large_free(), and png_free().  These
-currently just call the standard C functions.  The large functions must
-handle exactly 64K, but they don't have to handle more than that.  If
+goes through callbacks that are user-settable.  The default routines are
+in pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively.  To change
+these functions, call the appropriate png_set_*_fn() function.
+
+Memory allocation is done through the functions png_malloc(), png_zalloc(),
+and png_free().  These currently just call the standard C functions.  If
 your pointers can't access more then 64K at a time, you will want to set
 MAXSEG_64K in zlib.h.  Since it is unlikely that the method of handling
 memory allocation on a platform will change between applications, these
-functions must be modified in the library at compile time.
+functions must be modified in the library at compile time.  If you prefer
+to use a different method of allocating and freeing data, you can use
+
+    png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
+      malloc_fn, png_free_ptr free_fn)
+
+This function also provides a void pointer that can be retrieved via
+
+    mem_ptr=png_get_mem_ptr(png_ptr);
+
+Your replacement memory functions must have prototypes as follows:
+
+    png_voidp malloc_fn(png_structp png_ptr, png_uint_32 size);
+    void free_fn(png_structp png_ptr, png_voidp ptr);
 
 Input/Output in libpng is done through png_read() and png_write(),
 which currently just call fread() and fwrite().  The FILE * is stored in
@@ -2122,7 +3047,7 @@
     voidp read_io_ptr = png_get_io_ptr(read_ptr);
     voidp write_io_ptr = png_get_io_ptr(write_ptr);
 
-The replacement I/O functions should have prototypes as follows:
+The replacement I/O functions must have prototypes as follows:
 
     void user_read_data(png_structp png_ptr,
         png_bytep data, png_uint_32 length);
@@ -2137,15 +3062,20 @@
 Error handling in libpng is done through png_error() and png_warning().
 Errors handled through png_error() are fatal, meaning that png_error()
 should never return to its caller.  Currently, this is handled via
-setjmp() and longjmp(), but you could change this to do things like
-exit() if you should wish.  On non-fatal errors, png_warning() is called
+setjmp() and longjmp() (unless you have compiled libpng with
+PNG_SETJMP_NOT_SUPPORTED, in which case it is handled via PNG_ABORT()),
+but you could change this to do things like exit() if you should wish.
+
+On non-fatal errors, png_warning() is called
 to print a warning message, and then control returns to the calling code.
 By default png_error() and png_warning() print a message on stderr via
-fprintf() unless the library is compiled with PNG_NO_STDIO defined.  If
-you wish to change the behavior of the error functions, you will need to
-set up your own message callbacks.  These functions are normally supplied
-at the time that the png_struct is created.  It is also possible to change
-these functions after png_create_???_struct() has been called by calling:
+fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined
+(because you don't want the messages) or PNG_NO_STDIO defined (because
+fprintf() isn't available).  If you wish to change the behavior of the error
+functions, you will need to set up your own message callbacks.  These
+functions are normally supplied at the time that the png_struct is created.
+It is also possible to redirect errors and warnings to your own replacement
+functions after png_create_*_struct() has been called by calling:
 
     png_set_error_fn(png_structp png_ptr,
         png_voidp error_ptr, png_error_ptr error_fn,
@@ -2169,18 +3099,28 @@
 However, there are some uncertainties about the status of local variables
 after a longjmp, so the user may want to be careful about doing anything after
 setjmp returns non-zero besides returning itself.  Consult your compiler
-documentation for more details.
+documentation for more details.  For an alternative approach, you may wish
+to use the "cexcept" facility (see http://cexcept.sourceforge.net).
+
+.SS Custom chunks
 
-If you need to read or write custom chunks, you will need to get deeper
-into the libpng code, as a mechanism has not yet been supplied for user
-callbacks with custom chunks.  First, read the PNG specification, and have
-a first level of understanding of how it works.  Pay particular attention
-to the sections that describe chunk names, and look at how other chunks
-were designed, so you can do things similarly.  Second, check out the
-sections of libpng that read and write chunks.  Try to find a chunk that
-is similar to yours and copy off of it.  More details can be found in the
-comments inside the code.  A way of handling unknown chunks in a generic
-method, potentially via callback functions, would be best.
+If you need to read or write custom chunks, you may need to get deeper
+into the libpng code.  The library now has mechanisms for storing
+and writing chunks of unknown type; you can even declare callbacks
+for custom chunks.  Hoewver, this may not be good enough if the
+library code itself needs to know about interactions between your
+chunk and existing `intrinsic' chunks.
+
+If you need to write a new intrinsic chunk, first read the PNG
+specification. Acquire a first level of
+understanding of how it works.  Pay particular attention to the
+sections that describe chunk names, and look at how other chunks were
+designed, so you can do things similarly.  Second, check out the
+sections of libpng that read and write chunks.  Try to find a chunk
+that is similar to yours and use it as a template.  More details can
+be found in the comments inside the code.  It is best to handle unknown
+chunks in a generic method, via callback functions, instead of by
+modifying libpng functions.
 
 If you wish to write your own transformation for the data, look through
 the part of the code that does the transformations, and check out some of
@@ -2188,22 +3128,19 @@
 transformation to the one you want to add and copy off of it.  More details
 can be found in the comments inside the code itself.
 
-Configuring for 16 bit platforms:
+.SS Configuring for 16 bit platforms
 
-You may need to change the png_large_malloc() and png_large_free()
-routines in pngmem.c, as these are required to allocate 64K, although
-there is already support for many of the common DOS compilers.  Also,
-you will want to look into zconf.h to tell zlib (and thus libpng) that
+You will want to look into zconf.h to tell zlib (and thus libpng) that
 it cannot allocate more then 64K at a time.  Even if you can, the memory
 won't be accessible.  So limit zlib and libpng to 64K by defining MAXSEG_64K.
 
-Configuring for DOS:
+.SS Configuring for DOS
 
 For DOS users who only have access to the lower 640K, you will
 have to limit zlib's memory usage via a png_set_compression_mem_level()
 call.  See zlib.h or zconf.h in the zlib library for more information.
 
-Configuring for Medium Model:
+.SS Configuring for Medium Model
 
 Libpng's support for medium model has been tested on most of the popular
 compilers.  Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
@@ -2211,19 +3148,19 @@
 all set.  Everything in the library (except for zlib's structure) is
 expecting far data.  You must use the typedefs with the p or pp on
 the end for pointers (or at least look at them and be careful).  Make
-note that the row's of data are defined as png_bytepp, which is an
+note that the rows of data are defined as png_bytepp, which is an
 unsigned char far * far *.
 
-Configuring for gui/windowing platforms:
+.SS Configuring for gui/windowing platforms:
 
 You will need to write new error and warning functions that use the GUI
 interface, as described previously, and set them to be the error and
-warning functions at the time that png_create_???_struct() is called,
+warning functions at the time that png_create_*_struct() is called,
 in order to have them available during the structure initialization.
 They can be changed later via png_set_error_fn().  On some compilers,
 you may also have to change the memory allocators (png_malloc, etc.).
 
-Configuring for compiler xxx:
+.SS Configuring for compiler xxx:
 
 All includes for libpng are in pngconf.h.  If you need to add/change/delete
 an include, this is the place to do it.  The includes that are not
@@ -2231,7 +3168,7 @@
 which is only defined for those routines inside libpng itself.  The
 files in libpng proper only include png.h, which includes pngconf.h.
 
-Configuring zlib:
+.SS Configuring zlib:
 
 There are special functions to configure the compression.  Perhaps the
 most useful one changes the compression level, which currently uses
@@ -2262,8 +3199,9 @@
     png_set_compression_window_bits(png_ptr,
         window_bits);
     png_set_compression_method(png_ptr, method);
+    png_set_compression_buffer_size(png_ptr, size);
 
-Controlling row filtering:
+.SS Controlling row filtering
 
 If you want to control whether libpng uses filtering or not, which
 filters are used, and how it goes about picking row filters, you
@@ -2275,24 +3213,34 @@
 for any images with bit depths less than 8 bits/pixel.
 
 The 'method' parameter sets the main filtering method, which is
-currently only '0' in the PNG 1.0 specification.  The 'filters'
+currently only '0' in the PNG 1.2 specification.  The 'filters'
 parameter sets which filter(s), if any, should be used for each
 scanline.  Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
 to turn filtering on and off, respectively.
 
 Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,
 PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise
-ORed together '|' to specify one or more filters to use.  These
-filters are described in more detail in the PNG specification.  If
+ORed together with '|' to specify one or more filters to use.
+These filters are described in more detail in the PNG specification.  If
 you intend to change the filter type during the course of writing
 the image, you should start with flags set for all of the filters
 you intend to use so that libpng can initialize its internal
 structures appropriately for all of the filter types.
 
     filters = PNG_FILTER_NONE | PNG_FILTER_SUB
-       | PNG_FILTER_UP;
+              PNG_FILTER_UP | PNG_FILTER_AVE |
+              PNG_FILTER_PAETH | PNG_ALL_FILTERS;
+    or
+    filters = one of PNG_FILTER_VALUE_NONE,
+              PNG_FILTER_VALUE_SUB, PNG_FILTER_VALUE_UP,
+              PNG_FILTER_VALUE_AVE, PNG_FILTER_VALUE_PAETH
+
     png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
        filters);
+              The second parameter can also be PNG_INTRAPIXEL_DIFFERENCING
+              if you are writing a PNG to be embedded in a MNG
+              datastream.  This parameter must be the same as the
+              value of filter_method used in png_set_IHDR().
 
 It is also possible to influence how libpng chooses from among the
 available filters.  This is done in two ways - by telling it how
@@ -2329,7 +3277,7 @@
 are given only to help explain the function usage.  Little testing has
 been done to find optimum values for either the costs or the weights.
 
-Removing unwanted object code:
+.SS Removing unwanted object code
 
 There are a bunch of #define's in pngconf.h that control what parts of
 libpng are compiled.  All the defines end in _SUPPORTED.  If you are
@@ -2339,13 +3287,13 @@
 PNG_NO_.
 
 You can also turn all of the transforms and ancillary chunk capabilities
-off en masse with  compiler directives that define
+off en masse with compiler directives that define
 PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
 or all four,
 along with directives to turn on any of the capabilities that you do
 want.  The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable
 the extra transformations but still leave the library fully capable of reading
-and writing PNG files with all known public chunks [except for sPLT].
+and writing PNG files with all known public chunks
 Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive
 produces a library that is incapable of reading or writing ancillary chunks.
 If you are not using the progressive reading capability, you can
@@ -2367,7 +3315,7 @@
 The size of the library itself should not be an issue, because only
 those sections that are actually used will be loaded into memory.
 
-Requesting debug printout:
+.SS Requesting debug printout
 
 The macro definition PNG_DEBUG can be used to request debugging
 printout.  Set it to an integer value in the range 0 to 3.  Higher
@@ -2404,7 +3352,33 @@
 having level = 0 will be printed.  There aren't any such statements in
 this version of libpng, but if you insert some they will be printed.
 
-.SH VI.  Changes to Libpng from version 0.88
+
+.SH VI.  MNG support
+
+The MNG specification (available at http://www.libpng.org/pub/mng) allows
+certain extensions to PNG for PNG images that are embedded in MNG datastreams.
+Libpng can support some of these extensions.  To enable them, use the
+png_permit_mng_features() function:
+
+   feature_set = png_permit_mng_features(png_ptr, mask)
+   mask is a png_uint_32 containing the logical OR of the
+        features you want to enable.  These include
+        PNG_FLAG_MNG_EMPTY_PLTE
+        PNG_FLAG_MNG_FILTER_64
+        PNG_ALL_MNG_FEATURES
+   feature_set is a png_32_uint that is the logical AND of
+      your mask with the set of MNG features that is
+      supported by the version of libpng that you are using.
+
+It is an error to use this function when reading or writing a standalone
+PNG file with the PNG 8-byte signature.  The PNG datastream must be wrapped
+in a MNG datastream.  As a minimum, it must have the MNG 8-byte signature
+and the MHDR and MEND chunks.  Libpng does not provide support for these
+or any other MNG chunks; your application must provide its own support for
+them.  You may wish to consider using libmng (available at
+http://www.libmng.com) instead.
+
+.SH VII.  Changes to Libpng from version 0.88
 
 It should be noted that versions of libpng later than 0.96 are not
 distributed by the original libpng author, Guy Schalnat, nor by
@@ -2415,8 +3389,10 @@
 
 The old libpng functions png_read_init(), png_write_init(),
 png_info_init(), png_read_destroy(), and png_write_destory() have been
-moved to PNG_INTERNAL in version 0.95 to discourage their use.  The
-preferred method of creating and initializing the libpng structures is
+moved to PNG_INTERNAL in version 0.95 to discourage their use.  These
+functions will be removed from libpng version 2.0.0.
+
+The preferred method of creating and initializing the libpng structures is
 via the png_create_read_struct(), png_create_write_struct(), and
 png_create_info_struct() because they isolate the size of the structures
 from the application, allow version error checking, and also allow the
@@ -2433,20 +3409,34 @@
 because this caused applications that do not use custom error functions
 to fail if the png_ptr was not initialized to zero.  It is still possible
 to set the error callbacks AFTER png_read_init(), or to change them with
-png_set_error_fn(), which is essentially the same function, but with a
-new name to force compilation errors with applications that try to use
-the old method.
+png_set_error_fn(), which is essentially the same function, but with a new
+name to force compilation errors with applications that try to use the old
+method.
+
+Starting with version 1.0.7, you can find out which version of the library
+you are using at run-time:
+
+   png_uint_32 libpng_vn = png_access_version_number();
 
-.SH VII. Y2K Compliance in libpng
+The number libpng_vn is constructed from the major version, minor
+version with leading zero, and release number with leading zero,
+(e.g., libpng_vn for version 1.0.7 is 10007).
 
-January 13, 1999
+You can also check which version of png.h you used when compiling your
+application:
+
+   png_uint_32 application_vn = PNG_LIBPNG_VER;
+
+.SH VIII. Y2K Compliance in libpng
+
+January 31, 2001
 
 Since the PNG Development group is an ad-hoc body, we can't make
 an official declaration.
 
-This is your unofficial assurance that libpng from version 0.81 and
-upward are Y2K compliant.  It is my belief that earlier versions were
-also Y2K compliant.
+This is your unofficial assurance that libpng from version 0.71 and
+upward through 1.0.9 are Y2K compliant.  It is my belief that earlier
+versions were also Y2K compliant.
 
 Libpng only has three year fields.  One is a 2-byte unsigned integer that
 will hold years up to 65535.  The other two hold the date in text
@@ -2461,7 +3451,7 @@
 
 There are seven time-related functions:
 
-    png_convert_to_rfc_1123() in png.c 
+    png_convert_to_rfc_1123() in png.c
       (formerly png_convert_to_rfc_1152() in error)
     png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
     png_convert_from_time_t() in pngwrite.c
@@ -2470,20 +3460,23 @@
     png_set_tIME() in pngset.c
     png_write_tIME() in pngwutil.c, called in pngwrite.c
 
-All appear to handle dates properly in a Y2K environment.  The 
+All appear to handle dates properly in a Y2K environment.  The
 png_convert_from_time_t() function calls gmtime() to convert from system
 clock time, which returns (year - 1900), which we properly convert to
 the full 4-digit year.  There is a possibility that applications using
 libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
-function, or incorrectly passing only a 2-digit year instead of
-"year - 1900" into the png_convert_from_struct_tm() function, but this
-is not under our control.  The libpng documentation has always stated
-that it works with 4-digit years, and the APIs have been documented as
-such.
+function, or that they are incorrectly passing only a 2-digit year
+instead of "year - 1900" into the png_convert_from_struct_tm() function,
+but this is not under our control.  The libpng documentation has always
+stated that it works with 4-digit years, and the APIs have been
+documented as such.
 
 The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
 integer to hold the year, and can hold years as large as 65535.
 
+zlib, upon which libpng depends, is also Y2K compliant.  It contains
+no date-related code.
+
 
    Glenn Randers-Pehrson
    libpng maintainer
@@ -2499,36 +3492,51 @@
 The following table summarizes matters since version 0.89c, which was
 the first widely used release:
 
-   source     png.h   png.h   shared-lib
-   version    string    int   version
-   -------    ------  ------  ----------
-   0.89c      0.89        89  1.0.89
-   0.90       0.90        90  0.90  [should be 2.0.90]
-   0.95       0.95        95  0.95  [should be 2.0.95]
-   0.96       0.96        96  0.96  [should be 2.0.96]
-   0.97b      1.00.97     97  1.0.1 [should be 2.0.97]
-   0.97c      0.97        97  2.0.97
-   0.98       0.98        98  2.0.98
-   0.99       0.99        98  2.0.99
-   0.99a-m    0.99        99  2.0.99
-   1.00       1.00       100  2.1.0 [int should be 10000]
-   1.0.0      1.0.0      100  2.1.0 [int should be 10000]
-   1.0.1      1.0.1    10001  2.1.0
-
-Henceforth the source version will match the shared-library
-minor and patch numbers; the shared-library major version number will be
-used for changes in backward compatibility, as it is intended.
-The PNG_PNGLIB_VER macro, which is not used within libpng but
-is available for applications, is an unsigned integer of the form
-xyyzz corresponding to the source version x.y.z (leading zeros in y and z).
- 
+   source                   png.h    png.h   shared-lib
+   version                  string     int   version
+   -------                  ------   -----  ----------
+   0.89c ("1.0 beta 3")     0.89        89  1.0.89
+   0.90  ("1.0 beta 4")     0.90        90  0.90  [should have been 2.0.90]
+   0.95  ("1.0 beta 5")     0.95        95  0.95  [should have been 2.0.95]
+   0.96  ("1.0 beta 6")     0.96        96  0.96  [should have been 2.0.96]
+   0.97b ("1.00.97 beta 7") 1.00.97     97  1.0.1 [should have been 2.0.97]
+   0.97c                    0.97        97  2.0.97
+   0.98                     0.98        98  2.0.98
+   0.99                     0.99        98  2.0.99
+   0.99a-m                  0.99        99  2.0.99
+   1.00                     1.00       100  2.1.0 [100 should be 10000]
+   1.0.0                    1.0.0      100  2.1.0 [100 should be 10000]
+   1.0.1                    1.0.1    10001  2.1.0
+   1.0.1a-e                 1.0.1a-e 10002  2.1.0.1a-e
+   1.0.2                    1.0.2    10002  2.1.0.2
+   1.0.2a-b                 1.0.2a-b 10003  2.1.0.2a-b
+   1.0.3                    1.0.3    10003  2.1.0.3
+   1.0.3a-d                 1.0.3a-d 10004  2.1.0.3a-d
+   1.0.4                    1.0.4    10004  2.1.0.4
+   1.0.4a-f                 1.0.4a-f 10005  2.1.0.4a-f
+   1.0.5 (+ 2 patches)      1.0.5    10005  2.1.0.5
+   1.0.5a-d                 1.0.5a-d 10006  2.1.0.5a-d
+   1.0.5e-r                 1.0.5e-r 10100  2.1.0.5e-r (not compatible)
+   1.0.5s-v                 1.0.5s-v 10006  2.1.0.5s-v (compatible)
+   1.0.6 (+ 3 patches)      1.0.6    10006  2.1.0.6
+   1.0.6d                   1.0.6d   10007  2.1.0.6d
+   1.0.7                    1.0.7    10007  2.1.0.7    (still compatible)
+
+   Henceforth the source version will match the shared-library minor
+   and patch numbers; the shared-library major version number will be
+   used for changes in backward compatibility, as it is intended.  The
+   PNG_PNGLIB_VER macro, which is not used within libpng but is available
+   for applications, is an unsigned integer of the form xyyzz corresponding
+   to the source version x.y.z (leading zeros in y and z).  Beta versions
+   are given the previous public release number plus a letter or two.
+
 .SH "SEE ALSO"
 libpngpf(3), png(5)
 .LP
 .IR libpng :
 .IP
 ftp://ftp.uu.net/graphics/png
-http://www.cdrom.com/pub/png
+http://www.libpng.org/pub/png
 
 .LP
 .IR zlib :
@@ -2539,7 +3547,7 @@
 .br
 ftp://ftp.uu.net/pub/archiving/zip/zlib
 .br
-http://www.cdrom.com/pub/infozip/zlib
+ftp://ftp.info-zip.org/pub/infozip/zlib
 
 .LP
 .IR PNG specification: RFC 2083
@@ -2560,36 +3568,84 @@
 
 .SH AUTHORS
 This man page: Glenn Randers-Pehrson
-<randeg at alumni.rpi.edu>
-  
-Contributing Authors: John Bowler, Kevin Bracey, Sam Bushell, Andreas Dilger,
-Magnus Holmgren, Tom Lane, Dave Martindale, Glenn Randers-Pehrson,
-Greg Roelofs, Guy Eric Schalnat, Paul Schmidt, Tom Tanner, Willem van
-Schaik, Tim Wegner.
-<png-implement at dworkin.wustl.edu>
+<randeg at alum.rpi.edu>
 
 The contributing authors would like to thank all those who helped
 with testing, bug fixes, and patience.  This wouldn't have been
 possible without all of you.
 
 Thanks to Frank J. T. Wojcik for helping with the documentation.
-  
-Libpng version 1.0.3 - January 14, 1999:
+
+Libpng version 1.0.9 - January 31, 2001:
 Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
-Currently maintained by Glenn Randers-Pehrson (randeg at alumni.rpi.edu).
+Currently maintained by Glenn Randers-Pehrson (randeg at alum.rpi.edu).
 
 Supported by the PNG development group
 .br
-(png-implement at dworkin.wustl.edu).
+(png-implement at ccrc.wustl.edu).
 
-.SH COPYRIGHT NOTICE:
+.SH COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
 
-Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
-Copyright (c) 1996, 1997 Andreas Dilger
+(This copy of the libpng notices is provided for your convenience.  In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.)
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+libpng versions 1.0.7, July 1, 2000, through  1.0.9, January 31, 2001, are
+Copyright (c) 2000 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.0.6
+with the following individuals added to the list of Contributing Authors
+
+   Simon-Pierre Cadieux
+   Eric S. Raymond
+   Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+   There is no warranty against interference with your enjoyment of the
+   library or against infringement.  There is no warranty that our
+   efforts or the library will fulfill any of your particular purposes
+   or needs.  This library is provided with all faults, and the entire
+   risk of satisfactory quality, performance, accuracy, and effort is with
+   the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
 Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+Distributed according to the same disclaimer and license as libpng-0.96,
+with the following individuals added to the list of Contributing Authors:
+
+   Tom Lane
+   Glenn Randers-Pehrson
+   Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,
+with the following individuals added to the list of Contributing Authors:
 
-The PNG Reference Library (libpng) is supplied "AS IS".  The Contributing
-Authors and Group 42, Inc. disclaim all warranties, expressed or implied,
+   John Bowler
+   Kevin Bracey
+   Sam Bushell
+   Magnus Holmgren
+   Greg Roelofs
+   Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+   Andreas Dilger
+   Dave Martindale
+   Guy Eric Schalnat
+   Paul Schmidt
+   Tim Wegner
+
+The PNG Reference Library is supplied "AS IS".  The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
 including, without limitation, the warranties of merchantability and of
 fitness for any purpose.  The Contributing Authors and Group 42, Inc.
 assume no liability for direct, indirect, incidental, special, exemplary,
@@ -2600,16 +3656,13 @@
 source code, or portions hereof, for any purpose, without fee, subject
 to the following restrictions:
 
- 1. The origin of this source code must not be
-    misrepresented.
+1. The origin of this source code must not be misrepresented.
+
+2. Altered versions must be plainly marked as such and must not
+   be misrepresented as being the original source.
 
- 2. Altered versions must be plainly marked as such
-    and must not be misrepresented as being the
-    original source.
-
- 3. This Copyright notice may not be removed or
-    altered from any source or altered source
-    distribution.
+3. This Copyright notice may not be removed or altered from any
+   source or altered source distribution.
 
 The Contributing Authors and Group 42, Inc. specifically permit, without
 fee, and encourage the use of this source code as a component to
@@ -2617,5 +3670,21 @@
 source code in a product, acknowledgment is not required but would be
 appreciated.
 
+
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+   printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is a
+certification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+randeg at alum.rpi.edu
+January 31, 2001
+
 .\" end of man page
 

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/example.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/example.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/example.c	Sat Jul 13 21:26:47 2002
@@ -1,20 +1,33 @@
 
+#if 0 /* in case someone actually tries to compile this */
+
 /* example.c - an example of using libpng */
 
 /* This is an example of how to use libpng to read and write PNG files.
  * The file libpng.txt is much more verbose then this.  If you have not
  * read it, do so first.  This was designed to be a starting point of an
- * implementation.  This is not officially part of libpng, and therefore
- * does not require a copyright notice.
+ * implementation.  This is not officially part of libpng, is hereby placed
+ * in the public domain, and therefore does not require a copyright notice.
  *
  * This file does not currently compile, because it is missing certain
  * parts, like allocating memory to hold an image.  You will have to
  * supply these parts to get it to compile.  For an example of a minimal
- * working PNG reader/writer, see pngtest.c, included in this distribution.
+ * working PNG reader/writer, see pngtest.c, included in this distribution;
+ * see also the programs in the contrib directory.
  */
 
 #include "png.h"
 
+ /* The png_jmpbuf() macro, used in error handling, became available in
+  * libpng version 1.0.6.  If you want to be able to run your code with older
+  * versions of libpng, you must define the macro yourself (but only if it
+  * is not already defined by libpng!).
+  */
+
+#ifndef png_jmpbuf
+#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
+#endif
+
 /* Check to see if a file is a PNG file using png_sig_cmp().  png_sig_cmp()
  * returns zero if the image is a PNG and nonzero if it isn't a PNG.
  *
@@ -41,7 +54,7 @@
    char buf[PNG_BYTES_TO_CHECK];
 
    /* Open the prospective PNG file. */
-   if ((*fp = fopen(file_name, "rb")) != NULL);
+   if ((*fp = fopen(file_name, "rb")) == NULL)
       return 0;
 
    /* Read in some of the signature bytes */
@@ -71,7 +84,7 @@
    FILE *fp;
 
    if ((fp = fopen(file_name, "rb")) == NULL)
-      return;
+      return (ERROR);
 #else no_open_file /* prototype 2 */
 void read_png(FILE *fp, unsigned int sig_read)  /* file is already open */
 {
@@ -93,7 +106,7 @@
    if (png_ptr == NULL)
    {
       fclose(fp);
-      return;
+      return (ERROR);
    }
 
    /* Allocate/initialize the memory for image information.  REQUIRED. */
@@ -102,20 +115,21 @@
    {
       fclose(fp);
       png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
-      return;
+      return (ERROR);
    }
 
    /* Set error handling if you are using the setjmp/longjmp method (this is
     * the normal method of doing things with libpng).  REQUIRED unless you
     * set up your own error handlers in the png_create_read_struct() earlier.
     */
-   if (setjmp(png_ptr->jmpbuf))
+
+   if (setjmp(png_jmpbuf(png_ptr)))
    {
       /* Free all of the memory associated with the png_ptr and info_ptr */
       png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
       fclose(fp);
       /* If we get here, we had a problem reading the file */
-      return;
+      return (ERROR);
    }
 
    /* One of the following I/O initialization methods is REQUIRED */
@@ -134,6 +148,19 @@
    /* If we have already read some of the signature */
    png_set_sig_bytes(png_ptr, sig_read);
 
+#ifdef hilevel
+   /*
+    * If you have enough memory to read in the entire image at once,
+    * and you need to specify only transforms that can be controlled
+    * with one of the PNG_TRANSFORM_* bits (this presently excludes
+    * dithering, filling, setting background, and doing gamma
+    * adjustment), then you can read the entire image (including
+    * pixels) into the info structure with this call:
+    */
+   png_read_png(png_ptr, info_ptr, png_transforms, NULL);
+#else
+   /* OK, you're doing it the hard way, with the lower-level functions */
+
    /* The call to png_read_info() gives us all of the information from the
     * PNG file before the first IDAT (image data chunk).  REQUIRED
     */
@@ -151,7 +178,7 @@
    /* tell libpng to strip 16 bit/color files down to 8 bits/color */
    png_set_strip_16(png_ptr);
 
-   /* Strip alpha bytes from the input data without combining with th
+   /* Strip alpha bytes from the input data without combining with the
     * background (not recommended).
     */
    png_set_strip_alpha(png_ptr);
@@ -197,7 +224,8 @@
 
    /* Some suggestions as to how to get a screen gamma value */
 
-   /* Note that screen gamma is (display_gamma/viewing_gamma) */
+   /* Note that screen gamma is the display_exponent, which includes
+    * the CRT_exponent and any correction for viewing conditions */
    if (/* We have a user-defined screen gamma value */)
    {
       screen_gamma = user-defined screen_gamma;
@@ -215,7 +243,7 @@
       screen_gamma = 1.7 or 1.0;  /* A good guess for Mac systems */
    }
 
-   /* Tell libpng to handle the gamma conversion for you.  The second call
+   /* Tell libpng to handle the gamma conversion for you.  The final call
     * is a good guess for PC generated images, but it should be configurable
     * by the user at run time by the user.  It is strongly suggested that
     * your application support gamma correction.
@@ -224,7 +252,7 @@
    int intent;
 
    if (png_get_sRGB(png_ptr, info_ptr, &intent))
-      png_set_sRGB(png_ptr, intent, 0);
+      png_set_gamma(png_ptr, screen_gamma, 0.45455);
    else
    {
       double image_gamma;
@@ -239,7 +267,7 @@
     */
    if (color_type & PNG_COLOR_MASK_COLOR)
    {
-      png_uint_32 num_palette;
+      int num_palette;
       png_colorp palette;
 
       /* This reduces the image to the application supplied palette */
@@ -254,7 +282,7 @@
       /* This reduces the image to the palette supplied in the file */
       else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette))
       {
-         png_color16p histogram;
+         png_uint_16p histogram;
 
          png_get_hIST(png_ptr, info_ptr, &histogram);
 
@@ -263,7 +291,7 @@
       }
    }
 
-   /* invert monocrome files to have 0 as white and 1 as black */
+   /* invert monochrome files to have 0 as white and 1 as black */
    png_set_invert_mono(png_ptr);
 
    /* If you want to shift the pixel values from the range [0,255] or
@@ -272,14 +300,15 @@
     */
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
    {
-      png_color8p sig_bit;
+      png_color_8p sig_bit;
 
       png_get_sBIT(png_ptr, info_ptr, &sig_bit);
       png_set_shift(png_ptr, sig_bit);
    }
 
    /* flip the RGB pixels to BGR (or RGBA to BGRA) */
-   png_set_bgr(png_ptr);
+   if (color_type & PNG_COLOR_MASK_COLOR)
+      png_set_bgr(png_ptr);
 
    /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
    png_set_swap_alpha(png_ptr);
@@ -347,6 +376,9 @@
 
    /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
    png_read_end(png_ptr, info_ptr);
+#endif hilevel
+
+   /* At this point you have read the entire image */
 
    /* clean up after the read, and free any memory allocated - REQUIRED */
    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
@@ -355,7 +387,7 @@
    fclose(fp);
 
    /* that's it */
-   return;
+   return (OK);
 }
 
 /* progressively read a file */
@@ -375,7 +407,7 @@
    if (*png_ptr == NULL)
    {
       *info_ptr = NULL;
-      return ERROR;
+      return (ERROR);
    }
 
    *info_ptr = png_create_info_struct(png_ptr);
@@ -383,13 +415,13 @@
    if (*info_ptr == NULL)
    {
       png_destroy_read_struct(png_ptr, info_ptr, (png_infopp)NULL);
-      return ERROR;
+      return (ERROR);
    }
 
-   if (setjmp((*png_ptr)->jmpbuf))
+   if (setjmp(png_jmpbuf((*png_ptr))))
    {
       png_destroy_read_struct(png_ptr, info_ptr, (png_infopp)NULL);
-      return ERROR;
+      return (ERROR);
    }
 
    /* This one's new.  You will need to provide all three
@@ -407,18 +439,18 @@
    png_set_progressive_read_fn(*png_ptr, (void *)stream_data,
       info_callback, row_callback, end_callback);
 
-   return OK;
+   return (OK);
 }
 
 int
 process_data(png_structp *png_ptr, png_infop *info_ptr,
    png_bytep buffer, png_uint_32 length)
 {
-   if (setjmp((*png_ptr)->jmpbuf))
+   if (setjmp(png_jmpbuf((*png_ptr))))
    {
       /* Free the png_ptr and info_ptr memory on error */
       png_destroy_read_struct(png_ptr, info_ptr, (png_infopp)NULL);
-      return ERROR;
+      return (ERROR);
    }
 
    /* This one's new also.  Simply give it chunks of data as
@@ -432,7 +464,7 @@
     * callback, if you aren't already displaying them there.
     */
    png_process_data(*png_ptr, *info_ptr, buffer, length);
-   return OK;
+   return (OK);
 }
 
 info_callback(png_structp png_ptr, png_infop info)
@@ -496,11 +528,12 @@
    FILE *fp;
    png_structp png_ptr;
    png_infop info_ptr;
+   png_colorp palette;
 
    /* open the file */
    fp = fopen(file_name, "wb");
    if (fp == NULL)
-      return;
+      return (ERROR);
 
    /* Create and initialize the png_struct with the desired error handler
     * functions.  If you want to use the default stderr and longjump method,
@@ -514,7 +547,7 @@
    if (png_ptr == NULL)
    {
       fclose(fp);
-      return;
+      return (ERROR);
    }
 
    /* Allocate/initialize the image information data.  REQUIRED */
@@ -523,18 +556,18 @@
    {
       fclose(fp);
       png_destroy_write_struct(&png_ptr,  (png_infopp)NULL);
-      return;
+      return (ERROR);
    }
 
    /* Set error handling.  REQUIRED if you aren't supplying your own
-    * error hadnling functions in the png_create_write_struct() call.
+    * error handling functions in the png_create_write_struct() call.
     */
-   if (setjmp(png_ptr->jmpbuf))
+   if (setjmp(png_jmpbuf(png_ptr)))
    {
       /* If we get here, we had a problem reading the file */
       fclose(fp);
-      png_destroy_write_struct(&png_ptr,  (png_infopp)NULL);
-      return;
+      png_destroy_write_struct(&png_ptr, &info_ptr);
+      return (ERROR);
    }
 
    /* One of the following I/O initialization functions is REQUIRED */
@@ -549,6 +582,15 @@
    /* where user_io_ptr is a structure you want available to the callbacks */
 #endif no_streams /* only use one initialization method */
 
+#ifdef hilevel
+   /* This is the easy way.  Use it if you already have all the
+    * image info living info in the structure.  You could "|" many
+    * PNG_TRANSFORM flags into the png_transforms integer here.
+    */
+   png_write_png(png_ptr, info_ptr, png_transforms, NULL);
+#else
+   /* This is the hard way */
+
    /* Set the image information here.  Width and height are up to 2^31,
     * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
     * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
@@ -561,9 +603,12 @@
       PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
 
    /* set the palette if there is one.  REQUIRED for indexed-color images */
-   palette = (png_colorp)png_malloc(png_ptr, 256 * sizeof (png_color));
+   palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * sizeof (png_color));
    /* ... set palette colors ... */
-   png_set_PLTE(png_ptr, info_ptr, palette, 256);
+   png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);
+   /* You must not free palette here, because png_set_PLTE only makes a link to
+      the palette that you malloced.  Wait until you are about to destroy
+      the png structure. */
 
    /* optional significant bit chunk */
    /* if we are dealing with a grayscale image then */
@@ -592,15 +637,31 @@
    text_ptr[2].key = "Description";
    text_ptr[2].text = "<long text>";
    text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;
+#ifdef PNG_iTXt_SUPPORTED
+   text_ptr[0].lang = NULL;
+   text_ptr[1].lang = NULL;
+   text_ptr[2].lang = NULL;
+#endif
    png_set_text(png_ptr, info_ptr, text_ptr, 3);
 
    /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */
-   /* note that if sRGB is present the cHRM chunk must be ignored
+   /* note that if sRGB is present the gAMA and cHRM chunks must be ignored
     * on read and must be written in accordance with the sRGB profile */
 
    /* Write the file header information.  REQUIRED */
    png_write_info(png_ptr, info_ptr);
 
+   /* If you want, you can write the info in two steps, in case you need to
+    * write your private chunk ahead of PLTE:
+    *
+    *   png_write_info_before_PLTE(write_ptr, write_info_ptr);
+    *   write_my_chunk();
+    *   png_write_info(png_ptr, info_ptr);
+    *
+    * However, given the level of known- and unknown-chunk support in 1.1.0
+    * and up, this should no longer be necessary.
+    */
+
    /* Once we write out the header, the compression type on the text
     * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
     * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
@@ -611,7 +672,7 @@
     * all optional.  Only call them if you want them.
     */
 
-   /* invert monocrome pixels */
+   /* invert monochrome pixels */
    png_set_invert_mono(png_ptr);
 
    /* Shift the pixels up to a legal bit depth and fill in
@@ -650,10 +711,10 @@
     * use the first method if you aren't handling interlacing yourself.
     */
    png_uint_32 k, height, width;
-   png_byte image[height][width];
+   png_byte image[height][width*bytes_per_pixel];
    png_bytep row_pointers[height];
    for (k = 0; k < height; k++)
-     row_pointers[k] = image + k*width;
+     row_pointers[k] = image + k*width*bytes_per_pixel;
 
    /* One of the following output methods is REQUIRED */
 #ifdef entire /* write out the entire image data in one call */
@@ -679,24 +740,37 @@
 #endif no_entire /* use only one output method */
 
    /* You can write optional chunks like tEXt, zTXt, and tIME at the end
-    * as well.
+    * as well.  Shouldn't be necessary in 1.1.0 and up as all the public
+    * chunks are supported and you can use png_set_unknown_chunks() to
+    * register unknown chunks into the info structure to be written out.
     */
 
    /* It is REQUIRED to call this to finish writing the rest of the file */
    png_write_end(png_ptr, info_ptr);
+#endif hilevel
 
-   /* if you malloced the palette, free it here */
-   free(info_ptr->palette);
-
-   /* if you allocated any text comments, free them here */
+   /* If you png_malloced a palette, free it here (don't free info_ptr->palette,
+      as recommended in versions 1.0.5m and earlier of this example; if
+      libpng mallocs info_ptr->palette, libpng will free it).  If you
+      allocated it with malloc() instead of png_malloc(), use free() instead
+      of png_free(). */
+   png_free(png_ptr, palette);
+   palette=NULL;
+
+   /* Similarly, if you png_malloced any data that you passed in with
+      png_set_something(), such as a hist or trans array, free it here,
+      when you can be sure that libpng is through with it. */
+   png_free(png_ptr, trans);
+   trans=NULL;
 
    /* clean up after the write, and free any memory allocated */
-   png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+   png_destroy_write_struct(&png_ptr, &info_ptr);
 
    /* close the file */
    fclose(fp);
 
    /* that's it */
-   return;
+   return (OK);
 }
 
+#endif /* if 0 */

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngtrans.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngtrans.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngtrans.c	Sat Jul 13 21:26:48 2002
@@ -1,19 +1,19 @@
 
 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  */
 
 #define PNG_INTERNAL
 #include "png.h"
 
 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
-/* turn on bgr to rgb mapping */
-void
+/* turn on BGR-to-RGB mapping */
+void PNGAPI
 png_set_bgr(png_structp png_ptr)
 {
    png_debug(1, "in png_set_bgr\n");
@@ -23,7 +23,7 @@
 
 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
 /* turn on 16 bit byte swapping */
-void
+void PNGAPI
 png_set_swap(png_structp png_ptr)
 {
    png_debug(1, "in png_set_swap\n");
@@ -34,7 +34,7 @@
 
 #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
 /* turn on pixel packing */
-void
+void PNGAPI
 png_set_packing(png_structp png_ptr)
 {
    png_debug(1, "in png_set_packing\n");
@@ -48,7 +48,7 @@
 
 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
 /* turn on packed pixel swapping */
-void
+void PNGAPI
 png_set_packswap(png_structp png_ptr)
 {
    png_debug(1, "in png_set_packswap\n");
@@ -58,7 +58,7 @@
 #endif
 
 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
-void
+void PNGAPI
 png_set_shift(png_structp png_ptr, png_color_8p true_bits)
 {
    png_debug(1, "in png_set_shift\n");
@@ -69,7 +69,7 @@
 
 #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
     defined(PNG_WRITE_INTERLACING_SUPPORTED)
-int
+int PNGAPI
 png_set_interlace_handling(png_structp png_ptr)
 {
    png_debug(1, "in png_set_interlace handling\n");
@@ -89,7 +89,7 @@
  * for 48-bit input data, as well as to avoid problems with some compilers
  * that don't like bytes as parameters.
  */
-void
+void PNGAPI
 png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
 {
    png_debug(1, "in png_set_filler\n");
@@ -122,7 +122,7 @@
 
 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
     defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
-void
+void PNGAPI
 png_set_swap_alpha(png_structp png_ptr)
 {
    png_debug(1, "in png_set_swap_alpha\n");
@@ -132,7 +132,7 @@
 
 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
     defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
-void
+void PNGAPI
 png_set_invert_alpha(png_structp png_ptr)
 {
    png_debug(1, "in png_set_invert_alpha\n");
@@ -141,7 +141,7 @@
 #endif
 
 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
-void
+void PNGAPI
 png_set_invert_mono(png_structp png_ptr)
 {
    png_debug(1, "in png_set_invert_mono\n");
@@ -149,7 +149,7 @@
 }
 
 /* invert monochrome grayscale data */
-void
+void /* PRIVATE */
 png_do_invert(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_invert\n");
@@ -174,7 +174,7 @@
 
 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
 /* swaps byte order on 16 bit depth images */
-void
+void /* PRIVATE */
 png_do_swap(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_swap\n");
@@ -305,7 +305,7 @@
 };
 
 /* swaps pixel packing order within bytes */
-void
+void /* PRIVATE */
 png_do_packswap(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_packswap\n");
@@ -337,7 +337,7 @@
 #if defined(PNG_WRITE_FILLER_SUPPORTED) || \
     defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
 /* remove filler or alpha byte(s) */
-void
+void /* PRIVATE */
 png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
 {
    png_debug(1, "in png_do_strip_filler\n");
@@ -495,7 +495,7 @@
 
 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
 /* swaps red and blue bytes within a pixel */
-void
+void /* PRIVATE */
 png_do_bgr(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_bgr\n");
@@ -570,3 +570,40 @@
 }
 #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
 
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
+void PNGAPI
+png_set_user_transform_info(png_structp png_ptr, png_voidp
+   user_transform_ptr, int user_transform_depth, int user_transform_channels)
+{
+   png_debug(1, "in png_set_user_transform_info\n");
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+   png_ptr->user_transform_ptr = user_transform_ptr;
+   png_ptr->user_transform_depth = (png_byte)user_transform_depth;
+   png_ptr->user_transform_channels = (png_byte)user_transform_channels;
+#else
+   if(user_transform_ptr || user_transform_depth || user_transform_channels)
+      png_warning(png_ptr,
+        "This version of libpng does not support user transform info");
+#endif
+}
+#endif
+
+/* This function returns a pointer to the user_transform_ptr associated with
+ * the user transform functions.  The application should free any memory
+ * associated with this pointer before png_write_destroy and png_read_destroy
+ * are called.
+ */
+png_voidp PNGAPI
+png_get_user_transform_ptr(png_structp png_ptr)
+{
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+   return ((png_voidp)png_ptr->user_transform_ptr);
+#else
+   if(png_ptr)
+     return (NULL);
+   return (NULL);
+#endif
+}
+

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngrio.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngrio.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngrio.c	Sat Jul 13 21:26:48 2002
@@ -1,11 +1,11 @@
 
 /* pngrio.c - functions for data input
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This file provides a location for all input.  Users who need
  * special handling are expected to write a function that has the same
@@ -23,7 +23,7 @@
    with very small lengths, so you should implement some kind of simple
    buffering if you are using unbuffered reads.  This should never be asked
    to read more then 64K on a 16 bit machine. */
-void
+void /* PRIVATE */
 png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
 {
    png_debug1(4,"reading %d bytes\n", length);
@@ -39,7 +39,7 @@
    read_data function and use it at run time with png_set_read_fn(), rather
    than changing the library. */
 #ifndef USE_FAR_KEYWORD
-static void
+static void /* PRIVATE */
 png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
 {
    png_size_t check;
@@ -47,13 +47,16 @@
    /* fread() returns 0 on error, so it is OK to store this in a png_size_t
     * instead of an int, which is what fread() actually returns.
     */
+#if defined(_WIN32_WCE)
+   if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+      check = 0;
+#else
    check = (png_size_t)fread(data, (png_size_t)1, length,
-      (FILE *)png_ptr->io_ptr);
+      (png_FILE_p)png_ptr->io_ptr);
+#endif
 
    if (check != length)
-   {
       png_error(png_ptr, "Read Error");
-   }
 }
 #else
 /* this is the model-independent version. Since the standard I/O library
@@ -64,19 +67,24 @@
 #define NEAR_BUF_SIZE 1024
 #define MIN(a,b) (a <= b ? a : b)
 
-static void
+static void /* PRIVATE */
 png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
 {
    int check;
    png_byte *n_data;
-   FILE *io_ptr;
+   png_FILE_p io_ptr;
 
    /* Check if data really is near. If so, use usual code. */
    n_data = (png_byte *)CVT_PTR_NOCHECK(data);
-   io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
+   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
    if ((png_bytep)n_data == data)
    {
+#if defined(_WIN32_WCE)
+      if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+         check = 0;
+#else
       check = fread(n_data, 1, length, io_ptr);
+#endif
    }
    else
    {
@@ -87,7 +95,12 @@
       do
       {
          read = MIN(NEAR_BUF_SIZE, remaining);
+#if defined(_WIN32_WCE)
+         if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) )
+            err = 0;
+#else
          err = fread(buf, (png_size_t)1, read, io_ptr);
+#endif
          png_memcpy(data, buf, read); /* copy far buffer to near buffer */
          if(err != read)
             break;
@@ -99,9 +112,7 @@
       while (remaining != 0);
    }
    if ((png_uint_32)check != (png_uint_32)length)
-   {
       png_error(png_ptr, "read Error");
-   }
 }
 #endif
 #endif
@@ -119,7 +130,7 @@
                   unsigned int that is the number of bytes to be read.
                   To exit and output any fatal error messages the new write
                   function should call png_error(png_ptr, "Error msg"). */
-void
+void PNGAPI
 png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
    png_rw_ptr read_data_fn)
 {
@@ -146,6 +157,6 @@
 
 #if defined(PNG_WRITE_FLUSH_SUPPORTED)
    png_ptr->output_flush_fn = NULL;
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+#endif
 }
 

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwrite.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwrite.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwrite.c	Sat Jul 13 21:26:49 2002
@@ -1,11 +1,11 @@
 
 /* pngwrite.c - general routines to write a PNG file
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  */
 
 /* get internal access to png.h */
@@ -21,15 +21,20 @@
  * write a plain PNG file.  If you have long comments, I suggest writing
  * them in png_write_end(), and compressing them.
  */
-void
-png_write_info(png_structp png_ptr, png_infop info_ptr)
+void PNGAPI
+png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
-   int i;
-#endif
-
-   png_debug(1, "in png_write_info\n");
+   png_debug(1, "in png_write_info_before_PLTE\n");
+   if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+   {
    png_write_sig(png_ptr); /* write PNG signature */
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+   if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&(png_ptr->mng_features_permitted))
+   {
+      png_warning(png_ptr,"MNG features are not allowed in a PNG datastream\n");
+      png_ptr->mng_features_permitted=0;
+   }
+#endif
    /* write IHDR information. */
    png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
       info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
@@ -43,24 +48,86 @@
       flag set, and if it does, writes the chunk. */
 #if defined(PNG_WRITE_gAMA_SUPPORTED)
    if (info_ptr->valid & PNG_INFO_gAMA)
+   {
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
       png_write_gAMA(png_ptr, info_ptr->gamma);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+      png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma);
+#  endif
+#endif
+   }
 #endif
 #if defined(PNG_WRITE_sRGB_SUPPORTED)
    if (info_ptr->valid & PNG_INFO_sRGB)
       png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
 #endif
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_iCCP)
+      png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE,
+                     info_ptr->iccp_profile, (int)info_ptr->iccp_proflen);
+#endif
 #if defined(PNG_WRITE_sBIT_SUPPORTED)
    if (info_ptr->valid & PNG_INFO_sBIT)
       png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
 #endif
 #if defined(PNG_WRITE_cHRM_SUPPORTED)
    if (info_ptr->valid & PNG_INFO_cHRM)
+   {
+#ifdef PNG_FLOATING_POINT_SUPPORTED
       png_write_cHRM(png_ptr,
          info_ptr->x_white, info_ptr->y_white,
          info_ptr->x_red, info_ptr->y_red,
          info_ptr->x_green, info_ptr->y_green,
          info_ptr->x_blue, info_ptr->y_blue);
+#else
+#  ifdef PNG_FIXED_POINT_SUPPORTED
+      png_write_cHRM_fixed(png_ptr,
+         info_ptr->int_x_white, info_ptr->int_y_white,
+         info_ptr->int_x_red, info_ptr->int_y_red,
+         info_ptr->int_x_green, info_ptr->int_y_green,
+         info_ptr->int_x_blue, info_ptr->int_y_blue);
+#  endif
 #endif
+   }
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+   if (info_ptr->unknown_chunks_num)
+   {
+       png_unknown_chunk *up;
+
+       png_debug(5, "writing extra chunks\n");
+
+       for (up = info_ptr->unknown_chunks;
+            up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+            up++)
+       {
+         int keep=png_handle_as_unknown(png_ptr, up->name);
+         if (keep != HANDLE_CHUNK_NEVER &&
+            up->location && (!(up->location & PNG_HAVE_PLTE)) &&
+            ((up->name[3] & 0x20) || keep == HANDLE_CHUNK_ALWAYS ||
+            (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+         {
+            png_write_chunk(png_ptr, up->name, up->data, up->size);
+         }
+       }
+   }
+#endif
+      png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
+   }
+}
+
+void PNGAPI
+png_write_info(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+   int i;
+#endif
+
+   png_debug(1, "in png_write_info\n");
+
+   png_write_info_before_PLTE(png_ptr, info_ptr);
+
    if (info_ptr->valid & PNG_INFO_PLTE)
       png_write_PLTE(png_ptr, info_ptr->palette,
          (png_uint_32)info_ptr->num_palette);
@@ -72,12 +139,12 @@
       {
 #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
          /* invert the alpha channel (in tRNS) */
-         if (png_ptr->transformations & PNG_INVERT_ALPHA &&
+         if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
             info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
          {
             int j;
             for (j=0; j<(int)info_ptr->num_trans; j++)
-               info_ptr->trans[j] = 255 - info_ptr->trans[j];
+               info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]);
          }
 #endif
       png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values),
@@ -103,6 +170,21 @@
          info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
          info_ptr->pcal_units, info_ptr->pcal_params);
 #endif
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_sCAL)
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
+      png_write_sCAL(png_ptr, (int)info_ptr->scal_unit,
+          info_ptr->scal_pixel_width, info_ptr->scal_pixel_height);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+      png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
+          info_ptr->scal_s_width, info_ptr->scal_s_height);
+#else
+      png_warning(png_ptr,
+          "png_write_sCAL not supported; sCAL chunk not written.\n");
+#endif
+#endif
+#endif
 #if defined(PNG_WRITE_pHYs_SUPPORTED)
    if (info_ptr->valid & PNG_INFO_pHYs)
       png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
@@ -112,22 +194,44 @@
    if (info_ptr->valid & PNG_INFO_tIME)
    {
       png_write_tIME(png_ptr, &(info_ptr->mod_time));
-      png_ptr->flags |= PNG_FLAG_WROTE_tIME;
+      png_ptr->mode |= PNG_WROTE_tIME;
    }
 #endif
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_sPLT)
+     for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+       png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
+#endif
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
    /* Check to see if we need to write text chunks */
    for (i = 0; i < info_ptr->num_text; i++)
    {
       png_debug2(2, "Writing header text chunk %d, type %d\n", i,
          info_ptr->text[i].compression);
+      /* an internationalized chunk? */
+      if (info_ptr->text[i].compression > 0)
+      {
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+          /* write international chunk */
+          png_write_iTXt(png_ptr,
+                         info_ptr->text[i].compression,
+                         info_ptr->text[i].key,
+                         info_ptr->text[i].lang,
+                         info_ptr->text[i].lang_key,
+                         info_ptr->text[i].text);
+#else
+          png_warning(png_ptr, "Unable to write international text\n");
+#endif
+          /* Mark this chunk as written */
+          info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+      }
       /* If we want a compressed text chunk */
-      if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
+      else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
       {
 #if defined(PNG_WRITE_zTXt_SUPPORTED)
          /* write compressed chunk */
          png_write_zTXt(png_ptr, info_ptr->text[i].key,
-            info_ptr->text[i].text, info_ptr->text[i].text_length,
+            info_ptr->text[i].text, 0,
             info_ptr->text[i].compression);
 #else
          png_warning(png_ptr, "Unable to write compressed text\n");
@@ -140,7 +244,8 @@
 #if defined(PNG_WRITE_tEXt_SUPPORTED)
          /* write uncompressed chunk */
          png_write_tEXt(png_ptr, info_ptr->text[i].key,
-            info_ptr->text[i].text, info_ptr->text[i].text_length);
+                         info_ptr->text[i].text,
+                         0);
 #else
          png_warning(png_ptr, "Unable to write uncompressed text\n");
 #endif
@@ -149,6 +254,29 @@
       }
    }
 #endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+   if (info_ptr->unknown_chunks_num)
+   {
+       png_unknown_chunk *up;
+
+       png_debug(5, "writing extra chunks\n");
+
+       for (up = info_ptr->unknown_chunks;
+            up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+            up++)
+       {
+         int keep=png_handle_as_unknown(png_ptr, up->name);
+         if (keep != HANDLE_CHUNK_NEVER &&
+            up->location && (up->location & PNG_HAVE_PLTE) &&
+            !(up->location & PNG_HAVE_IDAT) &&
+            ((up->name[3] & 0x20) || keep == HANDLE_CHUNK_ALWAYS ||
+            (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+         {
+            png_write_chunk(png_ptr, up->name, up->data, up->size);
+         }
+       }
+   }
+#endif
 }
 
 /* Writes the end of the PNG file.  If you don't want to write comments or
@@ -156,7 +284,7 @@
  * in png_write_info(), do not write them again here.  If you have long
  * comments, I suggest writing them here, and compressing them.
  */
-void
+void PNGAPI
 png_write_end(png_structp png_ptr, png_infop info_ptr)
 {
    png_debug(1, "in png_write_end\n");
@@ -166,27 +294,44 @@
    /* see if user wants us to write information chunks */
    if (info_ptr != NULL)
    {
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
       int i; /* local index variable */
 #endif
 #if defined(PNG_WRITE_tIME_SUPPORTED)
       /* check to see if user has supplied a time chunk */
-      if (info_ptr->valid & PNG_INFO_tIME &&
-         !(png_ptr->flags & PNG_FLAG_WROTE_tIME))
+      if ((info_ptr->valid & PNG_INFO_tIME) &&
+         !(png_ptr->mode & PNG_WROTE_tIME))
          png_write_tIME(png_ptr, &(info_ptr->mod_time));
 #endif
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
       /* loop through comment chunks */
       for (i = 0; i < info_ptr->num_text; i++)
       {
          png_debug2(2, "Writing trailer text chunk %d, type %d\n", i,
             info_ptr->text[i].compression);
-         if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
+         /* an internationalized chunk? */
+         if (info_ptr->text[i].compression > 0)
+         {
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+             /* write international chunk */
+             png_write_iTXt(png_ptr,
+                         info_ptr->text[i].compression,
+                         info_ptr->text[i].key,
+                         info_ptr->text[i].lang,
+                         info_ptr->text[i].lang_key,
+                         info_ptr->text[i].text);
+#else
+             png_warning(png_ptr, "Unable to write international text\n");
+#endif
+             /* Mark this chunk as written */
+             info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+         }
+         else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
          {
 #if defined(PNG_WRITE_zTXt_SUPPORTED)
             /* write compressed chunk */
             png_write_zTXt(png_ptr, info_ptr->text[i].key,
-               info_ptr->text[i].text, info_ptr->text[i].text_length,
+               info_ptr->text[i].text, 0,
                info_ptr->text[i].compression);
 #else
             png_warning(png_ptr, "Unable to write compressed text\n");
@@ -199,7 +344,7 @@
 #if defined(PNG_WRITE_tEXt_SUPPORTED)
             /* write uncompressed chunk */
             png_write_tEXt(png_ptr, info_ptr->text[i].key,
-               info_ptr->text[i].text, info_ptr->text[i].text_length);
+               info_ptr->text[i].text, 0);
 #else
             png_warning(png_ptr, "Unable to write uncompressed text\n");
 #endif
@@ -209,16 +354,45 @@
          }
       }
 #endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+   if (info_ptr->unknown_chunks_num)
+   {
+       png_unknown_chunk *up;
+
+       png_debug(5, "writing extra chunks\n");
+
+       for (up = info_ptr->unknown_chunks;
+            up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+            up++)
+       {
+         int keep=png_handle_as_unknown(png_ptr, up->name);
+         if (keep != HANDLE_CHUNK_NEVER &&
+            up->location && (up->location & PNG_AFTER_IDAT) &&
+            ((up->name[3] & 0x20) || keep == HANDLE_CHUNK_ALWAYS ||
+            (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+         {
+            png_write_chunk(png_ptr, up->name, up->data, up->size);
+         }
+       }
+   }
+#endif
    }
 
    png_ptr->mode |= PNG_AFTER_IDAT;
 
    /* write end of PNG file */
    png_write_IEND(png_ptr);
+#if 0
+/* This flush, added in libpng-1.0.8,  causes some applications to crash
+   because they do not set png_ptr->output_flush_fn */
+   png_flush(png_ptr);
+#endif
 }
 
 #if defined(PNG_WRITE_tIME_SUPPORTED)
-void
+#if !defined(_WIN32_WCE)
+/* "time.h" functions are not supported on WindowsCE */
+void PNGAPI
 png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime)
 {
    png_debug(1, "in png_convert_from_struct_tm\n");
@@ -230,7 +404,7 @@
    ptime->second = (png_byte)ttime->tm_sec;
 }
 
-void
+void PNGAPI
 png_convert_from_time_t(png_timep ptime, time_t ttime)
 {
    struct tm *tbuf;
@@ -240,9 +414,10 @@
    png_convert_from_struct_tm(ptime, tbuf);
 }
 #endif
+#endif
 
 /* Initialize png_ptr structure, and allocate any memory needed */
-png_structp
+png_structp PNGAPI
 png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr,
    png_error_ptr error_fn, png_error_ptr warn_fn)
 {
@@ -252,16 +427,19 @@
 }
 
 /* Alternate initialize png_ptr structure, and allocate any memory needed */
-png_structp
+png_structp PNGAPI
 png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
    png_malloc_ptr malloc_fn, png_free_ptr free_fn)
 {
 #endif /* PNG_USER_MEM_SUPPORTED */
    png_structp png_ptr;
+#ifdef PNG_SETJMP_SUPPORTED
 #ifdef USE_FAR_KEYWORD
    jmp_buf jmpbuf;
 #endif
+#endif
+   int i;
    png_debug(1, "in png_create_write_struct\n");
 #ifdef PNG_USER_MEM_SUPPORTED
    if ((png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
@@ -272,6 +450,8 @@
    {
       return ((png_structp)NULL);
    }
+
+#ifdef PNG_SETJMP_SUPPORTED
 #ifdef USE_FAR_KEYWORD
    if (setjmp(jmpbuf))
 #else
@@ -279,27 +459,52 @@
 #endif
    {
       png_free(png_ptr, png_ptr->zbuf);
+      png_ptr->zbuf=NULL;
       png_destroy_struct(png_ptr);
       return ((png_structp)NULL);
    }
 #ifdef USE_FAR_KEYWORD
    png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
 #endif
+#endif
+
 #ifdef PNG_USER_MEM_SUPPORTED
    png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
 #endif /* PNG_USER_MEM_SUPPORTED */
    png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
 
-   /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
-    * we must recompile any applications that use any older library version.
-    * For versions after libpng 1.0, we will be compatible, so we need
-    * only check the first digit.
-    */
-   if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
-       (png_libpng_ver[0] == '0' && user_png_ver[2] < '9'))
+   i=0;
+   do
    {
-      png_error(png_ptr,
-         "Incompatible libpng version in application and library");
+     if(user_png_ver[i] != png_libpng_ver[i])
+        png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+   } while (png_libpng_ver[i++]);
+
+   if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
+   {
+     /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+      * we must recompile any applications that use any older library version.
+      * For versions after libpng 1.0, we will be compatible, so we need
+      * only check the first digit.
+      */
+     if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+         (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+     {
+        png_error(png_ptr,
+           "Incompatible libpng version in application and library");
+     }
+
+     /* Libpng 1.0.6 was not binary compatible, due to insertion of the
+        info_ptr->free_me member.  Note to maintainer: this test can be
+        removed from version 2.0.0 and beyond because the previous test
+        would have already rejected it. */
+
+     if (user_png_ver[4] == '6' && user_png_ver[2] == '0' &&
+         user_png_ver[0] == '1' && user_png_ver[5] == '\0')
+     {
+        png_error(png_ptr,
+           "Application must be recompiled; version 1.0.6 was incompatible");
+     }
    }
 
    /* initialize zbuf - compression buffer */
@@ -318,20 +523,58 @@
 }
 
 /* Initialize png_ptr structure, and allocate any memory needed */
-void
+#undef png_write_init
+void PNGAPI
 png_write_init(png_structp png_ptr)
 {
+   /* We only come here via pre-1.0.7-compiled applications */
+   png_write_init_2(png_ptr, "1.0.0", 10000, 10000);
+}
+
+void PNGAPI
+png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver,
+   png_size_t png_struct_size, png_size_t png_info_size)
+{
+#ifdef PNG_SETJMP_SUPPORTED
    jmp_buf tmp_jmp; /* to save current jump buffer */
+#endif
+   int i = 0;
+   do
+   {
+     if (user_png_ver[i] != png_libpng_ver[i])
+     {
+#ifdef PNG_LEGACY_SUPPORTED
+       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+#else
+       png_ptr->error_fn=(png_error_ptr)NULL;
+       png_error(png_ptr,
+       "Application uses deprecated png_write_init() and must be recompiled.");
+#endif
+     }
+   } while (png_libpng_ver[i++]);
+
+   if (sizeof(png_struct) > png_struct_size ||
+      sizeof(png_info) > png_info_size)
+     {
+       png_ptr->error_fn=(png_error_ptr)NULL;
+       png_error(png_ptr,
+      "Application and library have different sized structs. Please recompile.");
+     }
+
+   png_debug(1, "in png_write_init_2\n");
 
-   png_debug(1, "in png_write_init\n");
+#ifdef PNG_SETJMP_SUPPORTED
    /* save jump buffer and error functions */
    png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
+#endif
 
    /* reset all variables to 0 */
    png_memset(png_ptr, 0, sizeof (png_struct));
 
+#ifdef PNG_SETJMP_SUPPORTED
    /* restore jump buffer */
    png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
+#endif
 
    /* initialize zbuf - compression buffer */
    png_ptr->zbuf_size = PNG_ZBUF_SIZE;
@@ -350,7 +593,7 @@
  * have called png_set_interlace_handling(), you will have to
  * "write" the image seven times.
  */
-void
+void PNGAPI
 png_write_rows(png_structp png_ptr, png_bytepp row,
    png_uint_32 num_rows)
 {
@@ -368,7 +611,7 @@
 /* Write the image.  You only need to call this function once, even
  * if you are writing an interlaced image.
  */
-void
+void PNGAPI
 png_write_image(png_structp png_ptr, png_bytepp image)
 {
    png_uint_32 i; /* row index */
@@ -395,7 +638,7 @@
 }
 
 /* called by user to write a row of image data */
-void
+void PNGAPI
 png_write_row(png_structp png_ptr, png_bytep row)
 {
    png_debug2(1, "in png_write_row (row %ld, pass %d)\n",
@@ -443,49 +686,49 @@
       switch (png_ptr->pass)
       {
          case 0:
-            if (png_ptr->row_number & 7)
+            if (png_ptr->row_number & 0x07)
             {
                png_write_finish_row(png_ptr);
                return;
             }
             break;
          case 1:
-            if ((png_ptr->row_number & 7) || png_ptr->width < 5)
+            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
             {
                png_write_finish_row(png_ptr);
                return;
             }
             break;
          case 2:
-            if ((png_ptr->row_number & 7) != 4)
+            if ((png_ptr->row_number & 0x07) != 4)
             {
                png_write_finish_row(png_ptr);
                return;
             }
             break;
          case 3:
-            if ((png_ptr->row_number & 3) || png_ptr->width < 3)
+            if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
             {
                png_write_finish_row(png_ptr);
                return;
             }
             break;
          case 4:
-            if ((png_ptr->row_number & 3) != 2)
+            if ((png_ptr->row_number & 0x03) != 2)
             {
                png_write_finish_row(png_ptr);
                return;
             }
             break;
          case 5:
-            if ((png_ptr->row_number & 1) || png_ptr->width < 2)
+            if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
             {
                png_write_finish_row(png_ptr);
                return;
             }
             break;
          case 6:
-            if (!(png_ptr->row_number & 1))
+            if (!(png_ptr->row_number & 0x01))
             {
                png_write_finish_row(png_ptr);
                return;
@@ -507,11 +750,11 @@
       (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
 
    png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type);
-   png_debug1(3, "row_info->width = %d\n", png_ptr->row_info.width);
+   png_debug1(3, "row_info->width = %lu\n", png_ptr->row_info.width);
    png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels);
    png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth);
    png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth);
-   png_debug1(3, "row_info->rowbytes = %d\n", png_ptr->row_info.rowbytes);
+   png_debug1(3, "row_info->rowbytes = %lu\n", png_ptr->row_info.rowbytes);
 
    /* Copy user's row into buffer, leaving room for filter byte. */
    png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row,
@@ -537,6 +780,24 @@
    if (png_ptr->transformations)
       png_do_write_transformations(png_ptr);
 
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+   /* Write filter_method 64 (intrapixel differencing) only if
+    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+    * 2. Libpng did not write a PNG signature (this filter_method is only
+    *    used in PNG datastreams that are embedded in MNG datastreams) and
+    * 3. The application called png_permit_mng_features with a mask that
+    *    included PNG_FLAG_MNG_FILTER_64 and
+    * 4. The filter_method is 64 and
+    * 5. The color_type is RGB or RGBA
+    */
+   if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+      (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+   {
+      /* Intrapixel differencing */
+      png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
+   }
+#endif
+
    /* Find a filter if necessary, filter the row and write it out. */
    png_write_find_filter(png_ptr, &(png_ptr->row_info));
 
@@ -546,7 +807,7 @@
 
 #if defined(PNG_WRITE_FLUSH_SUPPORTED)
 /* Set the automatic flush interval or 0 to turn flushing off */
-void
+void PNGAPI
 png_set_flush(png_structp png_ptr, int nrows)
 {
    png_debug(1, "in png_set_flush\n");
@@ -554,7 +815,7 @@
 }
 
 /* flush the current output buffers now */
-void
+void PNGAPI
 png_write_flush(png_structp png_ptr)
 {
    int wrote_IDAT;
@@ -607,7 +868,7 @@
 #endif /* PNG_WRITE_FLUSH_SUPPORTED */
 
 /* free all memory used by the write */
-void
+void PNGAPI
 png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
 {
    png_structp png_ptr = NULL;
@@ -630,22 +891,17 @@
 
    if (info_ptr != NULL)
    {
-#ifdef PNG_WRITE_tEXt_SUPPORTED
-      png_free(png_ptr, info_ptr->text);
-#endif
-#if defined(PNG_READ_pCAL_SUPPORTED)
-      png_free(png_ptr, info_ptr->pcal_purpose);
-      png_free(png_ptr, info_ptr->pcal_units);
-      if (info_ptr->pcal_params != NULL)
+      png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+      if (png_ptr->num_chunk_list)
       {
-         int i;
-         for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
-         {
-            png_free(png_ptr, info_ptr->pcal_params[i]);
-         }
-         png_free(png_ptr, info_ptr->pcal_params);
+         png_free(png_ptr, png_ptr->chunk_list);
+         png_ptr->chunk_list=NULL;
+         png_ptr->num_chunk_list=0;
       }
 #endif
+
 #ifdef PNG_USER_MEM_SUPPORTED
       png_destroy_struct_2((png_voidp)info_ptr, free_fn);
 #else
@@ -668,10 +924,12 @@
 
 
 /* Free any memory used in png_ptr struct (old method) */
-void
+void PNGAPI
 png_write_destroy(png_structp png_ptr)
 {
+#ifdef PNG_SETJMP_SUPPORTED
    jmp_buf tmp_jmp; /* save jump buffer */
+#endif
    png_error_ptr error_fn;
    png_error_ptr warning_fn;
    png_voidp error_ptr;
@@ -691,19 +949,23 @@
    png_free(png_ptr, png_ptr->up_row);
    png_free(png_ptr, png_ptr->avg_row);
    png_free(png_ptr, png_ptr->paeth_row);
+
 #if defined(PNG_TIME_RFC1123_SUPPORTED)
    png_free(png_ptr, png_ptr->time_buffer);
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
+#endif
+
 #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
    png_free(png_ptr, png_ptr->prev_filters);
    png_free(png_ptr, png_ptr->filter_weights);
    png_free(png_ptr, png_ptr->inv_filter_weights);
    png_free(png_ptr, png_ptr->filter_costs);
    png_free(png_ptr, png_ptr->inv_filter_costs);
-#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+#endif
 
+#ifdef PNG_SETJMP_SUPPORTED
    /* reset structure */
    png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
+#endif
 
    error_fn = png_ptr->error_fn;
    warning_fn = png_ptr->warning_fn;
@@ -721,15 +983,21 @@
    png_ptr->free_fn = free_fn;
 #endif
 
+#ifdef PNG_SETJMP_SUPPORTED
    png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
+#endif
 }
 
 /* Allow the application to select one or more row filters to use. */
-void
+void PNGAPI
 png_set_filter(png_structp png_ptr, int method, int filters)
 {
    png_debug(1, "in png_set_filter\n");
-   /* We allow 'method' only for future expansion of the base filter method. */
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+   if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+      (method == PNG_INTRAPIXEL_DIFFERENCING))
+         method = PNG_FILTER_TYPE_BASE;
+#endif
    if (method == PNG_FILTER_TYPE_BASE)
    {
       switch (filters & (PNG_ALL_FILTERS | 0x07))
@@ -756,14 +1024,14 @@
        */
       if (png_ptr->row_buf != NULL)
       {
-         if (png_ptr->do_filter & PNG_FILTER_SUB && png_ptr->sub_row == NULL)
+         if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
          {
             png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
               (png_ptr->rowbytes + 1));
             png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
          }
 
-         if (png_ptr->do_filter & PNG_FILTER_UP && png_ptr->up_row == NULL)
+         if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
          {
             if (png_ptr->prev_row == NULL)
             {
@@ -778,7 +1046,7 @@
             }
          }
 
-         if (png_ptr->do_filter & PNG_FILTER_AVG && png_ptr->avg_row == NULL)
+         if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
          {
             if (png_ptr->prev_row == NULL)
             {
@@ -793,13 +1061,13 @@
             }
          }
 
-         if (png_ptr->do_filter & PNG_FILTER_PAETH &&
+         if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
              png_ptr->paeth_row == NULL)
          {
             if (png_ptr->prev_row == NULL)
             {
                png_warning(png_ptr, "Can't add Paeth filter after starting");
-               png_ptr->do_filter &= ~PNG_FILTER_PAETH;
+               png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
             }
             else
             {
@@ -825,7 +1093,7 @@
  * better compression.
  */
 #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)      /* GRR 970116 */
-void
+void PNGAPI
 png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
    int num_weights, png_doublep filter_weights,
    png_doublep filter_costs)
@@ -850,8 +1118,8 @@
       num_weights = 0;
    }
 
-   png_ptr->num_prev_filters = num_weights;
-   png_ptr->heuristic_method = heuristic_method;
+   png_ptr->num_prev_filters = (png_byte)num_weights;
+   png_ptr->heuristic_method = (png_byte)heuristic_method;
 
    if (num_weights > 0)
    {
@@ -942,7 +1210,7 @@
 }
 #endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
 
-void
+void PNGAPI
 png_set_compression_level(png_structp png_ptr, int level)
 {
    png_debug(1, "in png_set_compression_level\n");
@@ -950,7 +1218,7 @@
    png_ptr->zlib_level = level;
 }
 
-void
+void PNGAPI
 png_set_compression_mem_level(png_structp png_ptr, int mem_level)
 {
    png_debug(1, "in png_set_compression_mem_level\n");
@@ -958,7 +1226,7 @@
    png_ptr->zlib_mem_level = mem_level;
 }
 
-void
+void PNGAPI
 png_set_compression_strategy(png_structp png_ptr, int strategy)
 {
    png_debug(1, "in png_set_compression_strategy\n");
@@ -966,16 +1234,26 @@
    png_ptr->zlib_strategy = strategy;
 }
 
-void
+void PNGAPI
 png_set_compression_window_bits(png_structp png_ptr, int window_bits)
 {
    if (window_bits > 15)
       png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
+   else if (window_bits < 8)
+      png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
+#ifndef WBITS_8_OK
+   /* avoid libpng bug with 256-byte windows */
+   if (window_bits == 8)
+     {
+       png_warning(png_ptr, "Compression window is being reset to 512");
+       window_bits=9;
+     }
+#endif
    png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
    png_ptr->zlib_window_bits = window_bits;
 }
 
-void
+void PNGAPI
 png_set_compression_method(png_structp png_ptr, int method)
 {
    png_debug(1, "in png_set_compression_method\n");
@@ -985,14 +1263,14 @@
    png_ptr->zlib_method = method;
 }
 
-void
+void PNGAPI
 png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
 {
    png_ptr->write_row_fn = write_row_fn;
 }
 
 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
-void
+void PNGAPI
 png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
    write_user_transform_fn)
 {
@@ -1002,3 +1280,86 @@
 }
 #endif
 
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+void PNGAPI
+png_write_png(png_structp png_ptr, png_infop info_ptr,
+              int transforms, voidp params)
+{
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+   /* invert the alpha channel from opacity to transparency */
+   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+       png_set_invert_alpha(png_ptr);
+#endif
+
+   /* Write the file header information. */
+   png_write_info(png_ptr, info_ptr);
+
+   /* ------ these transformations don't touch the info structure ------- */
+
+#if defined(PNG_WRITE_INVERT_SUPPORTED)
+   /* invert monochrome pixels */
+   if (transforms & PNG_TRANSFORM_INVERT_MONO)
+       png_set_invert_mono(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+   /* Shift the pixels up to a legal bit depth and fill in
+    * as appropriate to correctly scale the image.
+    */
+   if ((transforms & PNG_TRANSFORM_SHIFT)
+               && (info_ptr->valid & PNG_INFO_sBIT))
+       png_set_shift(png_ptr, &info_ptr->sig_bit);
+#endif
+
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+   /* pack pixels into bytes */
+   if (transforms & PNG_TRANSFORM_PACKING)
+       png_set_packing(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+   /* swap location of alpha bytes from ARGB to RGBA */
+   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+       png_set_swap_alpha(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED)
+   /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
+    * RGB (4 channels -> 3 channels). The second parameter is not used.
+    */
+   if (transforms & PNG_TRANSFORM_STRIP_FILLER)
+       png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+#endif
+
+#if defined(PNG_WRITE_BGR_SUPPORTED)
+   /* flip BGR pixels to RGB */
+   if (transforms & PNG_TRANSFORM_BGR)
+       png_set_bgr(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_SWAP_SUPPORTED)
+   /* swap bytes of 16-bit files to most significant byte first */
+   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+       png_set_swap(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+   /* swap bits of 1, 2, 4 bit packed pixel formats */
+   if (transforms & PNG_TRANSFORM_PACKSWAP)
+       png_set_packswap(png_ptr);
+#endif
+
+   /* ----------------------- end of transformations ------------------- */
+
+   /* write the bits */
+   if (info_ptr->valid & PNG_INFO_IDAT)
+       png_write_image(png_ptr, info_ptr->row_pointers);
+
+   /* It is REQUIRED to call this to finish writing the rest of the file */
+   png_write_end(png_ptr, info_ptr);
+
+   if(transforms == 0 || params == (voidp)NULL)
+      /* quiet compiler warnings */ return;
+}
+#endif

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngconf.h
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngconf.h	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngconf.h	Sat Jul 13 21:26:49 2002
@@ -1,11 +1,10 @@
-
 /* pngconf.h - machine configurable file for libpng
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  */
 
 /* Any machine specific code is near the front of this file, so if you
@@ -17,7 +16,6 @@
 #ifndef PNGCONF_H
 #define PNGCONF_H
 
-
 /* This is the size of the compression buffer, and thus the size of
  * an IDAT chunk.  Make this whatever size you feel is best for your
  * machine.  One of these will be allocated per png_struct.  When this
@@ -32,7 +30,11 @@
  */
 
 #ifndef PNG_ZBUF_SIZE
-#define PNG_ZBUF_SIZE 8192
+#  define PNG_ZBUF_SIZE 8192
+#endif
+
+#ifndef PNG_NO_FLOATING_POINT_SUPPORTED
+#  define PNG_FLOATING_POINT_SUPPORTED
 #endif
 
 /* If you are running on a machine where you cannot allocate more
@@ -44,9 +46,68 @@
 #define PNG_MAX_MALLOC_64K
  */
 #if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
-#define PNG_MAX_MALLOC_64K
+#  define PNG_MAX_MALLOC_64K
+#endif
+
+/* Special munging to support doing things the 'cygwin' way:
+ * 'Normal' png-on-win32 defines/defaults:
+ *   PNG_BUILD_DLL -- building dll
+ *   PNG_USE_DLL   -- building an application, linking to dll
+ *   (no define)   -- building static library, or building an
+ *                    application and linking to the static lib
+ * 'Cygwin' defines/defaults:
+ *   PNG_BUILD_DLL -- building the dll
+ *   (no define)   -- building an application, linking to the dll
+ *   PNG_STATIC    -- building the static lib, or building an application
+ *                    that links to the static lib.
+ *   ALL_STATIC    -- building various static libs, or building an application
+ *                    that links to the static libs.
+ * Thus,
+ * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and
+ * this bit of #ifdefs will define the 'correct' config variables based on
+ * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but
+ * unnecessary.
+ */
+#if defined(__CYGWIN__)
+#  if defined(PNG_BUILD_DLL)
+#    if defined(PNG_USE_DLL)
+#      undef PNG_USE_DLL
+#    endif
+#    if !defined(PNG_DLL)
+#      define PNG_DLL
+#    endif
+#    if defined(PNG_STATIC)
+#      undef PNG_STATIC
+#    endif
+#  else
+#    if defined(ALL_STATIC)
+#      define PNG_STATIC
+#    endif
+#    if defined(PNG_STATIC)
+#      if defined(PNG_USE_DLL)
+#        undef PNG_USE_DLL
+#      endif
+#      if defined(PNG_DLL)
+#        undef PNG_DLL
+#      endif
+#    else
+#      if defined(PNG_USE_DLL)
+#        if !defined(PNG_DLL)
+#          define PNG_DLL
+#        endif
+#      else
+#        if defined(PNG_DLL)
+#           define PNG_USE_DLL
+#        else
+#           define PNG_USE_DLL
+#           define PNG_DLL
+#        endif
+#      endif
+#    endif
+#  endif
 #endif
 
+
 /* This protects us against compilers that run on a windowing system
  * and thus don't have or would rather us not use the stdio types:
  * stdin, stdout, and stderr.  The only one currently used is stderr
@@ -54,25 +115,44 @@
  * prevent these from being compiled and used. #defining PNG_NO_STDIO
  * will also prevent these, plus will prevent the entire set of stdio
  * macros and functions (FILE *, printf, etc.) from being compiled and used,
- * unless PNG_DEBUG has been #defined.
+ * unless (PNG_DEBUG > 0) has been #defined.
  *
  * #define PNG_NO_CONSOLE_IO
  * #define PNG_NO_STDIO
  */
 
-#ifdef PNG_DEBUG
-#  if (PNG_DEBUG > 0)
-#    include <stdio.h>
+#if defined(_WIN32_WCE)
+#  include <windows.h>
+   /* Console I/O functions are not supported on WindowsCE */
+#  define PNG_NO_CONSOLE_IO
+#  ifdef PNG_DEBUG
+#    undef PNG_DEBUG
 #  endif
-#else
+#endif
+
+#ifdef PNG_BUILD_DLL
+#  ifndef PNG_CONSOLE_IO_SUPPORTED
+#    ifndef PNG_NO_CONSOLE_IO
+#      define PNG_NO_CONSOLE_IO
+#    endif
+#  endif
+#endif
+
 #  ifdef PNG_NO_STDIO
 #    ifndef PNG_NO_CONSOLE_IO
 #      define PNG_NO_CONSOLE_IO
 #    endif
+#    ifdef PNG_DEBUG
+#      if (PNG_DEBUG > 0)
+#        include <stdio.h>
+#      endif
+#    endif
 #  else
-#    include <stdio.h>
+#    if !defined(_WIN32_WCE)
+/* "stdio.h" functions are not supported on WindowsCE */
+#      include <stdio.h>
+#    endif
 #  endif
-#endif
 
 /* This macro protects us against machines that don't have function
  * prototypes (ie K&R style headers).  If your compiler does not handle
@@ -84,13 +164,13 @@
 #ifndef PNGARG
 
 #ifdef OF /* zlib prototype munger */
-#define PNGARG(arglist) OF(arglist)
+#  define PNGARG(arglist) OF(arglist)
 #else
 
 #ifdef _NO_PROTO
-#define PNGARG(arglist) ()
+#  define PNGARG(arglist) ()
 #else
-#define PNGARG(arglist) arglist
+#  define PNGARG(arglist) arglist
 #endif /* _NO_PROTO */
 
 #endif /* OF */
@@ -102,49 +182,63 @@
  * on non-Mac platforms.
  */
 #ifndef MACOS
-#if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
-    defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
-#define MACOS
-#endif
+#  if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
+      defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
+#    define MACOS
+#  endif
 #endif
 
 /* enough people need this for various reasons to include it here */
-#if !defined(MACOS) && !defined(RISCOS)
-#include <sys/types.h>
+#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE)
+#  include <sys/types.h>
+#endif
+
+#ifndef PNG_SETJMP_NOT_SUPPORTED
+#  define PNG_SETJMP_SUPPORTED
 #endif
 
+#ifdef PNG_SETJMP_SUPPORTED
 /* This is an attempt to force a single setjmp behaviour on Linux.  If
  * the X config stuff didn't define _BSD_SOURCE we wouldn't need this.
  */
-#ifdef __linux__
-#ifdef _BSD_SOURCE
-#define _PNG_SAVE_BSD_SOURCE
-#undef _BSD_SOURCE
-#endif
-#ifdef _SETJMP_H
-__png.h__ already includes setjmp.h
-__dont__ include it again
-#endif
-#endif /* __linux__ */
-
-/* include setjmp.h for error handling */
-#include <setjmp.h>
-
-#ifdef __linux__
-#ifdef _PNG_SAVE_BSD_SOURCE
-#define _BSD_SOURCE
-#undef _PNG_SAVE_BSD_SOURCE
+
+#  ifdef __linux__
+#    ifdef _BSD_SOURCE
+#      define PNG_SAVE_BSD_SOURCE
+#      undef _BSD_SOURCE
+#    endif
+#    ifdef _SETJMP_H
+      __png.h__ already includes setjmp.h;
+      __dont__ include it again.;
+#    endif
+#  endif /* __linux__ */
+
+   /* include setjmp.h for error handling */
+#  include <setjmp.h>
+
+#  ifdef __linux__
+#    ifdef PNG_SAVE_BSD_SOURCE
+#      define _BSD_SOURCE
+#      undef PNG_SAVE_BSD_SOURCE
+#    endif
+#  endif /* __linux__ */
+#endif /* PNG_SETJMP_SUPPORTED */
+
+#if defined(_AIX) && defined(__xlC__)
+/* This prevents "AIX/xlC" from generating an "index(s,c)" macro in strings.h
+ * that conflicts with libpng's png_color_16.index */
+#  undef __STR__
 #endif
-#endif /* __linux__ */
 
 #ifdef BSD
-#include <strings.h>
+#  include <strings.h>
 #else
-#include <string.h>
+#  include <string.h>
 #endif
 
 /* Other defines for things like memory and the like can go here.  */
 #ifdef PNG_INTERNAL
+
 #include <stdlib.h>
 
 /* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which
@@ -160,21 +254,29 @@
  * them inside an appropriate ifdef/endif pair for portability.
  */
 
-#if defined(MACOS)
-/* We need to check that <math.h> hasn't already been included earlier
- * as it seems it doesn't agree with <fp.h>, yet we should really use
- * <fp.h> if possible.
- */
-#if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
-#include <fp.h>
-#endif
-#else
-#include <math.h>
+#if defined(PNG_FLOATING_POINT_SUPPORTED)
+#  if defined(MACOS)
+     /* We need to check that <math.h> hasn't already been included earlier
+      * as it seems it doesn't agree with <fp.h>, yet we should really use
+      * <fp.h> if possible.
+      */
+#    if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
+#      include <fp.h>
+#    endif
+#  else
+#    include <math.h>
+#  endif
+#  if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
+     /* Amiga SAS/C: We must include builtin FPU functions when compiling using
+      * MATH=68881
+      */
+#    include <m68881.h>
+#  endif
 #endif
 
 /* Codewarrior on NT has linking problems without this. */
-#if defined(__MWERKS__) && defined(WIN32)
-#define PNG_ALWAYS_EXTERN
+#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__)
+#  define PNG_ALWAYS_EXTERN
 #endif
 
 /* For some reason, Borland C++ defines memcmp, etc. in mem.h, not
@@ -182,12 +284,12 @@
  * "feature"?
  */
 #ifdef __TURBOC__
-#include <mem.h>
-#include "alloc.h"
+#  include <mem.h>
+#  include "alloc.h"
 #endif
 
 #ifdef _MSC_VER
-#include <malloc.h>
+#  include <malloc.h>
 #endif
 
 /* This controls how fine the dithering gets.  As this allocates
@@ -195,13 +297,13 @@
  * with dithering quality can decrease some or all of these.
  */
 #ifndef PNG_DITHER_RED_BITS
-#define PNG_DITHER_RED_BITS 5
+#  define PNG_DITHER_RED_BITS 5
 #endif
 #ifndef PNG_DITHER_GREEN_BITS
-#define PNG_DITHER_GREEN_BITS 5
+#  define PNG_DITHER_GREEN_BITS 5
 #endif
 #ifndef PNG_DITHER_BLUE_BITS
-#define PNG_DITHER_BLUE_BITS 5
+#  define PNG_DITHER_BLUE_BITS 5
 #endif
 
 /* This controls how fine the gamma correction becomes when you
@@ -212,14 +314,14 @@
  */
 
 #ifndef PNG_MAX_GAMMA_8
-#define PNG_MAX_GAMMA_8 11
+#  define PNG_MAX_GAMMA_8 11
 #endif
 
 /* This controls how much a difference in gamma we can tolerate before
  * we actually start doing gamma conversion.
  */
 #ifndef PNG_GAMMA_THRESHOLD
-#define PNG_GAMMA_THRESHOLD 0.05
+#  define PNG_GAMMA_THRESHOLD 0.05
 #endif
 
 #endif /* PNG_INTERNAL */
@@ -249,143 +351,226 @@
  * things to happen if the library and/or application ever change.
  */
 
-/* Any transformations you will not be using can be undef'ed here */
+/* Any features you will not be using can be undef'ed here */
 
 /* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user
-   to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS
-   on the compile line, then pick and choose which ones to define without
-   having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED
-   if you only want to have a png-compliant reader/writer but don't need
-   any of the extra transformations.  This saves about 80 kbytes in a
-   typical installation of the library. (PNG_NO_* form added in version
-   1.0.1c, for consistency)
- */
+ * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS
+ * on the compile line, then pick and choose which ones to define without
+ * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED
+ * if you only want to have a png-compliant reader/writer but don't need
+ * any of the extra transformations.  This saves about 80 kbytes in a
+ * typical installation of the library. (PNG_NO_* form added in version
+ * 1.0.1c, for consistency)
+ */
+
+/* The size of the png_text structure changed in libpng-1.0.6 when
+ * iTXt is supported.  It is turned off by default, to support old apps
+ * that malloc the png_text structure instead of calling png_set_text()
+ * and letting libpng malloc it.  It will be turned on by default in
+ * libpng-2.0.0.
+ */
+
+#ifndef PNG_iTXt_SUPPORTED
+#  ifndef PNG_READ_iTXt_SUPPORTED
+#    define PNG_NO_READ_iTXt
+#  endif
+#  ifndef PNG_WRITE_iTXt_SUPPORTED
+#    define PNG_NO_WRITE_iTXt
+#  endif
+#endif
+
+/* The following support, added after version 1.0.0, can be turned off here en
+ * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility
+ * with old applications that require the length of png_struct and png_info
+ * to remain unchanged.
+ */
+
+#ifdef PNG_LEGACY_SUPPORTED
+#  define PNG_NO_FREE_ME
+#  define PNG_NO_READ_UNKNOWN_CHUNKS
+#  define PNG_NO_WRITE_UNKNOWN_CHUNKS
+#  define PNG_NO_READ_USER_CHUNKS
+#  define PNG_NO_READ_iCCP
+#  define PNG_NO_WRITE_iCCP
+#  define PNG_NO_READ_iTXt
+#  define PNG_NO_WRITE_iTXt
+#  define PNG_NO_READ_sCAL
+#  define PNG_NO_WRITE_sCAL
+#  define PNG_NO_READ_sPLT
+#  define PNG_NO_WRITE_sPLT
+#  define PNG_NO_INFO_IMAGE
+#  define PNG_NO_READ_RGB_TO_GRAY
+#  define PNG_NO_READ_USER_TRANSFORM
+#  define PNG_NO_WRITE_USER_TRANSFORM
+#  define PNG_NO_USER_MEM
+#  define PNG_NO_READ_EMPTY_PLTE
+#  define PNG_NO_MNG_FEATURES
+#  define PNG_NO_FIXED_POINT_SUPPORTED
+#endif
+
+/* Ignore attempt to turn off both floating and fixed point support */
+#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \
+    !defined(PNG_NO_FIXED_POINT_SUPPORTED)
+#  define PNG_FIXED_POINT_SUPPORTED
+#endif
 
+#ifndef PNG_NO_FREE_ME
+#  define PNG_FREE_ME_SUPPORTED
+#endif
 
 #if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \
     !defined(PNG_NO_READ_TRANSFORMS)
-#define PNG_READ_TRANSFORMS_SUPPORTED
+#  define PNG_READ_TRANSFORMS_SUPPORTED
 #endif
 #if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \
     !defined(PNG_NO_WRITE_TRANSFORMS)
-#define PNG_WRITE_TRANSFORMS_SUPPORTED
+#  define PNG_WRITE_TRANSFORMS_SUPPORTED
 #endif
 
 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
-#ifndef PNG_NO_READ_EXPAND
-#define PNG_READ_EXPAND_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_SHIFT
-#define PNG_READ_SHIFT_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_PACK
-#define PNG_READ_PACK_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_BGR
-#define PNG_READ_BGR_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_SWAP
-#define PNG_READ_SWAP_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_PACKSWAP
-#define PNG_READ_PACKSWAP_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_INVERT
-#define PNG_READ_INVERT_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_DITHER
-#define PNG_READ_DITHER_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_BACKGROUND
-#define PNG_READ_BACKGROUND_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_16_TO_8
-#define PNG_READ_16_TO_8_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_FILLER
-#define PNG_READ_FILLER_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_GAMMA
-#define PNG_READ_GAMMA_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_GRAY_TO_RGB
-#define PNG_READ_GRAY_TO_RGB_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_SWAP_ALPHA
-#define PNG_READ_SWAP_ALPHA_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_INVERT_ALPHA
-#define PNG_READ_INVERT_ALPHA_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_STRIP_ALPHA
-#define PNG_READ_STRIP_ALPHA_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_USER_TRANSFORM
-#define PNG_READ_USER_TRANSFORM_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_RGB_TO_GRAY
-#define PNG_READ_RGB_TO_GRAY_SUPPORTED
-#endif
+#  ifndef PNG_NO_READ_EXPAND
+#    define PNG_READ_EXPAND_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_SHIFT
+#    define PNG_READ_SHIFT_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_PACK
+#    define PNG_READ_PACK_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_BGR
+#    define PNG_READ_BGR_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_SWAP
+#    define PNG_READ_SWAP_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_PACKSWAP
+#    define PNG_READ_PACKSWAP_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_INVERT
+#    define PNG_READ_INVERT_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_DITHER
+#    define PNG_READ_DITHER_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_BACKGROUND
+#    define PNG_READ_BACKGROUND_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_16_TO_8
+#    define PNG_READ_16_TO_8_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_FILLER
+#    define PNG_READ_FILLER_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_GAMMA
+#    define PNG_READ_GAMMA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_GRAY_TO_RGB
+#    define PNG_READ_GRAY_TO_RGB_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_SWAP_ALPHA
+#    define PNG_READ_SWAP_ALPHA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_INVERT_ALPHA
+#    define PNG_READ_INVERT_ALPHA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_STRIP_ALPHA
+#    define PNG_READ_STRIP_ALPHA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_USER_TRANSFORM
+#    define PNG_READ_USER_TRANSFORM_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_RGB_TO_GRAY
+#    define PNG_READ_RGB_TO_GRAY_SUPPORTED
+#  endif
 #endif /* PNG_READ_TRANSFORMS_SUPPORTED */
 
 #if !defined(PNG_NO_PROGRESSIVE_READ) && \
- !defined(PNG_PROGRESSIVE_READ_NOT_SUPPORTED) /* if you don't do progressive   */
-#define PNG_PROGRESSIVE_READ_SUPPORTED       /* reading.  This is not talking */
+ !defined(PNG_PROGRESSIVE_READ_NOT_SUPPORTED)  /* if you don't do progressive */
+#  define PNG_PROGRESSIVE_READ_SUPPORTED     /* reading.  This is not talking */
 #endif                               /* about interlacing capability!  You'll */
               /* still have interlacing unless you change the following line: */
+
 #define PNG_READ_INTERLACING_SUPPORTED /* required for PNG-compliant decoders */
 
-#ifndef PNG_NO_READ_COMPOSITED_NODIV
-#define PNG_READ_COMPOSITE_NODIV_SUPPORTED    /* well tested on Intel and SGI */
+#ifndef PNG_NO_READ_COMPOSITE_NODIV
+#  ifndef PNG_NO_READ_COMPOSITED_NODIV  /* libpng-1.0.x misspelling */
+#    define PNG_READ_COMPOSITE_NODIV_SUPPORTED   /* well tested on Intel, SGI */
+#  endif
 #endif
 
-#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
-#ifndef PNG_NO_WRITE_SHIFT
-#define PNG_WRITE_SHIFT_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_PACK
-#define PNG_WRITE_PACK_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_BGR
-#define PNG_WRITE_BGR_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_SWAP
-#define PNG_WRITE_SWAP_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_PACKSWAP
-#define PNG_WRITE_PACKSWAP_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_INVERT
-#define PNG_WRITE_INVERT_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_FILLER
-#define PNG_WRITE_FILLER_SUPPORTED  /* This is the same as WRITE_STRIP_ALPHA */
-#endif
-#ifndef PNG_NO_WRITE_SWAP_ALPHA
-#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_INVERT_ALPHA
-#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
+/* Enable if you need to support PNGs that are embedded in MNG
+   datastreams */
+/*
+#ifndef PNG_NO_MNG_FEATURES
+#  define PNG_MNG_FEATURES_SUPPORTED
 #endif
-#ifndef PNG_NO_WRITE_USER_TRANSFORM
-#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
+*/
+
+/* Deprecated, will be removed from version 2.0.0 */
+#ifndef PNG_NO_READ_EMPTY_PLTE
+#  define PNG_READ_EMPTY_PLTE_SUPPORTED
 #endif
+
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+#  ifndef PNG_NO_WRITE_SHIFT
+#    define PNG_WRITE_SHIFT_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_PACK
+#    define PNG_WRITE_PACK_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_BGR
+#    define PNG_WRITE_BGR_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_SWAP
+#    define PNG_WRITE_SWAP_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_PACKSWAP
+#    define PNG_WRITE_PACKSWAP_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_INVERT
+#    define PNG_WRITE_INVERT_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_FILLER
+#    define PNG_WRITE_FILLER_SUPPORTED   /* same as WRITE_STRIP_ALPHA */
+#  endif
+#  ifndef PNG_NO_WRITE_SWAP_ALPHA
+#    define PNG_WRITE_SWAP_ALPHA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_INVERT_ALPHA
+#    define PNG_WRITE_INVERT_ALPHA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_USER_TRANSFORM
+#    define PNG_WRITE_USER_TRANSFORM_SUPPORTED
+#  endif
 #endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
 
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+#  ifndef PNG_NO_USER_TRANSFORM_PTR
+#    define PNG_USER_TRANSFORM_PTR_SUPPORTED
+#  endif
+#endif
+
 #define PNG_WRITE_INTERLACING_SUPPORTED  /* not required for PNG-compliant
                                             encoders, but can cause trouble
                                             if left undefined */
 
-#ifndef PNG_NO_WRITE_WEIGHTED_FILTER
-#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \
+     defined(PNG_FLOATING_POINT_SUPPORTED)
+#  define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
 #endif
 
 #ifndef PNG_NO_WRITE_FLUSH
-#define PNG_WRITE_FLUSH_SUPPORTED
+#  define PNG_WRITE_FLUSH_SUPPORTED
+#endif
+
+/* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */
+#ifndef PNG_NO_WRITE_EMPTY_PLTE
+#  define PNG_WRITE_EMPTY_PLTE_SUPPORTED
 #endif
 
 #ifndef PNG_NO_STDIO
-#define PNG_TIME_RFC1123_SUPPORTED
+#  define PNG_TIME_RFC1123_SUPPORTED
 #endif
 
 /* This adds extra functions in pngget.c for accessing data from the
@@ -405,7 +590,16 @@
  * png_get_y_offset_microns()
  */
 #ifndef PNG_NO_EASY_ACCESS
-#define PNG_EASY_ACCESS_SUPPORTED
+#  define PNG_EASY_ACCESS_SUPPORTED
+#endif
+
+/* PNG_ASSEMBLER_CODE will be enabled by default in version 1.2.0 
+   even when PNG_USE_PNGVCRD or PNG_USE_PNGGCCRD is not defined */
+#ifndef PNG_NO_ASSEMBLER_CODE
+#  if defined(PNG_USE_PNGVCRD) || defined(PNG_USE_PNGGCCRD)
+#    define PNG_ASSEMBLER_CODE_SUPPORTED
+#    define PNG_MMX_CODE_SUPPORTED
+#  endif
 #endif
 
 /* These are currently experimental features, define them if you want */
@@ -413,7 +607,12 @@
 /* very little testing */
 /*
 #define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
-#define PNG_USER_MEM_SUPPORTED
+#ifndef PNG_NO_USER_MEM
+#  define PNG_USER_MEM_SUPPORTED
+#endif
+#ifndef PNG_NO_ZALLOC_ZERO
+#  define PNG_ZALLOC_ZERO
+#endif
 */
 
 /* This is only for PowerPC big-endian and 680x0 systems */
@@ -422,6 +621,11 @@
 #define PNG_READ_BIG_ENDIAN_SUPPORTED
 */
 
+/* Buggy compilers (e.g., gcc 2.7.2.2) need this */
+/*
+#define PNG_NO_POINTER_INDEXING
+*/
+
 /* These functions are turned off by default, as they will be phased out. */
 /*
 #define  PNG_USELESS_TESTS_SUPPORTED
@@ -436,103 +640,263 @@
 
 #if !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
     !defined(PNG_NO_READ_ANCILLARY_CHUNKS)
-#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+#  define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
 #endif
 #if !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
     !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS)
-#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+#  define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
 #endif
 
 #ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+
+#ifdef PNG_NO_READ_TEXT
+#  define PNG_NO_READ_iTXt
+#  define PNG_NO_READ_tEXt
+#  define PNG_NO_READ_zTXt
+#endif
 #ifndef PNG_NO_READ_bKGD
-#define PNG_READ_bKGD_SUPPORTED
+#  define PNG_READ_bKGD_SUPPORTED
+#  define PNG_bKGD_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_cHRM
-#define PNG_READ_cHRM_SUPPORTED
+#  define PNG_READ_cHRM_SUPPORTED
+#  define PNG_cHRM_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_gAMA
-#define PNG_READ_gAMA_SUPPORTED
+#  define PNG_READ_gAMA_SUPPORTED
+#  define PNG_gAMA_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_hIST
-#define PNG_READ_hIST_SUPPORTED
+#  define PNG_READ_hIST_SUPPORTED
+#  define PNG_hIST_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_iCCP
+#  define PNG_READ_iCCP_SUPPORTED
+#  define PNG_iCCP_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_iTXt
+#  define PNG_READ_iTXt_SUPPORTED
+#  define PNG_iTXt_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_oFFs
-#define PNG_READ_oFFs_SUPPORTED
+#  define PNG_READ_oFFs_SUPPORTED
+#  define PNG_oFFs_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_pCAL
-#define PNG_READ_pCAL_SUPPORTED
+#  define PNG_READ_pCAL_SUPPORTED
+#  define PNG_pCAL_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sCAL
+#  define PNG_READ_sCAL_SUPPORTED
+#  define PNG_sCAL_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_pHYs
-#define PNG_READ_pHYs_SUPPORTED
+#  define PNG_READ_pHYs_SUPPORTED
+#  define PNG_pHYs_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_sBIT
-#define PNG_READ_sBIT_SUPPORTED
+#  define PNG_READ_sBIT_SUPPORTED
+#  define PNG_sBIT_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sPLT
+#  define PNG_READ_sPLT_SUPPORTED
+#  define PNG_sPLT_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_sRGB
-#define PNG_READ_sRGB_SUPPORTED
+#  define PNG_READ_sRGB_SUPPORTED
+#  define PNG_sRGB_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_tEXt
-#define PNG_READ_tEXt_SUPPORTED
+#  define PNG_READ_tEXt_SUPPORTED
+#  define PNG_tEXt_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_tIME
-#define PNG_READ_tIME_SUPPORTED
+#  define PNG_READ_tIME_SUPPORTED
+#  define PNG_tIME_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_tRNS
-#define PNG_READ_tRNS_SUPPORTED
+#  define PNG_READ_tRNS_SUPPORTED
+#  define PNG_tRNS_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_zTXt
-#define PNG_READ_zTXt_SUPPORTED
+#  define PNG_READ_zTXt_SUPPORTED
+#  define PNG_zTXt_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_UNKNOWN_CHUNKS
+#  define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+#  ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
+#    define PNG_UNKNOWN_CHUNKS_SUPPORTED
+#  endif
+#  ifndef PNG_NO_HANDLE_AS_UNKNOWN
+#    define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#  endif
+#endif
+#if !defined(PNG_NO_READ_USER_CHUNKS) && \
+     defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+#  define PNG_READ_USER_CHUNKS_SUPPORTED
+#  define PNG_USER_CHUNKS_SUPPORTED
+#  ifdef PNG_NO_READ_UNKNOWN_CHUNKS
+#    undef PNG_NO_READ_UNKNOWN_CHUNKS
+#  endif
+#  ifdef PNG_NO_HANDLE_AS_UNKNOWN
+#    undef PNG_NO_HANDLE_AS_UNKNOWN
+#  endif
 #endif
 #ifndef PNG_NO_READ_OPT_PLTE
-#define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the optional */
-#endif                              /* PLTE chunk in RGB and RGBA images */
+#  define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */
+#endif                      /* optional PLTE chunk in RGB and RGBA images */
+#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \
+    defined(PNG_READ_zTXt_SUPPORTED)
+#  define PNG_READ_TEXT_SUPPORTED
+#  define PNG_TEXT_SUPPORTED
+#endif
+
 #endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */
 
 #ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+
+#ifdef PNG_NO_WRITE_TEXT
+#  define PNG_NO_WRITE_iTXt
+#  define PNG_NO_WRITE_tEXt
+#  define PNG_NO_WRITE_zTXt
+#endif
 #ifndef PNG_NO_WRITE_bKGD
-#define PNG_WRITE_bKGD_SUPPORTED
+#  define PNG_WRITE_bKGD_SUPPORTED
+#  ifndef PNG_bKGD_SUPPORTED
+#    define PNG_bKGD_SUPPORTED
+#  endif
 #endif
 #ifndef PNG_NO_WRITE_cHRM
-#define PNG_WRITE_cHRM_SUPPORTED
+#  define PNG_WRITE_cHRM_SUPPORTED
+#  ifndef PNG_cHRM_SUPPORTED
+#    define PNG_cHRM_SUPPORTED
+#  endif
 #endif
 #ifndef PNG_NO_WRITE_gAMA
-#define PNG_WRITE_gAMA_SUPPORTED
+#  define PNG_WRITE_gAMA_SUPPORTED
+#  ifndef PNG_gAMA_SUPPORTED
+#    define PNG_gAMA_SUPPORTED
+#  endif
 #endif
 #ifndef PNG_NO_WRITE_hIST
-#define PNG_WRITE_hIST_SUPPORTED
+#  define PNG_WRITE_hIST_SUPPORTED
+#  ifndef PNG_hIST_SUPPORTED
+#    define PNG_hIST_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_iCCP
+#  define PNG_WRITE_iCCP_SUPPORTED
+#  ifndef PNG_iCCP_SUPPORTED
+#    define PNG_iCCP_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_iTXt
+#  define PNG_WRITE_iTXt_SUPPORTED
+#  ifndef PNG_iTXt_SUPPORTED
+#    define PNG_iTXt_SUPPORTED
+#  endif
 #endif
 #ifndef PNG_NO_WRITE_oFFs
-#define PNG_WRITE_oFFs_SUPPORTED
+#  define PNG_WRITE_oFFs_SUPPORTED
+#  ifndef PNG_oFFs_SUPPORTED
+#    define PNG_oFFs_SUPPORTED
+#  endif
 #endif
 #ifndef PNG_NO_WRITE_pCAL
-#define PNG_WRITE_pCAL_SUPPORTED
+#  define PNG_WRITE_pCAL_SUPPORTED
+#  ifndef PNG_pCAL_SUPPORTED
+#    define PNG_pCAL_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_sCAL
+#  define PNG_WRITE_sCAL_SUPPORTED
+#  ifndef PNG_sCAL_SUPPORTED
+#    define PNG_sCAL_SUPPORTED
+#  endif
 #endif
 #ifndef PNG_NO_WRITE_pHYs
-#define PNG_WRITE_pHYs_SUPPORTED
+#  define PNG_WRITE_pHYs_SUPPORTED
+#  ifndef PNG_pHYs_SUPPORTED
+#    define PNG_pHYs_SUPPORTED
+#  endif
 #endif
 #ifndef PNG_NO_WRITE_sBIT
-#define PNG_WRITE_sBIT_SUPPORTED
+#  define PNG_WRITE_sBIT_SUPPORTED
+#  ifndef PNG_sBIT_SUPPORTED
+#    define PNG_sBIT_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_sPLT
+#  define PNG_WRITE_sPLT_SUPPORTED
+#  ifndef PNG_sPLT_SUPPORTED
+#    define PNG_sPLT_SUPPORTED
+#  endif
 #endif
 #ifndef PNG_NO_WRITE_sRGB
-#define PNG_WRITE_sRGB_SUPPORTED
+#  define PNG_WRITE_sRGB_SUPPORTED
+#  ifndef PNG_sRGB_SUPPORTED
+#    define PNG_sRGB_SUPPORTED
+#  endif
 #endif
 #ifndef PNG_NO_WRITE_tEXt
-#define PNG_WRITE_tEXt_SUPPORTED
+#  define PNG_WRITE_tEXt_SUPPORTED
+#  ifndef PNG_tEXt_SUPPORTED
+#    define PNG_tEXt_SUPPORTED
+#  endif
 #endif
 #ifndef PNG_NO_WRITE_tIME
-#define PNG_WRITE_tIME_SUPPORTED
+#  define PNG_WRITE_tIME_SUPPORTED
+#  ifndef PNG_tIME_SUPPORTED
+#    define PNG_tIME_SUPPORTED
+#  endif
 #endif
 #ifndef PNG_NO_WRITE_tRNS
-#define PNG_WRITE_tRNS_SUPPORTED
+#  define PNG_WRITE_tRNS_SUPPORTED
+#  ifndef PNG_tRNS_SUPPORTED
+#    define PNG_tRNS_SUPPORTED
+#  endif
 #endif
 #ifndef PNG_NO_WRITE_zTXt
-#define PNG_WRITE_zTXt_SUPPORTED
+#  define PNG_WRITE_zTXt_SUPPORTED
+#  ifndef PNG_zTXt_SUPPORTED
+#    define PNG_zTXt_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS
+#  define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+#  ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
+#    define PNG_UNKNOWN_CHUNKS_SUPPORTED
+#  endif
+#  ifndef PNG_NO_HANDLE_AS_UNKNOWN
+#     ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#       define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#     endif
+#  endif
 #endif
+#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
+    defined(PNG_WRITE_zTXt_SUPPORTED)
+#  define PNG_WRITE_TEXT_SUPPORTED
+#  ifndef PNG_TEXT_SUPPORTED
+#    define PNG_TEXT_SUPPORTED
+#  endif
+#endif
+
 #endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */
 
+/* Turn this off to disable png_read_png() and
+ * png_write_png() and leave the row_pointers member
+ * out of the info structure.
+ */
+#ifndef PNG_NO_INFO_IMAGE
+#  define PNG_INFO_IMAGE_SUPPORTED
+#endif
+
 /* need the time information for reading tIME chunks */
-#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
-#include <time.h>
+#if defined(PNG_tIME_SUPPORTED)
+#  if !defined(_WIN32_WCE)
+     /* "time.h" functions are not supported on WindowsCE */
+#    include <time.h>
+#  endif
 #endif
 
 /* Some typedefs to get us started.  These should be safe on most of the
@@ -566,28 +930,26 @@
 /* Separate compiler dependencies (problem here is that zlib.h always
    defines FAR. (SJT) */
 #ifdef __BORLANDC__
-#if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
-#define LDATA 1
-#else
-#define LDATA 0
-#endif
-
-#if !defined(__WIN32__) && !defined(__FLAT__)
-#define PNG_MAX_MALLOC_64K
-#if (LDATA != 1)
-#ifndef FAR
-#define FAR __far
-#endif
-#define USE_FAR_KEYWORD
-#endif   /* LDATA != 1 */
-
-/* Possibly useful for moving data out of default segment.
- * Uncomment it if you want. Could also define FARDATA as
- * const if your compiler supports it. (SJT)
-#  define FARDATA FAR
- */
-#endif  /* __WIN32__, __FLAT__ */
-
+#  if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
+#    define LDATA 1
+#  else
+#    define LDATA 0
+#  endif
+   /* GRR:  why is Cygwin in here?  Cygwin is not Borland C... */
+#  if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__)
+#    define PNG_MAX_MALLOC_64K
+#    if (LDATA != 1)
+#      ifndef FAR
+#        define FAR __far
+#      endif
+#      define USE_FAR_KEYWORD
+#    endif   /* LDATA != 1 */
+     /* Possibly useful for moving data out of default segment.
+      * Uncomment it if you want. Could also define FARDATA as
+      * const if your compiler supports it. (SJT)
+#    define FARDATA FAR
+      */
+#  endif  /* __WIN32__, __FLAT__, __CYGWIN__ */
 #endif   /* __BORLANDC__ */
 
 
@@ -599,22 +961,26 @@
 /* MSC Medium model */
 #if defined(FAR)
 #  if defined(M_I86MM)
-#     define USE_FAR_KEYWORD
-#     define FARDATA FAR
-#     include <dos.h>
+#    define USE_FAR_KEYWORD
+#    define FARDATA FAR
+#    include <dos.h>
 #  endif
 #endif
 
 /* SJT: default case */
 #ifndef FAR
-#   define FAR
+#  define FAR
 #endif
 
 /* At this point FAR is always defined */
 #ifndef FARDATA
-#define FARDATA
+#  define FARDATA
 #endif
 
+/* Typedef for floating-point numbers that are converted
+   to fixed-point with a multiple of 100,000, e.g., int_gamma */
+typedef png_int_32 png_fixed_point;
+
 /* Add typedefs for pointers */
 typedef void            FAR * png_voidp;
 typedef png_byte        FAR * png_bytep;
@@ -624,7 +990,19 @@
 typedef png_int_16      FAR * png_int_16p;
 typedef PNG_CONST char  FAR * png_const_charp;
 typedef char            FAR * png_charp;
+typedef png_fixed_point FAR * png_fixed_point_p;
+
+#ifndef PNG_NO_STDIO
+#if defined(_WIN32_WCE)
+typedef HANDLE                png_FILE_p;
+#else
+typedef FILE                * png_FILE_p;
+#endif
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
 typedef double          FAR * png_doublep;
+#endif
 
 /* Pointers to pointers; i.e. arrays */
 typedef png_byte        FAR * FAR * png_bytepp;
@@ -634,9 +1012,12 @@
 typedef png_int_16      FAR * FAR * png_int_16pp;
 typedef PNG_CONST char  FAR * FAR * png_const_charpp;
 typedef char            FAR * FAR * png_charpp;
+typedef png_fixed_point FAR * FAR * png_fixed_point_pp;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
 typedef double          FAR * FAR * png_doublepp;
+#endif
 
-/* Pointers to pointers to pointers; i.e. pointer to array */
+/* Pointers to pointers to pointers; i.e., pointer to array */
 typedef char            FAR * FAR * FAR * png_charppp;
 
 /* libpng typedefs for types in zlib. If zlib changes
@@ -647,59 +1028,237 @@
 typedef charf * FAR *   png_zcharpp;
 typedef z_stream FAR *  png_zstreamp;
 
-/* allow for compilation as dll under MS Windows */
-#ifdef __WIN32DLL__
-#define PNG_EXPORT(type,symbol) __declspec(dllexport) type symbol
+/*
+ * Define PNG_BUILD_DLL if the module being built is a Windows
+ * LIBPNG DLL.
+ *
+ * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL.
+ * It is equivalent to Microsoft predefined macro _DLL that is
+ * automatically defined when you compile using the share
+ * version of the CRT (C Run-Time library)
+ *
+ * The cygwin mods make this behavior a little different:
+ * Define PNG_BUILD_DLL if you are building a dll for use with cygwin
+ * Define PNG_STATIC if you are building a static library for use with cygwin,
+ *   -or- if you are building an application that you want to link to the
+ *   static library.
+ * PNG_USE_DLL is defined by default (no user action needed) unless one of
+ *   the other flags is defined.
+ */
+
+#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL))
+#  define PNG_DLL
+#endif
+/* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib.
+ * When building a static lib, default to no GLOBAL ARRAYS, but allow
+ * command-line override
+ */
+#if defined(__CYGWIN__)
+#  if !defined(PNG_STATIC)
+#    if defined(PNG_USE_GLOBAL_ARRAYS)
+#      undef PNG_USE_GLOBAL_ARRAYS
+#    endif
+#    if !defined(PNG_USE_LOCAL_ARRAYS)
+#      define PNG_USE_LOCAL_ARRAYS
+#    endif
+#  else
+#    if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS)
+#      if defined(PNG_USE_GLOBAL_ARRAYS)
+#        undef PNG_USE_GLOBAL_ARRAYS
+#      endif
+#    endif
+#  endif
+#  if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
+#    define PNG_USE_LOCAL_ARRAYS
+#  endif
+#endif
+
+/* Do not use global arrays (helps with building DLL's)
+ * They are no longer used in libpng itself, since version 1.0.5c,
+ * but might be required for some pre-1.0.5c applications.
+ */
+#if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
+#  if defined(PNG_NO_GLOBAL_ARRAYS) || (defined(__GNUC__) && defined(PNG_DLL))
+#    define PNG_USE_LOCAL_ARRAYS
+#  else
+#    define PNG_USE_GLOBAL_ARRAYS
+#  endif
 #endif
 
-/* allow for compilation as dll with BORLAND C++ 5.0 */
-#if defined(__BORLANDC__) && defined(_Windows) && defined(__DLL__)
-#   define PNG_EXPORT(type,symbol) type _export symbol
+
+#ifndef PNGAPI
+
+#if defined(__MINGW32__) || defined(__CYGWIN__) && !defined(PNG_MODULEDEF)
+#  ifndef PNG_NO_MODULEDEF
+#    define PNG_NO_MODULEDEF
+#  endif
+#endif
+
+#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF)
+#  define PNG_IMPEXP
+#endif
+
+#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \
+    (( defined(_Windows) || defined(_WINDOWS) || \
+       defined(WIN32) || defined(_WIN32) || defined(__WIN32__) \
+	  ) && !defined(__CYGWIN__))
+
+#  if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800))
+#    define PNGAPI __cdecl
+#  else
+#    define PNGAPI _cdecl
+#  endif
+
+#  if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \
+       0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */)
+#     define PNG_IMPEXP
+#  endif
+
+#  if !defined(PNG_IMPEXP)
+
+#     define PNG_EXPORT_TYPE1(type,symbol)  PNG_IMPEXP type PNGAPI symbol
+#     define PNG_EXPORT_TYPE2(type,symbol)  type PNG_IMPEXP PNGAPI symbol
+
+      /* Borland/Microsoft */
+#     if defined(_MSC_VER) || defined(__BORLANDC__)
+#        if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500)
+#           define PNG_EXPORT PNG_EXPORT_TYPE1
+#        else
+#           define PNG_EXPORT PNG_EXPORT_TYPE2
+#           if defined(PNG_BUILD_DLL)
+#              define PNG_IMPEXP __export
+#           else
+#              define PNG_IMPEXP /*__import*/ /* doesn't exist AFAIK in
+                                                 VC++*/
+#           endif                             /* Exists in Borland C++ for
+                                                 C++ classes (== huge) */
+#        endif
+#     endif
+
+#     if !defined(PNG_IMPEXP)
+#        if defined(PNG_BUILD_DLL)
+#           define PNG_IMPEXP __declspec(dllexport)
+#        else
+#           define PNG_IMPEXP __declspec(dllimport)
+#        endif
+#     endif
+#  endif  /* PNG_IMPEXP */
+#else /* !(DLL || non-cygwin WINDOWS) */
+#  if defined(__CYGWIN__) && !defined(PNG_DLL)
+#    if !defined(PNG_IMPEXP)
+#      define PNG_IMPEXP
+#    endif
+#    define PNGAPI __cdecl
+#  else
+#    if 0 /* ... other platforms, with other meanings */
+#    else
+#       define PNGAPI
+#       define PNG_IMPEXP
+#    endif
+#  endif
+#endif
 #endif
 
-/* allow for compilation as shared lib under BeOS */
-#ifdef __BEOSDLL__
-#define PNG_EXPORT(type,symbol) __declspec(export) type symbol
+#ifndef PNGAPI
+#  define PNGAPI
+#endif
+#ifndef PNG_IMPEXP
+#  define PNG_IMPEXP
 #endif
 
 #ifndef PNG_EXPORT
-#define PNG_EXPORT(type,symbol) type symbol
+#  define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol
 #endif
 
+#ifdef PNG_USE_GLOBAL_ARRAYS
+#  ifndef PNG_EXPORT_VAR
+#    define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type
+#  endif
+#endif
 
-/* User may want to use these so not in PNG_INTERNAL. Any library functions
- * that are passed far data must be model independent.
+/* User may want to use these so they are not in PNG_INTERNAL. Any library
+ * functions that are passed far data must be model independent.
  */
 
+#ifndef PNG_ABORT
+#  define PNG_ABORT() abort()
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
+#else
+#  define png_jmpbuf(png_ptr) \
+   (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED)
+#endif
+
 #if defined(USE_FAR_KEYWORD)  /* memory model independent fns */
 /* use this to make far-to-near assignments */
-#   define CHECK   1
-#   define NOCHECK 0
-#   define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK))
-#   define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK))
-#   define png_strcpy _fstrcpy
-#   define png_strlen _fstrlen
-#   define png_memcmp _fmemcmp      /* SJT: added */
-#   define png_memcpy _fmemcpy
-#   define png_memset _fmemset
+#  define CHECK   1
+#  define NOCHECK 0
+#  define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK))
+#  define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK))
+#  define png_strcpy _fstrcpy
+#  define png_strlen _fstrlen
+#  define png_memcmp _fmemcmp      /* SJT: added */
+#  define png_memcpy _fmemcpy
+#  define png_memset _fmemset
 #else /* use the usual functions */
-#   define CVT_PTR(ptr)         (ptr)
-#   define CVT_PTR_NOCHECK(ptr) (ptr)
-#   define png_strcpy strcpy
-#   define png_strlen strlen
-#   define png_memcmp memcmp     /* SJT: added */
-#   define png_memcpy memcpy
-#   define png_memset memset
+#  define CVT_PTR(ptr)         (ptr)
+#  define CVT_PTR_NOCHECK(ptr) (ptr)
+#  define png_strcpy strcpy
+#  define png_strlen strlen
+#  define png_memcmp memcmp     /* SJT: added */
+#  define png_memcpy memcpy
+#  define png_memset memset
 #endif
 /* End of memory model independent support */
 
-/* Just a double check that someone hasn't tried to define something
+/* Just a little check that someone hasn't tried to define something
  * contradictory.
  */
 #if (PNG_ZBUF_SIZE > 65536) && defined(PNG_MAX_MALLOC_64K)
-#undef PNG_ZBUF_SIZE
-#define PNG_ZBUF_SIZE 65536
+#  undef PNG_ZBUF_SIZE
+#  define PNG_ZBUF_SIZE 65536
+#endif
+
+/* Prior to libpng-1.0.9, this block was in pngasmrd.h */
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_INTERNAL)
+
+/* These are the default thresholds before the MMX code kicks in; if either
+ * rowbytes or bitdepth is below the threshold, plain C code is used.  These
+ * can be overridden at runtime via the png_set_mmx_thresholds() call in
+ * libpng 1.2.0 and later.  The values below were chosen by Intel.
+ */
+
+#ifndef PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT
+#  define PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT  128  /*  >=  */
+#endif
+#ifndef PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT
+#  define PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT  9    /*  >=  */   
 #endif
 
+/* Set this in the makefile for VC++ on Pentium, not here. */
+/* Platform must be Pentium.  Makefile must assemble and load pngvcrd.c .
+ * MMX will be detected at run time and used if present.
+ */
+#ifdef PNG_USE_PNGVCRD
+#  define PNG_HAVE_ASSEMBLER_COMBINE_ROW
+#  define PNG_HAVE_ASSEMBLER_READ_INTERLACE
+#  define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+#endif
+
+/* Set this in the makefile for gcc/as on Pentium, not here. */
+/* Platform must be Pentium.  Makefile must assemble and load pnggccrd.c .
+ * MMX will be detected at run time and used if present.
+ */
+#ifdef PNG_USE_PNGGCCRD
+#  define PNG_HAVE_ASSEMBLER_COMBINE_ROW
+#  define PNG_HAVE_ASSEMBLER_READ_INTERLACE
+#  define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+#endif
+/* - see pnggccrd.c for info about what is currently enabled */
+
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+
 #endif /* PNGCONF_H */
 

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/Y2KINFO
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/Y2KINFO	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/Y2KINFO	Sat Jul 13 21:26:50 2002
@@ -1,29 +1,29 @@
    Y2K compliance in libpng:
    =========================
-      
-      January 13, 1999
-      
+
+      January 31, 2001
+
       Since the PNG Development group is an ad-hoc body, we can't make
       an official declaration.
-      
-      This is your unofficial assurance that libpng from version 0.81 and
-      upward are Y2K compliant.  It is my belief that earlier versions were
-      also Y2K compliant.
-      
+
+      This is your unofficial assurance that libpng from version 0.71 and
+      upward through 1.0.9 are Y2K compliant.  It is my belief that earlier
+      versions were also Y2K compliant.
+
       Libpng only has three year fields.  One is a 2-byte unsigned integer
       that will hold years up to 65535.  The other two hold the date in text
       format, and will hold years up to 9999.
-      
+
       The integer is
           "png_uint_16 year" in png_time_struct.
-      
+
       The strings are
           "png_charp time_buffer" in png_struct and
           "near_time_buffer", which is a local character string in png.c.
-      
+
       There are seven time-related functions:
 
-          png_convert_to_rfc_1123() in png.c 
+          png_convert_to_rfc_1123() in png.c
             (formerly png_convert_to_rfc_1152() in error)
           png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
           png_convert_from_time_t() in pngwrite.c
@@ -31,22 +31,25 @@
           png_handle_tIME() in pngrutil.c, called in pngread.c
           png_set_tIME() in pngset.c
           png_write_tIME() in pngwutil.c, called in pngwrite.c
-      
-      All appear to handle dates properly in a Y2K environment.  The 
+
+      All appear to handle dates properly in a Y2K environment.  The
       png_convert_from_time_t() function calls gmtime() to convert from system
       clock time, which returns (year - 1900), which we properly convert to
       the full 4-digit year.  There is a possibility that applications using
       libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
-      function, or incorrectly passing only a 2-digit year instead of
-      "year - 1900" into the png_convert_from_struct_tm() function, but this
-      is not under our control.  The libpng documentation has always stated
-      that it works with 4-digit years, and the APIs have been documented as
-      such.
-      
+      function, or that they are incorrectly passing only a 2-digit year
+      instead of "year - 1900" into the png_convert_from_struct_tm() function,
+      but this is not under our control.  The libpng documentation has always
+      stated that it works with 4-digit years, and the APIs have been
+      documented as such.
+
       The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
       integer to hold the year, and can hold years as large as 65535.
-      
-      
+
+      zlib, upon which libpng depends, is also Y2K compliant.  It contains
+      no date-related code.
+
+
          Glenn Randers-Pehrson
          libpng maintainer
          PNG Development Group

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngpread.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngpread.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngpread.c	Sat Jul 13 21:26:50 2002
@@ -1,11 +1,11 @@
 
 /* pngpread.c - read a png file in push mode
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  */
 
 #define PNG_INTERNAL
@@ -13,7 +13,18 @@
 
 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
 
-void
+/* push model modes */
+#define PNG_READ_SIG_MODE   0
+#define PNG_READ_CHUNK_MODE 1
+#define PNG_READ_IDAT_MODE  2
+#define PNG_SKIP_MODE       3
+#define PNG_READ_tEXt_MODE  4
+#define PNG_READ_zTXt_MODE  5
+#define PNG_READ_DONE_MODE  6
+#define PNG_READ_iTXt_MODE  7
+#define PNG_ERROR_MODE      8
+
+void PNGAPI
 png_process_data(png_structp png_ptr, png_infop info_ptr,
    png_bytep buffer, png_size_t buffer_size)
 {
@@ -28,7 +39,7 @@
 /* What we do with the incoming data depends on what we were previously
  * doing before we ran out of data...
  */
-void
+void /* PRIVATE */
 png_process_some_data(png_structp png_ptr, png_infop info_ptr)
 {
    switch (png_ptr->process_mode)
@@ -62,6 +73,13 @@
          break;
       }
 #endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      case PNG_READ_iTXt_MODE:
+      {
+         png_push_read_iTXt(png_ptr, info_ptr);
+         break;
+      }
+#endif
       case PNG_SKIP_MODE:
       {
          png_push_crc_finish(png_ptr);
@@ -81,7 +99,7 @@
  * checked by the calling application, or because of multiple calls to this
  * routine.
  */
-void
+void /* PRIVATE */
 png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
 {
    png_size_t num_checked = png_ptr->sig_bytes,
@@ -94,7 +112,7 @@
 
    png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
       num_to_check);
-   png_ptr->sig_bytes += num_to_check;
+   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes+num_to_check);
 
    if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
    {
@@ -113,16 +131,73 @@
    }
 }
 
-void
+void /* PRIVATE */
 png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IHDR;
+      PNG_IDAT;
+      PNG_IEND;
+      PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+      PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+      PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+      PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+      PNG_hIST;
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+      PNG_iCCP;
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      PNG_iTXt;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+      PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+      PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+      PNG_sBIT;
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+      PNG_sCAL;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      PNG_sRGB;
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+      PNG_sPLT;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+      PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+      PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      PNG_zTXt;
+#endif
+#endif /* PNG_USE_LOCAL_ARRAYS */
    /* First we make sure we have enough data for the 4 byte chunk name
     * and the 4 byte chunk length before proceeding with decoding the
     * chunk data.  To fully decode each of these chunks, we also make
     * sure we have enough data in the buffer for the 4 byte CRC at the
     * end of every chunk (except IDAT, which is handled separately).
     */
-   if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
+   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
    {
       png_byte chunk_length[4];
 
@@ -136,7 +211,7 @@
       png_ptr->push_length = png_get_uint_32(chunk_length);
       png_reset_crc(png_ptr);
       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
-      png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
+      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    }
 
    if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
@@ -159,7 +234,7 @@
 
       png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
    }
-   else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+   else if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
    {
       /* If we reach an IDAT chunk, this means we have read all of the
        * header chunks, and we can start reading the image (or if this
@@ -242,6 +317,30 @@
       png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
    }
 #endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
 #if defined(PNG_READ_tRNS_SUPPORTED)
    else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
    {
@@ -314,6 +413,18 @@
       png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
    }
 #endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
 #if defined(PNG_READ_tIME_SUPPORTED)
    else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
    {
@@ -338,22 +449,28 @@
       png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
    }
 #endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+   {
+      png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
    else
    {
       png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
    }
 
-   png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
+   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
 }
 
-void
+void /* PRIVATE */
 png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
 {
    png_ptr->process_mode = PNG_SKIP_MODE;
    png_ptr->skip_length = skip;
 }
 
-void
+void /* PRIVATE */
 png_push_crc_finish(png_structp png_ptr)
 {
    if (png_ptr->skip_length && png_ptr->save_buffer_size)
@@ -401,7 +518,7 @@
    }
 }
 
-void
+void /* PRIVATE */
 png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
 {
    png_bytep ptr;
@@ -439,7 +556,7 @@
    }
 }
 
-void
+void /* PRIVATE */
 png_push_save_buffer(png_structp png_ptr)
 {
    if (png_ptr->save_buffer_size)
@@ -483,7 +600,7 @@
    png_ptr->buffer_size = 0;
 }
 
-void
+void /* PRIVATE */
 png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
    png_size_t buffer_length)
 {
@@ -493,10 +610,13 @@
    png_ptr->current_buffer_ptr = png_ptr->current_buffer;
 }
 
-void
+void /* PRIVATE */
 png_push_read_IDAT(png_structp png_ptr)
 {
-   if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IDAT;
+#endif
+   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
    {
       png_byte chunk_length[4];
 
@@ -511,9 +631,9 @@
 
       png_reset_crc(png_ptr);
       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
-      png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
+      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
 
-      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+      if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
       {
          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
          if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
@@ -576,11 +696,11 @@
       }
 
       png_crc_finish(png_ptr, 0);
-      png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
+      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
    }
 }
 
-void
+void /* PRIVATE */
 png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
    png_size_t buffer_length)
 {
@@ -594,23 +714,26 @@
    for(;;)
    {
       ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
-      if (ret == Z_STREAM_END)
+      if (ret != Z_OK)
       {
-         if (png_ptr->zstream.avail_in)
-            png_error(png_ptr, "Extra compressed data");
-         if (!(png_ptr->zstream.avail_out))
+         if (ret == Z_STREAM_END)
          {
-            png_push_process_row(png_ptr);
-         }
+            if (png_ptr->zstream.avail_in)
+               png_error(png_ptr, "Extra compressed data");
+            if (!(png_ptr->zstream.avail_out))
+            {
+               png_push_process_row(png_ptr);
+            }
 
-         png_ptr->mode |= PNG_AFTER_IDAT;
-         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
-         break;
+            png_ptr->mode |= PNG_AFTER_IDAT;
+            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+            break;
+         }
+         else if (ret == Z_BUF_ERROR)
+            break;
+         else
+            png_error(png_ptr, "Decompression Error");
       }
-      else if (ret == Z_BUF_ERROR)
-         break;
-      else if (ret != Z_OK)
-         png_error(png_ptr, "Decompression Error");
       if (!(png_ptr->zstream.avail_out))
       {
          png_push_process_row(png_ptr);
@@ -622,7 +745,7 @@
    }
 }
 
-void
+void /* PRIVATE */
 png_push_process_row(png_structp png_ptr)
 {
    png_ptr->row_info.color_type = png_ptr->color_type;
@@ -649,18 +772,29 @@
    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
    {
       if (png_ptr->pass < 6)
+/*       old interface (pre-1.0.9):
          png_do_read_interlace(&(png_ptr->row_info),
             png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
+ */
+         png_do_read_interlace(png_ptr);
 
-      switch (png_ptr->pass)
-      {
+    switch (png_ptr->pass)
+    {
          case 0:
          {
             int i;
             for (i = 0; i < 8 && png_ptr->pass == 0; i++)
             {
                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
-               png_read_push_finish_row(png_ptr);
+               png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */
+            }
+            if (png_ptr->pass == 2) /* pass 1 might be empty */
+            {
+               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+               {
+                  png_push_have_row(png_ptr, NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
             }
             break;
          }
@@ -672,7 +806,7 @@
                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
                png_read_push_finish_row(png_ptr);
             }
-            if (png_ptr->pass == 2)
+            if (png_ptr->pass == 2) /* skip top 4 generated rows */
             {
                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
                {
@@ -695,6 +829,14 @@
                png_push_have_row(png_ptr, NULL);
                png_read_push_finish_row(png_ptr);
             }
+            if (png_ptr->pass == 4) /* pass 3 might be empty */
+            {
+               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+               {
+                  png_push_have_row(png_ptr, NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
             break;
          }
          case 3:
@@ -705,7 +847,7 @@
                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
                png_read_push_finish_row(png_ptr);
             }
-            if (png_ptr->pass == 4)
+            if (png_ptr->pass == 4) /* skip top two generated rows */
             {
                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
                {
@@ -728,6 +870,11 @@
                png_push_have_row(png_ptr, NULL);
                png_read_push_finish_row(png_ptr);
             }
+            if (png_ptr->pass == 6) /* pass 5 might be empty */
+            {
+               png_push_have_row(png_ptr, NULL);
+               png_read_push_finish_row(png_ptr);
+            }
             break;
          }
          case 5:
@@ -738,7 +885,7 @@
                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
                png_read_push_finish_row(png_ptr);
             }
-            if (png_ptr->pass == 6)
+            if (png_ptr->pass == 6) /* skip top generated row */
             {
                png_push_have_row(png_ptr, NULL);
                png_read_push_finish_row(png_ptr);
@@ -764,9 +911,35 @@
    }
 }
 
-void
+void /* PRIVATE */
 png_read_push_finish_row(png_structp png_ptr)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* start of interlace block */
+   const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* offset to next interlace block */
+   const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* start of interlace block in the y direction */
+   const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* offset to next interlace block in the y direction */
+   const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+   /* Width of interlace block.  This is not currently used - if you need
+    * it, uncomment it here and in png.h
+   const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
+   */
+
+   /* Height of interlace block.  This is not currently used - if you need
+    * it, uncomment it here and in png.h
+   const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+   */
+#endif
+
    png_ptr->row_number++;
    if (png_ptr->row_number < png_ptr->num_rows)
       return;
@@ -779,6 +952,11 @@
       do
       {
          png_ptr->pass++;
+         if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
+             (png_ptr->pass == 3 && png_ptr->width < 3) ||
+             (png_ptr->pass == 5 && png_ptr->width < 2))
+           png_ptr->pass++;
+
          if (png_ptr->pass >= 7)
             break;
 
@@ -803,10 +981,10 @@
 }
 
 #if defined(PNG_READ_tEXt_SUPPORTED)
-void
+void /* PRIVATE */
 png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
-   if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
+   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
       {
          png_error(png_ptr, "Out of place tEXt");
          /* to quiet some compiler warnings */
@@ -833,7 +1011,7 @@
    png_ptr->process_mode = PNG_READ_tEXt_MODE;
 }
 
-void
+void /* PRIVATE */
 png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr->buffer_size && png_ptr->current_text_left)
@@ -879,20 +1057,25 @@
       text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
       text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
       text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+      text_ptr->lang = (char *)NULL;
+      text_ptr->lang_key = (char *)NULL;
+#endif
       text_ptr->text = text;
 
       png_set_text(png_ptr, info_ptr, text_ptr, 1);
 
+      png_free(png_ptr, key);
       png_free(png_ptr, text_ptr);
    }
 }
 #endif
 
 #if defined(PNG_READ_zTXt_SUPPORTED)
-void
+void /* PRIVATE */
 png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
-   if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
+   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
       {
          png_error(png_ptr, "Out of place zTXt");
          /* to quiet some compiler warnings */
@@ -921,7 +1104,7 @@
    png_ptr->process_mode = PNG_READ_zTXt_MODE;
 }
 
-void
+void /* PRIVATE */
 png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr->buffer_size && png_ptr->current_text_left)
@@ -1058,7 +1241,119 @@
       text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
       text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
       text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+      text_ptr->lang = (char *)NULL;
+      text_ptr->lang_key = (char *)NULL;
+#endif
+      text_ptr->text = text;
+
+      png_set_text(png_ptr, info_ptr, text_ptr, 1);
+
+      png_free(png_ptr, key);
+      png_free(png_ptr, text_ptr);
+   }
+}
+#endif
+
+#if defined(PNG_READ_iTXt_SUPPORTED)
+void /* PRIVATE */
+png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+      {
+         png_error(png_ptr, "Out of place iTXt");
+         /* to quiet some compiler warnings */
+         if(info_ptr == NULL) return;
+      }
+
+#ifdef PNG_MAX_MALLOC_64K
+   png_ptr->skip_length = 0;  /* This may not be necessary */
+
+   if (length > (png_uint_32)65535L) /* Can't hold the entire string in memory */
+   {
+      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
+      png_ptr->skip_length = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+         (png_uint_32)(length+1));
+   png_ptr->current_text[length] = '\0';
+   png_ptr->current_text_ptr = png_ptr->current_text;
+   png_ptr->current_text_size = (png_size_t)length;
+   png_ptr->current_text_left = (png_size_t)length;
+   png_ptr->process_mode = PNG_READ_iTXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
+{
+
+   if (png_ptr->buffer_size && png_ptr->current_text_left)
+   {
+      png_size_t text_size;
+
+      if (png_ptr->buffer_size < png_ptr->current_text_left)
+         text_size = png_ptr->buffer_size;
+      else
+         text_size = png_ptr->current_text_left;
+      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+      png_ptr->current_text_left -= text_size;
+      png_ptr->current_text_ptr += text_size;
+   }
+   if (!(png_ptr->current_text_left))
+   {
+      png_textp text_ptr;
+      png_charp key;
+      int comp_flag;
+      png_charp lang;
+      png_charp lang_key;
+      png_charp text;
+
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_crc_finish(png_ptr);
+
+#if defined(PNG_MAX_MALLOC_64K)
+      if (png_ptr->skip_length)
+         return;
+#endif
+
+      key = png_ptr->current_text;
+      png_ptr->current_text = 0;
+
+      for (lang = key; *lang; lang++)
+         /* empty loop */ ;
+
+      if (lang != key + png_ptr->current_text_size)
+         lang++;
+
+      comp_flag = *lang++;
+      lang++;     /* skip comp_type, always zero */
+
+      for (lang_key = lang; *lang_key; lang_key++)
+         /* empty loop */ ;
+      lang_key++;        /* skip NUL separator */
+
+      for (text = lang_key; *text; text++)
+         /* empty loop */ ;
+
+      if (text != key + png_ptr->current_text_size)
+         text++;
+
+      text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
+      text_ptr->compression = comp_flag + 2;
+      text_ptr->key = key;
+      text_ptr->lang = lang;
+      text_ptr->lang_key = lang_key;
       text_ptr->text = text;
+      text_ptr->text_length = 0;
+      text_ptr->itxt_length = png_strlen(text);
 
       png_set_text(png_ptr, info_ptr, text_ptr, 1);
 
@@ -1068,42 +1363,89 @@
 #endif
 
 /* This function is called when we haven't found a handler for this
- * chunk.  In the future we will have code here that can handle
- * user-defined callback functions for unknown chunks before they are
- * ignored or cause an error.  If there isn't a problem with the
- * chunk itself (ie a bad chunk name or a critical chunk), the chunk
- * is (currently) silently ignored.
+ * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
+ * name or a critical chunk), the chunk is (currently) silently ignored.
  */
-void
+void /* PRIVATE */
 png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
+   png_uint_32 skip=0;
    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
 
    if (!(png_ptr->chunk_name[0] & 0x20))
    {
-      png_chunk_error(png_ptr, "unknown critical chunk");
-      /* to quiet some compiler warnings */
-      if(info_ptr == NULL) return;
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+      if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+           HANDLE_CHUNK_ALWAYS
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+           && png_ptr->read_user_chunk_fn == (png_user_chunk_ptr)NULL
+#endif
+         )
+#endif
+         png_chunk_error(png_ptr, "unknown critical chunk");
+
+      /* to quiet compiler warnings about unused info_ptr */
+      if (info_ptr == NULL)
+         return;
    }
 
-   png_push_crc_skip(png_ptr, length);
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+   if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
+   {
+       png_unknown_chunk chunk;
+
+#ifdef PNG_MAX_MALLOC_64K
+       if (length > (png_uint_32)65535L)
+       {
+           png_warning(png_ptr, "unknown chunk too large to fit in memory");
+           skip = length - (png_uint_32)65535L;
+           length = (png_uint_32)65535L;
+       }
+#endif
+
+       strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
+       chunk.data = (png_bytep)png_malloc(png_ptr, length);
+       png_crc_read(png_ptr, chunk.data, length);
+       chunk.size = length;
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+       if(png_ptr->read_user_chunk_fn != (png_user_chunk_ptr)NULL)
+       {
+          /* callback to user unknown chunk handler */
+          if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
+          {
+             if (!(png_ptr->chunk_name[0] & 0x20))
+                if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+                     HANDLE_CHUNK_ALWAYS)
+                   png_chunk_error(png_ptr, "unknown critical chunk");
+          }
+             png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
+       }
+       else
+#endif
+          png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
+       png_free(png_ptr, chunk.data);
+   }
+   else
+#endif
+      skip=length;
+   png_push_crc_skip(png_ptr, skip);
 }
 
-void
+void /* PRIVATE */
 png_push_have_info(png_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr->info_fn != NULL)
       (*(png_ptr->info_fn))(png_ptr, info_ptr);
 }
 
-void
+void /* PRIVATE */
 png_push_have_end(png_structp png_ptr, png_infop info_ptr)
 {
    if (png_ptr->end_fn != NULL)
       (*(png_ptr->end_fn))(png_ptr, info_ptr);
 }
 
-void
+void /* PRIVATE */
 png_push_have_row(png_structp png_ptr, png_bytep row)
 {
    if (png_ptr->row_fn != NULL)
@@ -1111,15 +1453,19 @@
          (int)png_ptr->pass);
 }
 
-void
+void PNGAPI
 png_progressive_combine_row (png_structp png_ptr,
    png_bytep old_row, png_bytep new_row)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   const int FARDATA png_pass_dsp_mask[7] =
+      {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+#endif
    if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
       png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
 }
 
-void
+void PNGAPI
 png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
    png_progressive_end_ptr end_fn)
@@ -1131,7 +1477,7 @@
    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
 }
 
-png_voidp
+png_voidp PNGAPI
 png_get_progressive_ptr(png_structp png_ptr)
 {
    return png_ptr->io_ptr;

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngset.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngset.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngset.c	Sat Jul 13 21:26:51 2002
@@ -1,11 +1,11 @@
 
 /* pngset.c - storage of image information into info struct
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * The functions here are used during reads to store data from the file
  * into the info struct, and during writes to store application data
@@ -16,8 +16,8 @@
 #define PNG_INTERNAL
 #include "png.h"
 
-#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED)
-void
+#if defined(PNG_bKGD_SUPPORTED)
+void PNGAPI
 png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
 {
    png_debug1(1, "in %s storage function\n", "bKGD");
@@ -29,8 +29,9 @@
 }
 #endif
 
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
-void
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
 png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
    double white_x, double white_y, double red_x, double red_y,
    double green_x, double green_y, double blue_x, double blue_y)
@@ -47,12 +48,56 @@
    info_ptr->y_green = (float)green_y;
    info_ptr->x_blue  = (float)blue_x;
    info_ptr->y_blue  = (float)blue_y;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5);
+   info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5);
+   info_ptr->int_x_red   = (png_fixed_point)(red_x*100000.+0.5);
+   info_ptr->int_y_red   = (png_fixed_point)(red_y*100000.+0.5);
+   info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5);
+   info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5);
+   info_ptr->int_x_blue  = (png_fixed_point)(blue_x*100000.+0.5);
+   info_ptr->int_y_blue  = (png_fixed_point)(blue_y*100000.+0.5);
+#endif
    info_ptr->valid |= PNG_INFO_cHRM;
 }
 #endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
+   png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
+   png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
+   png_fixed_point blue_x, png_fixed_point blue_y)
+{
+   png_debug1(1, "in %s storage function\n", "cHRM");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->int_x_white = white_x;
+   info_ptr->int_y_white = white_y;
+   info_ptr->int_x_red   = red_x;
+   info_ptr->int_y_red   = red_y;
+   info_ptr->int_x_green = green_x;
+   info_ptr->int_y_green = green_y;
+   info_ptr->int_x_blue  = blue_x;
+   info_ptr->int_y_blue  = blue_y;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   info_ptr->x_white = (float)(white_x/100000.);
+   info_ptr->y_white = (float)(white_y/100000.);
+   info_ptr->x_red   = (float)(red_x/100000.);
+   info_ptr->y_red   = (float)(red_y/100000.);
+   info_ptr->x_green = (float)(green_x/100000.);
+   info_ptr->y_green = (float)(green_y/100000.);
+   info_ptr->x_blue  = (float)(blue_x/100000.);
+   info_ptr->y_blue  = (float)(blue_y/100000.);
+#endif
+   info_ptr->valid |= PNG_INFO_cHRM;
+}
+#endif
+#endif
 
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
-void
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
 png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
 {
    png_debug1(1, "in %s storage function\n", "gAMA");
@@ -60,24 +105,63 @@
       return;
 
    info_ptr->gamma = (float)file_gamma;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   info_ptr->int_gamma = (int)(file_gamma*100000.+.5);
+#endif
    info_ptr->valid |= PNG_INFO_gAMA;
 }
 #endif
+#endif
+void PNGAPI
+png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
+   int_gamma)
+{
+   png_debug1(1, "in %s storage function\n", "gAMA");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   info_ptr->gamma = (float)(int_gamma/100000.);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   info_ptr->int_gamma = int_gamma;
+#endif
+   info_ptr->valid |= PNG_INFO_gAMA;
+}
 
-#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
-void
+#if defined(PNG_hIST_SUPPORTED)
+void PNGAPI
 png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
 {
+   int	i;
+
    png_debug1(1, "in %s storage function\n", "hIST");
    if (png_ptr == NULL || info_ptr == NULL)
       return;
-
-   info_ptr->hist = hist;
+   if (info_ptr->num_palette == 0)
+       png_warning(png_ptr,
+		   "Palette size 0, hIST allocation skipped.");
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
+#endif
+   png_ptr->hist = (png_uint_16p)png_malloc(png_ptr,
+      (png_uint_32)(info_ptr->num_palette * sizeof (png_uint_16)));
+
+   for (i = 0; i < info_ptr->num_palette; i++)
+       png_ptr->hist[i] = hist[i];
+   info_ptr->hist = png_ptr->hist;
    info_ptr->valid |= PNG_INFO_hIST;
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_HIST;
+#else
+   png_ptr->flags |= PNG_FLAG_FREE_HIST;
+#endif
 }
 #endif
 
-void
+void PNGAPI
 png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
    png_uint_32 width, png_uint_32 height, int bit_depth,
    int color_type, int interlace_type, int compression_type,
@@ -107,7 +191,7 @@
 
    /* check for overflow */
    rowbytes_per_pixel = (info_ptr->pixel_depth + 7) >> 3;
-   if (( width > (png_uint_32)2147483647L/rowbytes_per_pixel))
+   if (( width > PNG_MAX_UINT/rowbytes_per_pixel))
    {
       png_warning(png_ptr,
          "Width too large to process image data; rowbytes will overflow.");
@@ -117,10 +201,10 @@
       info_ptr->rowbytes = (info_ptr->width * info_ptr->pixel_depth + 7) >> 3;
 }
 
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
-void
+#if defined(PNG_oFFs_SUPPORTED)
+void PNGAPI
 png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
-   png_uint_32 offset_x, png_uint_32 offset_y, int unit_type)
+   png_int_32 offset_x, png_int_32 offset_y, int unit_type)
 {
    png_debug1(1, "in %s storage function\n", "oFFs");
    if (png_ptr == NULL || info_ptr == NULL)
@@ -133,8 +217,8 @@
 }
 #endif
 
-#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
-void
+#if defined(PNG_pCAL_SUPPORTED)
+void PNGAPI
 png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
    png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
    png_charp units, png_charpp params)
@@ -147,7 +231,7 @@
       return;
 
    length = png_strlen(purpose) + 1;
-   png_debug1(3, "allocating purpose for info (%d bytes)\n", length);
+   png_debug1(3, "allocating purpose for info (%lu bytes)\n", length);
    info_ptr->pcal_purpose = (png_charp)png_malloc(png_ptr, length);
    png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
 
@@ -158,7 +242,7 @@
    info_ptr->pcal_nparams = (png_byte)nparams;
 
    length = png_strlen(units) + 1;
-   png_debug1(3, "allocating units for info (%d bytes)\n", length);
+   png_debug1(3, "allocating units for info (%lu bytes)\n", length);
    info_ptr->pcal_units = (png_charp)png_malloc(png_ptr, length);
    png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
 
@@ -169,17 +253,69 @@
    for (i = 0; i < nparams; i++)
    {
       length = png_strlen(params[i]) + 1;
-      png_debug2(3, "allocating parameter %d for info (%d bytes)\n", i, length);
+      png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length);
       info_ptr->pcal_params[i] = (png_charp)png_malloc(png_ptr, length);
       png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
    }
 
    info_ptr->valid |= PNG_INFO_pCAL;
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_PCAL;
+#endif
 }
 #endif
 
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
-void
+#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
+             int unit, double width, double height)
+{
+   png_debug1(1, "in %s storage function\n", "sCAL");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->scal_unit = (png_byte)unit;
+   info_ptr->scal_pixel_width = width;
+   info_ptr->scal_pixel_height = height;
+
+   info_ptr->valid |= PNG_INFO_sCAL;
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
+             int unit, png_charp swidth, png_charp sheight)
+{
+   png_uint_32 length;
+
+   png_debug1(1, "in %s storage function\n", "sCAL");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->scal_unit = (png_byte)unit;
+
+   length = png_strlen(swidth) + 1;
+   png_debug1(3, "allocating unit for info (%d bytes)\n", length);
+   info_ptr->scal_s_width = (png_charp)png_malloc(png_ptr, length);
+   png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
+
+   length = png_strlen(sheight) + 1;
+   png_debug1(3, "allocating unit for info (%d bytes)\n", length);
+   info_ptr->scal_s_width = (png_charp)png_malloc(png_ptr, length);
+   png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
+
+   info_ptr->valid |= PNG_INFO_sCAL;
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_SCAL;
+#endif
+}
+#endif
+#endif
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+void PNGAPI
 png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
    png_uint_32 res_x, png_uint_32 res_y, int unit_type)
 {
@@ -194,21 +330,40 @@
 }
 #endif
 
-void
+void PNGAPI
 png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
    png_colorp palette, int num_palette)
 {
+
    png_debug1(1, "in %s storage function\n", "PLTE");
    if (png_ptr == NULL || info_ptr == NULL)
       return;
 
-   info_ptr->palette = palette;
-   info_ptr->num_palette = (png_uint_16)num_palette;
+   /*
+    * It may not actually be necessary to set png_ptr->palette here;
+    * we do it for backward compatibility with the way the png_handle_tRNS
+    * function used to do the allocation.
+    */
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
+#endif
+   png_ptr->palette = (png_colorp)png_zalloc(png_ptr, (uInt)num_palette,
+      sizeof (png_color));
+   memcpy(png_ptr->palette, palette, num_palette * sizeof (png_color));
+   info_ptr->palette = png_ptr->palette;
+   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_PLTE;
+#else
+   png_ptr->flags |= PNG_FLAG_FREE_PLTE;
+#endif
+
    info_ptr->valid |= PNG_INFO_PLTE;
 }
 
-#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
-void
+#if defined(PNG_sBIT_SUPPORTED)
+void PNGAPI
 png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
    png_color_8p sig_bit)
 {
@@ -221,8 +376,8 @@
 }
 #endif
 
-#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
-void
+#if defined(PNG_sRGB_SUPPORTED)
+void PNGAPI
 png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
 {
    png_debug1(1, "in %s storage function\n", "sRGB");
@@ -232,28 +387,61 @@
    info_ptr->srgb_intent = (png_byte)intent;
    info_ptr->valid |= PNG_INFO_sRGB;
 }
-void
+
+void PNGAPI
 png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
    int intent)
 {
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
    float file_gamma;
 #endif
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_fixed_point int_file_gamma;
+#endif
+#endif
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
    float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
 #endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
+      int_green_y, int_blue_x, int_blue_y;
+#endif
+#endif
    png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
    if (png_ptr == NULL || info_ptr == NULL)
       return;
 
    png_set_sRGB(png_ptr, info_ptr, intent);
 
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
-   file_gamma = (float).45;
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   file_gamma = (float).45455;
    png_set_gAMA(png_ptr, info_ptr, file_gamma);
 #endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   int_file_gamma = 45455L;
+   png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
+#endif
+#endif
 
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   int_white_x = 31270L;
+   int_white_y = 32900L;
+   int_red_x   = 64000L;
+   int_red_y   = 33000L;
+   int_green_x = 30000L;
+   int_green_y = 60000L;
+   int_blue_x  = 15000L;
+   int_blue_y  =  6000L;
+
+   png_set_cHRM_fixed(png_ptr, info_ptr,
+      int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y,
+      int_blue_x, int_blue_y);
+#endif
+#ifdef PNG_FLOATING_POINT_SUPPORTED
    white_x = (float).3127;
    white_y = (float).3290;
    red_x   = (float).64;
@@ -265,14 +453,47 @@
 
    png_set_cHRM(png_ptr, info_ptr,
       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
+#endif
+#endif
+}
+#endif
+
+
+#if defined(PNG_iCCP_SUPPORTED)
+void PNGAPI
+png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
+             png_charp name, int compression_type,
+             png_charp profile, png_uint_32 proflen)
+{
+   png_charp new_iccp_name;
+   png_charp new_iccp_profile;
 
+   png_debug1(1, "in %s storage function\n", "iCCP");
+   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
+      return;
+
+   new_iccp_name = png_malloc(png_ptr, png_strlen(name)+1);
+   strcpy(new_iccp_name, name);
+   new_iccp_profile = png_malloc(png_ptr, proflen);
+   png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
+
+   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
+
+   info_ptr->iccp_proflen = proflen;
+   info_ptr->iccp_name = new_iccp_name;
+   info_ptr->iccp_profile = new_iccp_profile;
+   /* Compression is always zero but is here so the API and info structure
+    * does not have to change if we introduce multiple compression types */
+   info_ptr->iccp_compression = (png_byte)compression_type;
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_ICCP;
 #endif
+   info_ptr->valid |= PNG_INFO_iCCP;
 }
 #endif
 
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
-    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
-void
+#if defined(PNG_TEXT_SUPPORTED)
+void PNGAPI
 png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
    int num_text)
 {
@@ -309,42 +530,126 @@
          info_ptr->num_text = 0;
          info_ptr->text = (png_textp)png_malloc(png_ptr,
             (png_uint_32)(info_ptr->max_text * sizeof (png_text)));
+#ifdef PNG_FREE_ME_SUPPORTED
+         info_ptr->free_me |= PNG_FREE_TEXT;
+#endif
       }
       png_debug1(3, "allocated %d entries for info_ptr->text\n",
          info_ptr->max_text);
    }
-
    for (i = 0; i < num_text; i++)
    {
+      png_size_t text_length,key_len;
+      png_size_t lang_len,lang_key_len;
       png_textp textp = &(info_ptr->text[info_ptr->num_text]);
 
-      if (text_ptr[i].text == NULL)
-         text_ptr[i].text = (png_charp)"";
+      if (text_ptr[i].key == (png_charp)NULL)
+          continue;
+
+      key_len = png_strlen(text_ptr[i].key);
 
-      if (text_ptr[i].text[0] == '\0')
+      if(text_ptr[i].compression <= 0)
       {
-         textp->text_length = 0;
-         textp->compression = PNG_TEXT_COMPRESSION_NONE;
+        lang_len = 0;
+        lang_key_len = 0;
+      }
+      else
+#ifdef PNG_iTXt_SUPPORTED
+      {
+        /* set iTXt data */
+        if (text_ptr[i].key != (png_charp)NULL)
+          lang_len = png_strlen(text_ptr[i].lang);
+        else
+          lang_len = 0;
+        if (text_ptr[i].lang_key != (png_charp)NULL)
+          lang_key_len = png_strlen(text_ptr[i].lang_key);
+        else
+          lang_key_len = 0;
+      }
+#else
+      {
+        png_warning(png_ptr, "iTXt chunk not supported.");
+        continue;
+      }
+#endif
+
+      if (text_ptr[i].text == (png_charp)NULL || text_ptr[i].text[0] == '\0')
+      {
+         text_length = 0;
+#ifdef PNG_iTXt_SUPPORTED
+         if(text_ptr[i].compression > 0)
+            textp->compression = PNG_ITXT_COMPRESSION_NONE;
+         else
+#endif
+            textp->compression = PNG_TEXT_COMPRESSION_NONE;
       }
       else
       {
-         textp->text_length = png_strlen(text_ptr[i].text);
+         text_length = png_strlen(text_ptr[i].text);
          textp->compression = text_ptr[i].compression;
       }
-      textp->text = text_ptr[i].text;
-      textp->key = text_ptr[i].key;
+
+      textp->key = (png_charp)png_malloc(png_ptr,
+         (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4));
+      png_debug2(2, "Allocated %d bytes at %x in png_set_text\n",
+         key_len + lang_len + lang_key_len + text_length + 4, (int)textp->key);
+
+      png_memcpy(textp->key, text_ptr[i].key,
+         (png_size_t)(key_len));
+      *(textp->key+key_len) = '\0';
+#ifdef PNG_iTXt_SUPPORTED
+      if (text_ptr[i].compression > 0)
+      {
+         textp->lang=textp->key + key_len + 1;
+         png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
+         *(textp->lang+lang_len) = '\0';
+         textp->lang_key=textp->lang + lang_len + 1;
+         png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
+         *(textp->lang_key+lang_key_len) = '\0';
+         textp->text=textp->lang_key + lang_key_len + 1;
+      }
+      else
+#endif
+      {
+#ifdef PNG_iTXt_SUPPORTED
+         textp->lang=(png_charp)NULL;
+         textp->lang_key=(png_charp)NULL;
+#endif
+         textp->text=textp->key + key_len + 1;
+      }
+      if(text_length)
+         png_memcpy(textp->text, text_ptr[i].text,
+            (png_size_t)(text_length));
+      *(textp->text+text_length) = '\0';
+
+#ifdef PNG_iTXt_SUPPORTED
+      if(textp->compression > 0)
+      {
+         textp->text_length = 0;
+         textp->itxt_length = text_length;
+      }
+      else
+#endif
+      {
+         textp->text_length = text_length;
+#ifdef PNG_iTXt_SUPPORTED
+         textp->itxt_length = 0;
+#endif
+      }
+      info_ptr->text[info_ptr->num_text]= *textp;
       info_ptr->num_text++;
       png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
    }
 }
 #endif
 
-#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
-void
+#if defined(PNG_tIME_SUPPORTED)
+void PNGAPI
 png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
 {
    png_debug1(1, "in %s storage function\n", "tIME");
-   if (png_ptr == NULL || info_ptr == NULL)
+   if (png_ptr == NULL || info_ptr == NULL ||
+       (png_ptr->mode & PNG_WROTE_tIME))
       return;
 
    png_memcpy(&(info_ptr->mod_time), mod_time, sizeof (png_time));
@@ -352,8 +657,8 @@
 }
 #endif
 
-#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED)
-void
+#if defined(PNG_tRNS_SUPPORTED)
+void PNGAPI
 png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
    png_bytep trans, int num_trans, png_color_16p trans_values)
 {
@@ -363,7 +668,21 @@
 
    if (trans != NULL)
    {
-      info_ptr->trans = trans;
+       /*
+	* It may not actually be necessary to set png_ptr->trans here;
+	* we do it for backward compatibility with the way the png_handle_tRNS
+	* function used to do the allocation.
+	*/
+#ifdef PNG_FREE_ME_SUPPORTED
+       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
+#endif
+       png_ptr->trans = info_ptr->trans = png_malloc(png_ptr, num_trans);
+       memcpy(info_ptr->trans, trans, num_trans);
+#ifdef PNG_FREE_ME_SUPPORTED
+       info_ptr->free_me |= PNG_FREE_TRNS;
+#else
+       png_ptr->flags |= PNG_FLAG_FREE_TRNS;
+#endif
    }
 
    if (trans_values != NULL)
@@ -378,3 +697,213 @@
 }
 #endif
 
+#if defined(PNG_sPLT_SUPPORTED)
+void PNGAPI
+png_set_sPLT(png_structp png_ptr,
+             png_infop info_ptr, png_sPLT_tp entries, int nentries)
+{
+    png_sPLT_tp np;
+    int i;
+
+    np = (png_sPLT_tp)png_malloc(png_ptr,
+        (info_ptr->splt_palettes_num + nentries) * sizeof(png_sPLT_t));
+
+    png_memcpy(np, info_ptr->splt_palettes,
+           info_ptr->splt_palettes_num * sizeof(png_sPLT_t));
+    png_free(png_ptr, info_ptr->splt_palettes);
+    info_ptr->splt_palettes=NULL;
+
+    for (i = 0; i < nentries; i++)
+    {
+        png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
+        png_sPLT_tp from = entries + i;
+
+        to->name = (png_charp)png_malloc(png_ptr,
+                                        png_strlen(from->name) + 1);
+        png_strcpy(to->name, from->name);
+        to->entries = (png_sPLT_entryp)png_malloc(png_ptr,
+                                 from->nentries * sizeof(png_sPLT_t));
+        png_memcpy(to->entries, from->entries,
+               from->nentries * sizeof(png_sPLT_t));
+        to->nentries = from->nentries;
+        to->depth = from->depth;
+    }
+
+    info_ptr->splt_palettes = np;
+    info_ptr->splt_palettes_num += nentries;
+    info_ptr->valid |= PNG_INFO_sPLT;
+#ifdef PNG_FREE_ME_SUPPORTED
+    info_ptr->free_me |= PNG_FREE_SPLT;
+#endif
+}
+#endif /* PNG_sPLT_SUPPORTED */
+
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+void PNGAPI
+png_set_unknown_chunks(png_structp png_ptr,
+   png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
+{
+    png_unknown_chunkp np;
+    int i;
+
+    if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
+        return;
+
+    np = (png_unknown_chunkp)png_malloc(png_ptr,
+        (info_ptr->unknown_chunks_num + num_unknowns) *
+        sizeof(png_unknown_chunk));
+
+    png_memcpy(np, info_ptr->unknown_chunks,
+           info_ptr->unknown_chunks_num * sizeof(png_unknown_chunk));
+    png_free(png_ptr, info_ptr->unknown_chunks);
+    info_ptr->unknown_chunks=NULL;
+
+    for (i = 0; i < num_unknowns; i++)
+    {
+        png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
+        png_unknown_chunkp from = unknowns + i;
+
+        png_strcpy((png_charp)to->name, (png_charp)from->name);
+        to->data = (png_bytep)png_malloc(png_ptr, from->size);
+        png_memcpy(to->data, from->data, from->size);
+        to->size = from->size;
+
+        /* note our location in the read or write sequence */
+        to->location = (png_byte)(png_ptr->mode & 0xff);
+    }
+
+    info_ptr->unknown_chunks = np;
+    info_ptr->unknown_chunks_num += num_unknowns;
+#ifdef PNG_FREE_ME_SUPPORTED
+    info_ptr->free_me |= PNG_FREE_UNKN;
+#endif
+}
+void PNGAPI
+png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
+   int chunk, int location)
+{
+   if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
+         (int)info_ptr->unknown_chunks_num)
+      info_ptr->unknown_chunks[chunk].location = (png_byte)location;
+}
+#endif
+
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+void PNGAPI
+png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
+{
+   /* This function is deprecated in favor of png_permit_mng_features()
+      and will be removed from libpng-2.0.0 */
+   png_debug(1, "in png_permit_empty_plte, DEPRECATED.\n");
+   if (png_ptr == NULL)
+      return;
+   png_ptr->mng_features_permitted = (png_byte)
+     ((png_ptr->mng_features_permitted & (~(PNG_FLAG_MNG_EMPTY_PLTE))) |
+     ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE)));
+}
+#endif
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+png_uint_32 PNGAPI
+png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
+{
+   png_debug(1, "in png_permit_mng_features\n");
+   if (png_ptr == NULL)
+      return (png_uint_32)0;
+   png_ptr->mng_features_permitted =
+     (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
+   return (png_uint_32)png_ptr->mng_features_permitted;
+}
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+void PNGAPI
+png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep
+   chunk_list, int num_chunks)
+{
+    png_bytep new_list, p;
+    int i, old_num_chunks;
+    if (num_chunks == 0)
+    {
+      if(keep == HANDLE_CHUNK_ALWAYS || keep == HANDLE_CHUNK_IF_SAFE)
+        png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
+      else
+        png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
+
+      if(keep == HANDLE_CHUNK_ALWAYS)
+        png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
+      else
+        png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
+      return;
+    }
+    if (chunk_list == NULL)
+      return;
+    old_num_chunks=png_ptr->num_chunk_list;
+    new_list=png_malloc(png_ptr,5*(num_chunks+old_num_chunks));
+    if(png_ptr->chunk_list != (png_bytep)NULL)
+    {
+       png_memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks);
+       png_free(png_ptr, png_ptr->chunk_list);
+       png_ptr->chunk_list=NULL;
+    }
+    png_memcpy(new_list+5*old_num_chunks, chunk_list, 5*num_chunks);
+    for (p=new_list+5*old_num_chunks+4, i=0; i<num_chunks; i++, p+=5)
+       *p=(png_byte)keep;
+    png_ptr->num_chunk_list=old_num_chunks+num_chunks;
+    png_ptr->chunk_list=new_list;
+#ifdef PNG_FREE_ME_SUPPORTED
+    png_ptr->free_me |= PNG_FREE_LIST;
+#endif
+}
+#endif
+
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+void PNGAPI
+png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
+   png_user_chunk_ptr read_user_chunk_fn)
+{
+   png_debug(1, "in png_set_read_user_chunk_fn\n");
+   png_ptr->read_user_chunk_fn = read_user_chunk_fn;
+   png_ptr->user_chunk_ptr = user_chunk_ptr;
+}
+#endif
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+void PNGAPI
+png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
+{
+   png_debug1(1, "in %s storage function\n", "rows");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if(info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
+      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+   info_ptr->row_pointers = row_pointers;
+   if(row_pointers)
+      info_ptr->valid |= PNG_INFO_IDAT;
+
+}
+#endif
+
+void PNGAPI
+png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size)
+{
+    if(png_ptr->zbuf)
+       png_free(png_ptr, png_ptr->zbuf);
+    png_ptr->zbuf_size = (png_size_t)size;
+    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
+    if(!png_ptr->zbuf)
+       png_error(png_ptr,"Unable to malloc zbuf");
+    png_ptr->zstream.next_out = png_ptr->zbuf;
+    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+}
+
+void PNGAPI
+png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
+{
+   if (png_ptr && info_ptr)
+      info_ptr->valid &= ~(mask);
+}
+

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwio.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwio.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwio.c	Sat Jul 13 21:26:51 2002
@@ -1,11 +1,11 @@
 
 /* pngwio.c - functions for data output
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This file provides a location for all output.  Users who need
  * special handling are expected to write functions that have the same
@@ -24,7 +24,7 @@
    buffering if you are using unbuffered writes.  This should never be asked
    to write more than 64K on a 16 bit machine.  */
 
-void
+void /* PRIVATE */
 png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
 {
    if (png_ptr->write_data_fn != NULL )
@@ -39,16 +39,19 @@
    write_data function and use it at run time with png_set_write_fn(), rather
    than changing the library. */
 #ifndef USE_FAR_KEYWORD
-static void
+static void /* PRIVATE */
 png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
 {
    png_uint_32 check;
 
-   check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));
+#if defined(_WIN32_WCE)
+   if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+      check = 0;
+#else
+   check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
+#endif
    if (check != length)
-   {
       png_error(png_ptr, "Write Error");
-   }
 }
 #else
 /* this is the model-independent version. Since the standard I/O library
@@ -59,19 +62,24 @@
 #define NEAR_BUF_SIZE 1024
 #define MIN(a,b) (a <= b ? a : b)
 
-static void
+static void /* PRIVATE */
 png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
 {
    png_uint_32 check;
    png_byte *near_data;  /* Needs to be "png_byte *" instead of "png_bytep" */
-   FILE *io_ptr;
+   png_FILE_p io_ptr;
 
    /* Check if data really is near. If so, use usual code. */
    near_data = (png_byte *)CVT_PTR_NOCHECK(data);
-   io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
+   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
    if ((png_bytep)near_data == data)
    {
+#if defined(_WIN32_WCE)
+      if ( !WriteFile(io_ptr, near_data, length, &check, NULL) )
+         check = 0;
+#else
       check = fwrite(near_data, 1, length, io_ptr);
+#endif
    }
    else
    {
@@ -83,7 +91,12 @@
       {
          written = MIN(NEAR_BUF_SIZE, remaining);
          png_memcpy(buf, data, written); /* copy far buffer to near buffer */
+#if defined(_WIN32_WCE)
+         if ( !WriteFile(io_ptr, buf, written, &err, NULL) )
+            err = 0;
+#else
          err = fwrite(buf, 1, written, io_ptr);
+#endif
          if (err != written)
             break;
          else
@@ -94,9 +107,7 @@
       while (remaining != 0);
    }
    if (check != length)
-   {
       png_error(png_ptr, "Write Error");
-   }
 }
 
 #endif
@@ -106,7 +117,7 @@
    to disk).  After png_flush is called, there should be no data pending
    writing in any buffers. */
 #if defined(PNG_WRITE_FLUSH_SUPPORTED)
-void
+void /* PRIVATE */
 png_flush(png_structp png_ptr)
 {
    if (png_ptr->output_flush_fn != NULL)
@@ -114,13 +125,15 @@
 }
 
 #if !defined(PNG_NO_STDIO)
-static void
+static void /* PRIVATE */
 png_default_flush(png_structp png_ptr)
 {
-   FILE *io_ptr;
-   io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
+#if !defined(_WIN32_WCE)
+   png_FILE_p io_ptr;
+   io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
    if (io_ptr != NULL)
       fflush(io_ptr);
+#endif
 }
 #endif
 #endif
@@ -147,7 +160,7 @@
                    PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
                    time, output_flush_fn will be ignored, although it must be
                    supplied for compatibility. */
-void
+void PNGAPI
 png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
    png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
 {

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngrutil.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngrutil.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngrutil.c	Sat Jul 13 21:26:52 2002
@@ -1,11 +1,11 @@
 
 /* pngrutil.c - utilities to read a PNG file
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This file contains routines that are only called from within
  * libpng itself during the course of reading an image.
@@ -14,9 +14,33 @@
 #define PNG_INTERNAL
 #include "png.h"
 
+#if defined(_WIN32_WCE)
+/* strtod() function is not supported on WindowsCE */
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+__inline double strtod(const char *nptr, char **endptr)
+{
+   double result = 0;
+   int len;
+   wchar_t *str, *end;
+
+   len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
+   str = (wchar_t *)malloc(len * sizeof(wchar_t));
+   if ( NULL != str )
+   {
+      MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
+      result = wcstod(str, &end);
+      len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
+      *endptr = (char *)nptr + (strlen(nptr) - len + 1);
+      free(str);
+   }
+   return result;
+}
+#  endif
+#endif
+
 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
-png_uint_32
+png_uint_32 /* PRIVATE */
 png_get_uint_32(png_bytep buf)
 {
    png_uint_32 i = ((png_uint_32)(*buf) << 24) +
@@ -27,11 +51,11 @@
    return (i);
 }
 
-#if defined(PNG_READ_pCAL_SUPPORTED)
+#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED)
 /* Grab a signed 32-bit integer from a buffer in big-endian format.  The
  * data is stored in the PNG file in two's complement format, and it is
  * assumed that the machine format for signed integers is the same. */
-png_int_32
+png_int_32 /* PRIVATE */
 png_get_int_32(png_bytep buf)
 {
    png_int_32 i = ((png_int_32)(*buf) << 24) +
@@ -44,7 +68,7 @@
 #endif /* PNG_READ_pCAL_SUPPORTED */
 
 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
-png_uint_16
+png_uint_16 /* PRIVATE */
 png_get_uint_16(png_bytep buf)
 {
    png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
@@ -55,7 +79,7 @@
 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
 
 /* Read data, and (optionally) run it through the CRC. */
-void
+void /* PRIVATE */
 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
 {
    png_read_data(png_ptr, buf, length);
@@ -66,7 +90,7 @@
    are reading a ancillary or critical chunk, and how the program has set
    things up, we may calculate the CRC on the data and print a message.
    Returns '1' if there was a CRC error, '0' otherwise. */
-int
+int /* PRIVATE */
 png_crc_finish(png_structp png_ptr, png_uint_32 skip)
 {
    png_size_t i;
@@ -83,10 +107,10 @@
 
    if (png_crc_error(png_ptr))
    {
-      if ((png_ptr->chunk_name[0] & 0x20 &&                /* Ancillary */
+      if (((png_ptr->chunk_name[0] & 0x20) &&                /* Ancillary */
            !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
           (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
-           png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))
+          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
       {
          png_chunk_warning(png_ptr, "CRC error");
       }
@@ -102,7 +126,7 @@
 
 /* Compare the CRC stored in the PNG file with that calculated by libpng from
    the data it has read thus far. */
-int
+int /* PRIVATE */
 png_crc_error(png_structp png_ptr)
 {
    png_byte crc_bytes[4];
@@ -132,9 +156,153 @@
       return (0);
 }
 
+#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
+    defined(PNG_READ_iCCP_SUPPORTED)
+/*
+ * Decompress trailing data in a chunk.  The assumption is that chunkdata
+ * points at an allocated area holding the contents of a chunk with a
+ * trailing compressed part.  What we get back is an allocated area
+ * holding the original prefix part and an uncompressed version of the
+ * trailing part (the malloc area passed in is freed).
+ */
+png_charp /* PRIVATE */
+png_decompress_chunk(png_structp png_ptr, int comp_type,
+                              png_charp chunkdata, png_size_t chunklength,
+                              png_size_t prefix_size, png_size_t *newlength)
+{
+   static char msg[] = "Error decoding compressed text";
+   png_charp text = NULL;
+   png_size_t text_size;
+
+   if (comp_type == PNG_COMPRESSION_TYPE_BASE)
+   {
+      int ret = Z_OK;
+      png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
+      png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
+      png_ptr->zstream.next_out = png_ptr->zbuf;
+      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+      text_size = 0;
+      text = NULL;
+
+      while (png_ptr->zstream.avail_in)
+      {
+         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+         if (ret != Z_OK && ret != Z_STREAM_END)
+         {
+            if (png_ptr->zstream.msg != NULL)
+               png_warning(png_ptr, png_ptr->zstream.msg);
+            else
+               png_warning(png_ptr, msg);
+            inflateReset(&png_ptr->zstream);
+            png_ptr->zstream.avail_in = 0;
+
+            if (text ==  NULL)
+            {
+               text_size = prefix_size + sizeof(msg) + 1;
+               text = (png_charp)png_malloc(png_ptr, text_size);
+               png_memcpy(text, chunkdata, prefix_size);
+            }
+
+            text[text_size - 1] = 0x00;
+
+            /* Copy what we can of the error message into the text chunk */
+            text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
+            text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
+            png_memcpy(text + prefix_size, msg, text_size + 1);
+            break;
+         }
+         if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
+         {
+            if (text == NULL)
+            {
+               text_size = prefix_size +
+                   png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+               text = (png_charp)png_malloc(png_ptr, text_size + 1);
+               png_memcpy(text + prefix_size, png_ptr->zbuf,
+                          text_size - prefix_size);
+               png_memcpy(text, chunkdata, prefix_size);
+               *(text + text_size) = 0x00;
+            }
+            else
+            {
+               png_charp tmp;
+
+               tmp = text;
+               text = (png_charp)png_malloc(png_ptr, (png_uint_32)(text_size +
+                  png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
+               png_memcpy(text, tmp, text_size);
+               png_free(png_ptr, tmp);
+               png_memcpy(text + text_size, png_ptr->zbuf,
+                  (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
+               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+               *(text + text_size) = 0x00;
+            }
+            if (ret == Z_STREAM_END)
+               break;
+            else
+            {
+               png_ptr->zstream.next_out = png_ptr->zbuf;
+               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+            }
+         }
+      }
+      if (ret != Z_STREAM_END)
+      {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+         char umsg[50];
+
+         if (ret == Z_BUF_ERROR)
+            sprintf(umsg,"Buffer error in compressed datastream in %s chunk",
+                png_ptr->chunk_name);
+         else if (ret == Z_DATA_ERROR)
+            sprintf(umsg,"Data error in compressed datastream in %s chunk",
+                png_ptr->chunk_name);
+         else
+            sprintf(umsg,"Incomplete compressed datastream in %s chunk",
+                png_ptr->chunk_name);
+         png_warning(png_ptr, umsg);
+#else
+         png_warning(png_ptr,
+            "Incomplete compressed datastream in chunk other than IDAT");
+#endif
+         text_size=prefix_size;
+         if (text ==  NULL)
+         {
+            text = (png_charp)png_malloc(png_ptr, text_size+1);
+            png_memcpy(text, chunkdata, prefix_size);
+         }
+         *(text + text_size) = 0x00;
+      }
+
+      inflateReset(&png_ptr->zstream);
+      png_ptr->zstream.avail_in = 0;
+
+      png_free(png_ptr, chunkdata);
+      chunkdata = text;
+      *newlength=text_size;
+   }
+   else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
+   {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+      char umsg[50];
+
+      sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
+      png_warning(png_ptr, umsg);
+#else
+      png_warning(png_ptr, "Unknown zTXt compression type");
+#endif
+
+      *(chunkdata + prefix_size) = 0x00;
+      *newlength=prefix_size;
+   }
+
+   return chunkdata;
+}
+#endif
 
 /* read and check the IDHR chunk */
-void
+void /* PRIVATE */
 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
    png_byte buf[13];
@@ -144,7 +312,7 @@
 
    png_debug(1, "in png_handle_IHDR\n");
 
-   if (png_ptr->mode != PNG_BEFORE_IHDR)
+   if (png_ptr->mode & PNG_HAVE_IHDR)
       png_error(png_ptr, "Out of place IHDR");
 
    /* check the length */
@@ -165,8 +333,8 @@
    interlace_type = buf[12];
 
    /* check for width and height valid values */
-   if (width == 0 || width > (png_uint_32)2147483647L || height == 0 ||
-        height > (png_uint_32)2147483647L)
+   if (width == 0 || width > PNG_MAX_UINT || height == 0 ||
+        height > PNG_MAX_UINT)
       png_error(png_ptr, "Invalid image size in IHDR");
 
    /* check other values */
@@ -178,7 +346,7 @@
       color_type == 5 || color_type > 6)
       png_error(png_ptr, "Invalid color type in IHDR");
 
-   if ((color_type == PNG_COLOR_TYPE_PALETTE && bit_depth) > 8 ||
+   if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
        ((color_type == PNG_COLOR_TYPE_RGB ||
          color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
          color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
@@ -190,8 +358,33 @@
    if (compression_type != PNG_COMPRESSION_TYPE_BASE)
       png_error(png_ptr, "Unknown compression method in IHDR");
 
-   if (filter_type != PNG_FILTER_TYPE_BASE)
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+   /* Accept filter_method 64 (intrapixel differencing) only if
+    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+    * 2. Libpng did not read a PNG signature (this filter_method is only
+    *    used in PNG datastreams that are embedded in MNG datastreams) and
+    * 3. The application called png_permit_mng_features with a mask that
+    *    included PNG_FLAG_MNG_FILTER_64 and
+    * 4. The filter_method is 64 and
+    * 5. The color_type is RGB or RGBA
+    */
+   if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted)
+      png_warning(png_ptr,"MNG features are not allowed in a PNG datastream\n");
+   if(filter_type != PNG_FILTER_TYPE_BASE)
+   {
+     if(!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+        (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
+        ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
+        (color_type == PNG_COLOR_TYPE_RGB || 
+         color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
+        png_error(png_ptr, "Unknown filter method in IHDR");
+     if(png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)
+        png_warning(png_ptr, "Invalid filter method in IHDR");
+   }
+#else
+   if(filter_type != PNG_FILTER_TYPE_BASE)
       png_error(png_ptr, "Unknown filter method in IHDR");
+#endif
 
    /* set internal variables */
    png_ptr->width = width;
@@ -199,6 +392,7 @@
    png_ptr->bit_depth = (png_byte)bit_depth;
    png_ptr->interlaced = (png_byte)interlace_type;
    png_ptr->color_type = (png_byte)color_type;
+   png_ptr->filter_type = (png_byte)filter_type;
 
    /* find number of channels */
    switch (png_ptr->color_type)
@@ -225,17 +419,20 @@
       (png_uint_32)png_ptr->pixel_depth + 7) >> 3);
    png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
    png_debug1(3,"channels = %d\n", png_ptr->channels);
-   png_debug1(3,"rowbytes = %d\n", png_ptr->rowbytes);
+   png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
       color_type, interlace_type, compression_type, filter_type);
 }
 
 /* read and check the palette */
-void
+void /* PRIVATE */
 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
-   png_colorp palette;
+   png_color palette[PNG_MAX_PALETTE_LENGTH];
    int num, i;
+#ifndef PNG_NO_POINTER_INDEXING
+   png_colorp pal_ptr;
+#endif
 
    png_debug(1, "in png_handle_PLTE\n");
 
@@ -260,7 +457,7 @@
    }
 #endif
 
-   if (length % 3)
+   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
    {
       if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
       {
@@ -275,8 +472,18 @@
    }
 
    num = (int)length / 3;
-   palette = (png_colorp)png_zalloc(png_ptr, (uInt)num, sizeof (png_color));
-   png_ptr->flags |= PNG_FLAG_FREE_PALETTE;
+
+#ifndef PNG_NO_POINTER_INDEXING
+   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
+   {
+      png_byte buf[3];
+
+      png_crc_read(png_ptr, buf, 3);
+      pal_ptr->red = buf[0];
+      pal_ptr->green = buf[1];
+      pal_ptr->blue = buf[2];
+   }
+#else
    for (i = 0; i < num; i++)
    {
       png_byte buf[3];
@@ -287,6 +494,7 @@
       palette[i].green = buf[1];
       palette[i].blue = buf[2];
    }
+#endif
 
    /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
       whatever the normal CRC configuration tells us.  However, if we
@@ -314,8 +522,6 @@
          else
          {
             png_chunk_warning(png_ptr, "CRC error");
-            png_ptr->flags &= ~PNG_FLAG_FREE_PALETTE;
-            png_zfree(png_ptr, palette);
             return;
          }
       }
@@ -326,19 +532,23 @@
       }
    }
 #endif
-   png_ptr->palette = palette;
-   png_ptr->num_palette = (png_uint_16)num;
+
    png_set_PLTE(png_ptr, info_ptr, palette, num);
 
-#if defined (PNG_READ_tRNS_SUPPORTED)
+#if defined(PNG_READ_tRNS_SUPPORTED)
    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    {
-      if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
+      if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
       {
-         if (png_ptr->num_trans > png_ptr->num_palette)
+         if (png_ptr->num_trans > (png_uint_16)num)
          {
             png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
-            png_ptr->num_trans = png_ptr->num_palette;
+            png_ptr->num_trans = (png_uint_16)num;
+         }
+         if (info_ptr->num_trans > (png_uint_16)num)
+         {
+            png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
+            info_ptr->num_trans = (png_uint_16)num;
          }
       }
    }
@@ -346,7 +556,7 @@
 
 }
 
-void
+void /* PRIVATE */
 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
    png_debug(1, "in png_handle_IEND\n");
@@ -360,7 +570,7 @@
          return;
    }
 
-   png_ptr->mode |= PNG_AFTER_IDAT | PNG_HAVE_IEND;
+   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
 
    if (length != 0)
    {
@@ -370,11 +580,13 @@
 }
 
 #if defined(PNG_READ_gAMA_SUPPORTED)
-void
+void /* PRIVATE */
 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
-   png_uint_32 igamma;
+   png_fixed_point igamma;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
    float file_gamma;
+#endif
    png_byte buf[4];
 
    png_debug(1, "in png_handle_gAMA\n");
@@ -391,7 +603,7 @@
       /* Should be an error, but we can cope with it */
       png_warning(png_ptr, "Out of place gAMA chunk");
 
-   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_gAMA
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
 #if defined(PNG_READ_sRGB_SUPPORTED)
       && !(info_ptr->valid & PNG_INFO_sRGB)
 #endif
@@ -413,34 +625,39 @@
    if (png_crc_finish(png_ptr, 0))
       return;
 
-   igamma = png_get_uint_32(buf);
+   igamma = (png_fixed_point)png_get_uint_32(buf);
    /* check for zero gamma */
    if (igamma == 0)
       return;
 
 #if defined(PNG_READ_sRGB_SUPPORTED)
    if (info_ptr->valid & PNG_INFO_sRGB)
-      if(igamma != (png_uint_32)45000L)
+      if(igamma < 45000L || igamma > 46000L)
       {
          png_warning(png_ptr,
            "Ignoring incorrect gAMA value when sRGB is also present");
 #ifndef PNG_NO_CONSOLE_IO
-         fprintf(stderr, "igamma = %lu\n", igamma);
+         fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
 #endif
          return;
       }
 #endif /* PNG_READ_sRGB_SUPPORTED */
 
+#ifdef PNG_FLOATING_POINT_SUPPORTED
    file_gamma = (float)igamma / (float)100000.0;
-#ifdef PNG_READ_GAMMA_SUPPORTED
-   png_ptr->gamma = file_gamma;
+#  ifdef PNG_READ_GAMMA_SUPPORTED
+     png_ptr->gamma = file_gamma;
+#  endif
+     png_set_gAMA(png_ptr, info_ptr, file_gamma);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
 #endif
-   png_set_gAMA(png_ptr, info_ptr, file_gamma);
 }
 #endif
 
 #if defined(PNG_READ_sBIT_SUPPORTED)
-void
+void /* PRIVATE */
 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
    png_size_t truelen;
@@ -463,7 +680,7 @@
       /* Should be an error, but we can cope with it */
       png_warning(png_ptr, "Out of place sBIT chunk");
    }
-   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sBIT)
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
    {
       png_warning(png_ptr, "Duplicate sBIT chunk");
       png_crc_finish(png_ptr, length);
@@ -506,17 +723,20 @@
 #endif
 
 #if defined(PNG_READ_cHRM_SUPPORTED)
-void
+void /* PRIVATE */
 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
    png_byte buf[4];
-   png_uint_32 val;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
    float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
+#endif
+   png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
+      int_y_green, int_x_blue, int_y_blue;
 
    png_debug(1, "in png_handle_cHRM\n");
 
    if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before sBIT");
+      png_error(png_ptr, "Missing IHDR before cHRM");
    else if (png_ptr->mode & PNG_HAVE_IDAT)
    {
       png_warning(png_ptr, "Invalid cHRM after IDAT");
@@ -527,7 +747,7 @@
       /* Should be an error, but we can cope with it */
       png_warning(png_ptr, "Missing PLTE before cHRM");
 
-   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_cHRM
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
 #if defined(PNG_READ_sRGB_SUPPORTED)
       && !(info_ptr->valid & PNG_INFO_sRGB)
 #endif
@@ -546,15 +766,13 @@
    }
 
    png_crc_read(png_ptr, buf, 4);
-   val = png_get_uint_32(buf);
-   white_x = (float)val / (float)100000.0;
+   int_x_white = (png_fixed_point)png_get_uint_32(buf);
 
    png_crc_read(png_ptr, buf, 4);
-   val = png_get_uint_32(buf);
-   white_y = (float)val / (float)100000.0;
+   int_y_white = (png_fixed_point)png_get_uint_32(buf);
 
-   if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
-       white_x + white_y > 1.0)
+   if (int_x_white > 80000L || int_y_white > 80000L ||
+      int_x_white + int_y_white > 100000L)
    {
       png_warning(png_ptr, "Invalid cHRM white point");
       png_crc_finish(png_ptr, 24);
@@ -562,15 +780,13 @@
    }
 
    png_crc_read(png_ptr, buf, 4);
-   val = png_get_uint_32(buf);
-   red_x = (float)val / (float)100000.0;
+   int_x_red = (png_fixed_point)png_get_uint_32(buf);
 
    png_crc_read(png_ptr, buf, 4);
-   val = png_get_uint_32(buf);
-   red_y = (float)val / (float)100000.0;
+   int_y_red = (png_fixed_point)png_get_uint_32(buf);
 
-   if (red_x < 0 || red_x > 0.8 || red_y < 0 || red_y > 0.8 ||
-       red_x + red_y > 1.0)
+   if (int_x_red > 80000L || int_y_red > 80000L ||
+      int_x_red + int_y_red > 100000L)
    {
       png_warning(png_ptr, "Invalid cHRM red point");
       png_crc_finish(png_ptr, 16);
@@ -578,15 +794,13 @@
    }
 
    png_crc_read(png_ptr, buf, 4);
-   val = png_get_uint_32(buf);
-   green_x = (float)val / (float)100000.0;
+   int_x_green = (png_fixed_point)png_get_uint_32(buf);
 
    png_crc_read(png_ptr, buf, 4);
-   val = png_get_uint_32(buf);
-   green_y = (float)val / (float)100000.0;
+   int_y_green = (png_fixed_point)png_get_uint_32(buf);
 
-   if (green_x < 0 || green_x > 0.8 || green_y < 0 || green_y > 0.8 ||
-       green_x + green_y > 1.0)
+   if (int_x_green > 80000L || int_y_green > 80000L ||
+      int_x_green + int_y_green > 100000L)
    {
       png_warning(png_ptr, "Invalid cHRM green point");
       png_crc_finish(png_ptr, 8);
@@ -594,57 +808,79 @@
    }
 
    png_crc_read(png_ptr, buf, 4);
-   val = png_get_uint_32(buf);
-   blue_x = (float)val / (float)100000.0;
+   int_x_blue = (png_fixed_point)png_get_uint_32(buf);
 
    png_crc_read(png_ptr, buf, 4);
-   val = png_get_uint_32(buf);
-   blue_y = (float)val / (float)100000.0;
+   int_y_blue = (png_fixed_point)png_get_uint_32(buf);
 
-   if (blue_x < (float)0 || blue_x > (float)0.8 || blue_y < (float)0 ||
-       blue_y > (float)0.8 || blue_x + blue_y > (float)1.0)
+   if (int_x_blue > 80000L || int_y_blue > 80000L ||
+      int_x_blue + int_y_blue > 100000L)
    {
       png_warning(png_ptr, "Invalid cHRM blue point");
       png_crc_finish(png_ptr, 0);
       return;
    }
-
-   if (png_crc_finish(png_ptr, 0))
-      return;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   white_x = (float)int_x_white / (float)100000.0;
+   white_y = (float)int_y_white / (float)100000.0;
+   red_x   = (float)int_x_red   / (float)100000.0;
+   red_y   = (float)int_y_red   / (float)100000.0;
+   green_x = (float)int_x_green / (float)100000.0;
+   green_y = (float)int_y_green / (float)100000.0;
+   blue_x  = (float)int_x_blue  / (float)100000.0;
+   blue_y  = (float)int_y_blue  / (float)100000.0;
+#endif
 
 #if defined(PNG_READ_sRGB_SUPPORTED)
    if (info_ptr->valid & PNG_INFO_sRGB)
       {
-      if (fabs(white_x - (float).3127) > (float).001 ||
-          fabs(white_y - (float).3290) > (float).001 ||
-          fabs(  red_x - (float).6400) > (float).001 ||
-          fabs(  red_y - (float).3300) > (float).001 ||
-          fabs(green_x - (float).3000) > (float).001 ||
-          fabs(green_y - (float).6000) > (float).001 ||
-          fabs( blue_x - (float).1500) > (float).001 ||
-          fabs( blue_y - (float).0600) > (float).001)
+      if (abs(int_x_white - 31270L) > 1000 ||
+          abs(int_y_white - 32900L) > 1000 ||
+          abs(  int_x_red - 64000L) > 1000 ||
+          abs(  int_y_red - 33000L) > 1000 ||
+          abs(int_x_green - 30000L) > 1000 ||
+          abs(int_y_green - 60000L) > 1000 ||
+          abs( int_x_blue - 15000L) > 1000 ||
+          abs( int_y_blue -  6000L) > 1000)
          {
 
             png_warning(png_ptr,
               "Ignoring incorrect cHRM value when sRGB is also present");
 #ifndef PNG_NO_CONSOLE_IO
+#ifdef PNG_FLOATING_POINT_SUPPORTED
             fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
                white_x, white_y, red_x, red_y);
             fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
                green_x, green_y, blue_x, blue_y);
+#else
+            fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
+               int_x_white, int_y_white, int_x_red, int_y_red);
+            fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
+               int_x_green, int_y_green, int_x_blue, int_y_blue);
 #endif
+#endif /* PNG_NO_CONSOLE_IO */
          }
+         png_crc_finish(png_ptr, 0);
          return;
       }
 #endif /* PNG_READ_sRGB_SUPPORTED */
 
+#ifdef PNG_FLOATING_POINT_SUPPORTED
    png_set_cHRM(png_ptr, info_ptr,
       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_set_cHRM_fixed(png_ptr, info_ptr,
+      int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
+      int_y_green, int_x_blue, int_y_blue);
+#endif
+   if (png_crc_finish(png_ptr, 0))
+      return;
 }
 #endif
 
 #if defined(PNG_READ_sRGB_SUPPORTED)
-void
+void /* PRIVATE */
 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
    int intent;
@@ -664,7 +900,7 @@
       /* Should be an error, but we can cope with it */
       png_warning(png_ptr, "Out of place sRGB chunk");
 
-   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sRGB)
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
    {
       png_warning(png_ptr, "Duplicate sRGB chunk");
       png_crc_finish(png_ptr, length);
@@ -692,40 +928,304 @@
 
 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
    if ((info_ptr->valid & PNG_INFO_gAMA))
-      if((png_uint_32)(png_ptr->gamma*(float)100000.+.5) != (png_uint_32)45000L)
+   {
+   int igamma;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+      igamma=(int)info_ptr->int_gamma;
+#else
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+      igamma=(int)(info_ptr->gamma * 100000.);
+#  endif
+#endif
+#if 0 && defined(PNG_cHRM_SUPPORTED) && !defined(PNG_FIXED_POINT_SUPPORTED)
+/* We need to define these here because they aren't in png.h */
+   png_fixed_point int_x_white;
+   png_fixed_point int_y_white;
+   png_fixed_point int_x_red;
+   png_fixed_point int_y_red;
+   png_fixed_point int_x_green;
+   png_fixed_point int_y_green;
+   png_fixed_point int_x_blue;
+   png_fixed_point int_y_blue;
+#endif
+      if(igamma < 45000L || igamma > 46000L)
       {
          png_warning(png_ptr,
            "Ignoring incorrect gAMA value when sRGB is also present");
 #ifndef PNG_NO_CONSOLE_IO
-           fprintf(stderr,"gamma=%f\n",png_ptr->gamma);
+#  ifdef PNG_FIXED_POINT_SUPPORTED
+         fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
+#  else
+#    ifdef PNG_FLOATING_POINT_SUPPORTED
+         fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
+#    endif
+#  endif
 #endif
       }
+   }
 #endif /* PNG_READ_gAMA_SUPPORTED */
 
 #ifdef PNG_READ_cHRM_SUPPORTED
+#ifdef PNG_FIXED_POINT_SUPPORTED
    if (info_ptr->valid & PNG_INFO_cHRM)
-      if (fabs(info_ptr->x_white - (float).3127) > (float).001 ||
-          fabs(info_ptr->y_white - (float).3290) > (float).001 ||
-          fabs(  info_ptr->x_red - (float).6400) > (float).001 ||
-          fabs(  info_ptr->y_red - (float).3300) > (float).001 ||
-          fabs(info_ptr->x_green - (float).3000) > (float).001 ||
-          fabs(info_ptr->y_green - (float).6000) > (float).001 ||
-          fabs( info_ptr->x_blue - (float).1500) > (float).001 ||
-          fabs( info_ptr->y_blue - (float).0600) > (float).001)
+      if (abs(info_ptr->int_x_white - 31270L) > 1000 ||
+          abs(info_ptr->int_y_white - 32900L) > 1000 ||
+          abs(  info_ptr->int_x_red - 64000L) > 1000 ||
+          abs(  info_ptr->int_y_red - 33000L) > 1000 ||
+          abs(info_ptr->int_x_green - 30000L) > 1000 ||
+          abs(info_ptr->int_y_green - 60000L) > 1000 ||
+          abs( info_ptr->int_x_blue - 15000L) > 1000 ||
+          abs( info_ptr->int_y_blue -  6000L) > 1000)
          {
             png_warning(png_ptr,
               "Ignoring incorrect cHRM value when sRGB is also present");
          }
+#endif /* PNG_FIXED_POINT_SUPPORTED */
 #endif /* PNG_READ_cHRM_SUPPORTED */
 
    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
 }
 #endif /* PNG_READ_sRGB_SUPPORTED */
 
+#if defined(PNG_READ_iCCP_SUPPORTED)
+void /* PRIVATE */
+png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+   png_charp chunkdata;
+   png_byte compression_type;
+   png_charp profile;
+   png_uint_32 skip = 0;
+   png_uint_32 profile_size = 0;
+   png_uint_32 profile_length = 0;
+   png_size_t slength, prefix_length, data_length;
+
+   png_debug(1, "in png_handle_iCCP\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before iCCP");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid iCCP after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Out of place iCCP chunk");
+
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
+   {
+      png_warning(png_ptr, "Duplicate iCCP chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (length > (png_uint_32)65535L)
+   {
+      png_warning(png_ptr, "iCCP chunk too large to fit in memory");
+      skip = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+
+   if (png_crc_finish(png_ptr, skip))
+   {
+      png_free(png_ptr, chunkdata);
+      return;
+   }
+
+   chunkdata[slength] = 0x00;
+
+   for (profile = chunkdata; *profile; profile++)
+      /* empty loop to find end of name */ ;
+
+   ++profile;
+
+   /* there should be at least one zero (the compression type byte)
+      following the separator, and we should be on it  */
+   if ( profile >= chunkdata + slength)
+   {
+      png_free(png_ptr, chunkdata);
+      png_warning(png_ptr, "Malformed iCCP chunk");
+      return;
+   }
+
+   /* compression_type should always be zero */
+   compression_type = *profile++;
+   if (compression_type)
+   {
+      png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
+      compression_type=0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
+                                 wrote nonzero) */
+   }
+
+   prefix_length = profile - chunkdata;
+   chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
+                                    slength, prefix_length, &data_length);
+
+   profile_length = data_length - prefix_length;
+
+   /* Check the profile_size recorded in the first 32 bits of the ICC profile */
+   profile_size = ((*(chunkdata+prefix_length))<<24) |
+                  ((*(chunkdata+prefix_length+1))<<16) |
+                  ((*(chunkdata+prefix_length+2))<< 8) |
+                  ((*(chunkdata+prefix_length+3))    );
+
+   if(profile_size < profile_length)
+      profile_length = profile_size;
+
+   if(profile_size > profile_length)
+   {
+      png_warning(png_ptr, "Ignoring truncated iCCP profile.\n");
+      return;
+   }
+
+   png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
+                chunkdata + prefix_length, profile_length);
+   png_free(png_ptr, chunkdata);
+}
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#if defined(PNG_READ_sPLT_SUPPORTED)
+void /* PRIVATE */
+png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+   png_bytep chunkdata;
+   png_bytep entry_start;
+   png_sPLT_t new_palette;
+#ifdef PNG_NO_POINTER_INDEXING
+   png_sPLT_entryp pp;
+#endif
+   int data_length, entry_size, i;
+   png_uint_32 skip = 0;
+   png_size_t slength;
+
+   png_debug(1, "in png_handle_sPLT\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sPLT");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid sPLT after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (length > (png_uint_32)65535L)
+   {
+      png_warning(png_ptr, "sPLT chunk too large to fit in memory");
+      skip = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, chunkdata, slength);
+
+   if (png_crc_finish(png_ptr, skip))
+   {
+      png_free(png_ptr, chunkdata);
+      return;
+   }
+
+   chunkdata[slength] = 0x00;
+
+   for (entry_start = chunkdata; *entry_start; entry_start++)
+      /* empty loop to find end of name */ ;
+   ++entry_start;
+
+   /* a sample depth should follow the separator, and we should be on it  */
+   if (entry_start > chunkdata + slength)
+   {
+      png_free(png_ptr, chunkdata);
+      png_warning(png_ptr, "malformed sPLT chunk");
+      return;
+   }
+
+   new_palette.depth = *entry_start++;
+   entry_size = (new_palette.depth == 8 ? 6 : 10);
+   data_length = (slength - (entry_start - chunkdata));
+
+   /* integrity-check the data length */
+   if (data_length % entry_size)
+   {
+      png_free(png_ptr, chunkdata);
+      png_error(png_ptr, "sPLT chunk has bad length");
+   }
+
+   new_palette.nentries = data_length / entry_size;
+   new_palette.entries = (png_sPLT_entryp)png_malloc(
+       png_ptr, new_palette.nentries * sizeof(png_sPLT_entry));
+
+#ifndef PNG_NO_POINTER_INDEXING
+   for (i = 0; i < new_palette.nentries; i++)
+   {
+      png_sPLT_entryp pp = new_palette.entries + i;
+
+      if (new_palette.depth == 8)
+      {
+          pp->red = *entry_start++;
+          pp->green = *entry_start++;
+          pp->blue = *entry_start++;
+          pp->alpha = *entry_start++;
+      }
+      else
+      {
+          pp->red   = png_get_uint_16(entry_start); entry_start += 2;
+          pp->green = png_get_uint_16(entry_start); entry_start += 2;
+          pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
+          pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
+      }
+      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+   }
+#else
+   pp = new_palette.entries;
+   for (i = 0; i < new_palette.nentries; i++)
+   {
+
+      if (new_palette.depth == 8)
+      {
+          pp[i].red   = *entry_start++;
+          pp[i].green = *entry_start++;
+          pp[i].blue  = *entry_start++;
+          pp[i].alpha = *entry_start++;
+      }
+      else
+      {
+          pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
+          pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
+          pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
+          pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
+      }
+      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+   }
+#endif
+
+   /* discard all chunk data except the name and stash that */
+   new_palette.name = (png_charp)chunkdata;
+
+   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
+
+   png_free(png_ptr, chunkdata);
+   png_free(png_ptr, new_palette.entries);
+}
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
 #if defined(PNG_READ_tRNS_SUPPORTED)
-void
+void /* PRIVATE */
 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
+   png_byte	readbuf[PNG_MAX_PALETTE_LENGTH];
+
    png_debug(1, "in png_handle_tRNS\n");
 
    if (!(png_ptr->mode & PNG_HAVE_IHDR))
@@ -736,7 +1236,7 @@
       png_crc_finish(png_ptr, length);
       return;
    }
-   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
    {
       png_warning(png_ptr, "Duplicate tRNS chunk");
       png_crc_finish(png_ptr, length);
@@ -750,7 +1250,7 @@
          /* Should be an error, but we can cope with it */
          png_warning(png_ptr, "Missing PLTE before tRNS");
       }
-      else if (length > png_ptr->num_palette)
+      else if (length > (png_uint_32)png_ptr->num_palette)
       {
          png_warning(png_ptr, "Incorrect tRNS chunk length");
          png_crc_finish(png_ptr, length);
@@ -763,9 +1263,7 @@
          return;
       }
 
-      png_ptr->trans = (png_bytep)png_malloc(png_ptr, length);
-      png_ptr->flags |= PNG_FLAG_FREE_TRANS;
-      png_crc_read(png_ptr, png_ptr->trans, (png_size_t)length);
+      png_crc_read(png_ptr, readbuf, (png_size_t)length);
       png_ptr->num_trans = (png_uint_16)length;
    }
    else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
@@ -810,13 +1308,13 @@
    if (png_crc_finish(png_ptr, 0))
       return;
 
-   png_set_tRNS(png_ptr, info_ptr, png_ptr->trans, png_ptr->num_trans,
+   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
       &(png_ptr->trans_values));
 }
 #endif
 
 #if defined(PNG_READ_bKGD_SUPPORTED)
-void
+void /* PRIVATE */
 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
    png_size_t truelen;
@@ -839,7 +1337,7 @@
       png_crc_finish(png_ptr, length);
       return;
    }
-   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_bKGD)
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
    {
       png_warning(png_ptr, "Duplicate bKGD chunk");
       png_crc_finish(png_ptr, length);
@@ -871,9 +1369,20 @@
    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    {
       png_ptr->background.index = buf[0];
-      png_ptr->background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
-      png_ptr->background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
-      png_ptr->background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
+      if(info_ptr->num_palette)
+      {
+          if(buf[0] > info_ptr->num_palette)
+          {
+             png_warning(png_ptr, "Incorrect bKGD chunk index value");
+             return;
+          }
+          png_ptr->background.red =
+             (png_uint_16)png_ptr->palette[buf[0]].red;
+          png_ptr->background.green =
+             (png_uint_16)png_ptr->palette[buf[0]].green;
+          png_ptr->background.blue =
+             (png_uint_16)png_ptr->palette[buf[0]].blue;
+      }
    }
    else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
    {
@@ -894,10 +1403,11 @@
 #endif
 
 #if defined(PNG_READ_hIST_SUPPORTED)
-void
+void /* PRIVATE */
 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
    int num, i;
+   png_uint_16	readbuf[PNG_MAX_PALETTE_LENGTH];
 
    png_debug(1, "in png_handle_hIST\n");
 
@@ -915,41 +1425,38 @@
       png_crc_finish(png_ptr, length);
       return;
    }
-   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_hIST)
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
    {
       png_warning(png_ptr, "Duplicate hIST chunk");
       png_crc_finish(png_ptr, length);
       return;
    }
 
-   if (length != (png_uint_32)(2 * png_ptr->num_palette))
+   num = (int)length / 2 ;
+   if (num != png_ptr->num_palette)
    {
       png_warning(png_ptr, "Incorrect hIST chunk length");
       png_crc_finish(png_ptr, length);
       return;
    }
 
-   num = (int)length / 2;
-   png_ptr->hist = (png_uint_16p)png_malloc(png_ptr,
-      (png_uint_32)(num * sizeof (png_uint_16)));
-   png_ptr->flags |= PNG_FLAG_FREE_HIST;
    for (i = 0; i < num; i++)
    {
       png_byte buf[2];
 
       png_crc_read(png_ptr, buf, 2);
-      png_ptr->hist[i] = png_get_uint_16(buf);
+      readbuf[i] = png_get_uint_16(buf);
    }
 
    if (png_crc_finish(png_ptr, 0))
       return;
 
-   png_set_hIST(png_ptr, info_ptr, png_ptr->hist);
+   png_set_hIST(png_ptr, info_ptr, readbuf);
 }
 #endif
 
 #if defined(PNG_READ_pHYs_SUPPORTED)
-void
+void /* PRIVATE */
 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
    png_byte buf[9];
@@ -959,16 +1466,16 @@
    png_debug(1, "in png_handle_pHYs\n");
 
    if (!(png_ptr->mode & PNG_HAVE_IHDR))
-      png_error(png_ptr, "Missing IHDR before pHYS");
+      png_error(png_ptr, "Missing IHDR before pHYs");
    else if (png_ptr->mode & PNG_HAVE_IDAT)
    {
-      png_warning(png_ptr, "Invalid pHYS after IDAT");
+      png_warning(png_ptr, "Invalid pHYs after IDAT");
       png_crc_finish(png_ptr, length);
       return;
    }
-   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs)
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
    {
-      png_warning(png_ptr, "Duplicate pHYS chunk");
+      png_warning(png_ptr, "Duplicate pHYs chunk");
       png_crc_finish(png_ptr, length);
       return;
    }
@@ -992,11 +1499,11 @@
 #endif
 
 #if defined(PNG_READ_oFFs_SUPPORTED)
-void
+void /* PRIVATE */
 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
    png_byte buf[9];
-   png_uint_32 offset_x, offset_y;
+   png_int_32 offset_x, offset_y;
    int unit_type;
 
    png_debug(1, "in png_handle_oFFs\n");
@@ -1009,7 +1516,7 @@
       png_crc_finish(png_ptr, length);
       return;
    }
-   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_oFFs)
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
    {
       png_warning(png_ptr, "Duplicate oFFs chunk");
       png_crc_finish(png_ptr, length);
@@ -1027,16 +1534,16 @@
    if (png_crc_finish(png_ptr, 0))
       return;
 
-   offset_x = png_get_uint_32(buf);
-   offset_y = png_get_uint_32(buf + 4);
+   offset_x = png_get_int_32(buf);
+   offset_y = png_get_int_32(buf + 4);
    unit_type = buf[8];
    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
 }
 #endif
 
 #if defined(PNG_READ_pCAL_SUPPORTED)
-/* read the pCAL chunk (png-scivis-19970203) */
-void
+/* read the pCAL chunk (described in the PNG Extensions document) */
+void /* PRIVATE */
 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
    png_charp purpose;
@@ -1057,14 +1564,14 @@
       png_crc_finish(png_ptr, length);
       return;
    }
-   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_pCAL)
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
    {
       png_warning(png_ptr, "Duplicate pCAL chunk");
       png_crc_finish(png_ptr, length);
       return;
    }
 
-   png_debug1(2, "Allocating and reading pCAL chunk data (%d bytes)\n",
+   png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
       length + 1);
    purpose = (png_charp)png_malloc(png_ptr, length + 1);
    slength = (png_size_t)length;
@@ -1151,8 +1658,121 @@
 }
 #endif
 
+#if defined(PNG_READ_sCAL_SUPPORTED)
+/* read the sCAL chunk */
+void /* PRIVATE */
+png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_charp buffer, ep;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   double width, height;
+   png_charp vp;
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_charp swidth, sheight;
+#endif
+#endif
+   png_size_t slength;
+
+   png_debug(1, "in png_handle_sCAL\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sCAL");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid sCAL after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
+   {
+      png_warning(png_ptr, "Duplicate sCAL chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
+      length + 1);
+   buffer = (png_charp)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)buffer, slength);
+
+   if (png_crc_finish(png_ptr, 0))
+   {
+      png_free(png_ptr, buffer);
+      return;
+   }
+
+   buffer[slength] = 0x00; /* null terminate the last string */
+
+   ep = buffer + 1;        /* skip unit byte */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   width = strtod(ep, &vp);
+   if (*vp)
+   {
+       png_warning(png_ptr, "malformed width string in sCAL chunk");
+       return;
+   }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   swidth = (png_charp)png_malloc(png_ptr, strlen(ep) + 1);
+   png_memcpy(swidth, ep, (png_size_t)strlen(ep));
+#endif
+#endif
+
+   for (ep = buffer; *ep; ep++)
+      /* empty loop */ ;
+   ep++;
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   height = strtod(ep, &vp);
+   if (*vp)
+   {
+       png_warning(png_ptr, "malformed height string in sCAL chunk");
+       return;
+   }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   sheight = (png_charp)png_malloc(png_ptr, strlen(ep) + 1);
+   png_memcpy(sheight, ep, (png_size_t)strlen(ep));
+#endif
+#endif
+
+   if (buffer + slength < ep
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+      || width <= 0. || height <= 0.
+#endif
+      )
+   {
+      png_warning(png_ptr, "Invalid sCAL data");
+      png_free(png_ptr, buffer);
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+      png_free(png_ptr, swidth);
+      png_free(png_ptr, sheight);
+#endif
+      return;
+   }
+
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
+#endif
+#endif
+
+   png_free(png_ptr, buffer);
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+   png_free(png_ptr, swidth);
+   png_free(png_ptr, sheight);
+#endif
+}
+#endif
+
 #if defined(PNG_READ_tIME_SUPPORTED)
-void
+void /* PRIVATE */
 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
    png_byte buf[7];
@@ -1162,7 +1782,7 @@
 
    if (!(png_ptr->mode & PNG_HAVE_IHDR))
       png_error(png_ptr, "Out of place tIME chunk");
-   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tIME)
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
    {
       png_warning(png_ptr, "Duplicate tIME chunk");
       png_crc_finish(png_ptr, length);
@@ -1196,7 +1816,7 @@
 
 #if defined(PNG_READ_tEXt_SUPPORTED)
 /* Note: this does not properly handle chunks that are > 64K under DOS */
-void
+void /* PRIVATE */
 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
    png_textp text_ptr;
@@ -1243,28 +1863,33 @@
    text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
    text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
    text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+   text_ptr->lang = NULL;
+   text_ptr->lang_key = NULL;
+   text_ptr->itxt_length = 0;
+#endif
    text_ptr->text = text;
+   text_ptr->text_length = png_strlen(text);
 
    png_set_text(png_ptr, info_ptr, text_ptr, 1);
 
+   png_free(png_ptr, key);
    png_free(png_ptr, text_ptr);
 }
 #endif
 
 #if defined(PNG_READ_zTXt_SUPPORTED)
 /* note: this does not correctly handle chunks that are > 64K under DOS */
-void
+void /* PRIVATE */
 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
-   static char msg[] = "Error decoding zTXt chunk";
    png_textp text_ptr;
-   png_charp key;
+   png_charp chunkdata;
    png_charp text;
-   int comp_type = PNG_TEXT_COMPRESSION_NONE;
-   png_size_t slength;
+   int comp_type;
+   png_size_t slength, prefix_len, data_len;
 
    png_debug(1, "in png_handle_zTXt\n");
-
    if (!(png_ptr->mode & PNG_HAVE_IHDR))
       png_error(png_ptr, "Missing IHDR before zTXt");
 
@@ -1282,172 +1907,233 @@
    }
 #endif
 
-   key = (png_charp)png_malloc(png_ptr, length + 1);
+   chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
    slength = (png_size_t)length;
-   png_crc_read(png_ptr, (png_bytep)key, slength);
+   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
    if (png_crc_finish(png_ptr, 0))
    {
-      png_free(png_ptr, key);
+      png_free(png_ptr, chunkdata);
       return;
    }
 
-   key[slength] = 0x00;
+   chunkdata[slength] = 0x00;
 
-   for (text = key; *text; text++)
+   for (text = chunkdata; *text; text++)
       /* empty loop */ ;
 
-   /* zTXt must have some text after the keyword */
-   if (text == key + slength)
+   /* zTXt must have some text after the chunkdataword */
+   if (text == chunkdata + slength)
    {
+      comp_type = PNG_TEXT_COMPRESSION_NONE;
       png_warning(png_ptr, "Zero length zTXt chunk");
    }
-   else if ((comp_type = *(++text)) == PNG_TEXT_COMPRESSION_zTXt)
+   else
    {
-      png_size_t text_size, key_size;
-      text++;
+       comp_type = *(++text);
+       if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
+       {
+          png_warning(png_ptr, "Unknown compression type in zTXt chunk");
+          comp_type = PNG_TEXT_COMPRESSION_zTXt;
+       }
+       text++;        /* skip the compression_method byte */
+   }
+   prefix_len = text - chunkdata;
 
-      png_ptr->zstream.next_in = (png_bytep)text;
-      png_ptr->zstream.avail_in = (uInt)(length - (text - key));
-      png_ptr->zstream.next_out = png_ptr->zbuf;
-      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+   chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
+                                    (png_size_t)length, prefix_len, &data_len);
 
-      key_size = (png_size_t)(text - key);
-      text_size = 0;
-      text = NULL;
+   text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
+   text_ptr->compression = comp_type;
+   text_ptr->key = chunkdata;
+#ifdef PNG_iTXt_SUPPORTED
+   text_ptr->lang = NULL;
+   text_ptr->lang_key = NULL;
+   text_ptr->itxt_length = 0;
+#endif
+   text_ptr->text = chunkdata + prefix_len;
+   text_ptr->text_length = data_len;
 
-      while (png_ptr->zstream.avail_in)
-      {
-         int ret;
+   png_set_text(png_ptr, info_ptr, text_ptr, 1);
 
-         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
-         if (ret != Z_OK && ret != Z_STREAM_END)
-         {
-            if (png_ptr->zstream.msg != NULL)
-               png_warning(png_ptr, png_ptr->zstream.msg);
-            else
-               png_warning(png_ptr, msg);
-            inflateReset(&png_ptr->zstream);
-            png_ptr->zstream.avail_in = 0;
+   png_free(png_ptr, text_ptr);
+   png_free(png_ptr, chunkdata);
+}
+#endif
 
-            if (text ==  NULL)
-            {
-               text_size = key_size + sizeof(msg) + 1;
-               text = (png_charp)png_malloc(png_ptr, (png_uint_32)text_size);
-               png_memcpy(text, key, key_size);
-            }
+#if defined(PNG_READ_iTXt_SUPPORTED)
+/* note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_textp text_ptr;
+   png_charp chunkdata;
+   png_charp key, lang, text, lang_key;
+   int comp_flag;
+   int comp_type = 0;
+   png_size_t slength, prefix_len, data_len;
 
-            text[text_size - 1] = 0x00;
+   png_debug(1, "in png_handle_iTXt\n");
 
-            /* Copy what we can of the error message into the text chunk */
-            text_size = (png_size_t)(slength - (text - key) - 1);
-            text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
-            png_memcpy(text + key_size, msg, text_size + 1);
-            break;
-         }
-         if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
-         {
-            if (text == NULL)
-            {
-               text = (png_charp)png_malloc(png_ptr,
-                  (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
-                     + key_size + 1));
-               png_memcpy(text + key_size, png_ptr->zbuf,
-                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
-               png_memcpy(text, key, key_size);
-               text_size = key_size + png_ptr->zbuf_size -
-                  png_ptr->zstream.avail_out;
-               *(text + text_size) = 0x00;
-            }
-            else
-            {
-               png_charp tmp;
-
-               tmp = text;
-               text = (png_charp)png_malloc(png_ptr, (png_uint_32)(text_size +
-                  png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
-               png_memcpy(text, tmp, text_size);
-               png_free(png_ptr, tmp);
-               png_memcpy(text + text_size, png_ptr->zbuf,
-                  (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
-               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
-               *(text + text_size) = 0x00;
-            }
-            if (ret != Z_STREAM_END)
-            {
-               png_ptr->zstream.next_out = png_ptr->zbuf;
-               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-            }
-            else
-            {
-               break;
-            }
-         }
-      }
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before iTXt");
 
-      inflateReset(&png_ptr->zstream);
-      png_ptr->zstream.avail_in = 0;
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+      png_ptr->mode |= PNG_AFTER_IDAT;
 
-      png_free(png_ptr, key);
-      key = text;
-      text += key_size;
+#ifdef PNG_MAX_MALLOC_64K
+   /* We will no doubt have problems with chunks even half this size, but
+      there is no hard and fast rule to tell us where to stop. */
+   if (length > (png_uint_32)65535L)
+   {
+     png_warning(png_ptr,"iTXt chunk too large to fit in memory");
+     png_crc_finish(png_ptr, length);
+     return;
    }
-   else /* if (comp_type >= PNG_TEXT_COMPRESSION_LAST) */
+#endif
+
+   chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+   if (png_crc_finish(png_ptr, 0))
    {
-      png_size_t text_size;
-#if !defined(PNG_NO_STDIO)
-      char umsg[50];
+      png_free(png_ptr, chunkdata);
+      return;
+   }
 
-      sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
-      png_warning(png_ptr, umsg);
-#else
-      png_warning(png_ptr, "Unknown zTXt compression type");
-#endif
+   chunkdata[slength] = 0x00;
+
+   for (lang = chunkdata; *lang; lang++)
+      /* empty loop */ ;
+   lang++;        /* skip NUL separator */
 
-      /* Copy what we can of the error message into the text chunk */
-      text_size = (png_size_t)(slength - (text - key) - 1);
-      text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
-      png_memcpy(text, msg, text_size + 1);
+   /* iTXt must have a language tag (possibly empty), two compression bytes,
+      translated keyword (possibly empty), and possibly some text after the
+      keyword */
+
+   if (lang >= chunkdata + slength)
+   {
+      comp_flag = PNG_TEXT_COMPRESSION_NONE;
+      png_warning(png_ptr, "Zero length iTXt chunk");
    }
+   else
+   {
+       comp_flag = *lang++;
+       comp_type = *lang++;
+   }
+
+   for (lang_key = lang; *lang_key; lang_key++)
+      /* empty loop */ ;
+   lang_key++;        /* skip NUL separator */
 
+   for (text = lang_key; *text; text++)
+      /* empty loop */ ;
+   text++;        /* skip NUL separator */
+
+   prefix_len = text - chunkdata;
+
+   key=chunkdata;
+   if (comp_flag)
+       chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
+          (size_t)length, prefix_len, &data_len);
+   else
+       data_len=png_strlen(chunkdata + prefix_len);
    text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
-   text_ptr->compression = comp_type;
-   text_ptr->key = key;
-   text_ptr->text = text;
+   text_ptr->compression = (int)comp_flag + 1;
+   text_ptr->lang_key = chunkdata+(lang_key-key);
+   text_ptr->lang = chunkdata+(lang-key);
+   text_ptr->itxt_length = data_len;
+   text_ptr->text_length = 0;
+   text_ptr->key = chunkdata;
+   text_ptr->text = chunkdata + prefix_len;
 
    png_set_text(png_ptr, info_ptr, text_ptr, 1);
 
    png_free(png_ptr, text_ptr);
+   png_free(png_ptr, chunkdata);
 }
 #endif
 
 /* This function is called when we haven't found a handler for a
    chunk.  If there isn't a problem with the chunk itself (ie bad
-   chunk name, CRC, or a critical chunk), the chunk is silently ignored. */
-void
+   chunk name, CRC, or a critical chunk), the chunk is silently ignored
+   -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
+   case it will be saved away to be written out later. */
+void /* PRIVATE */
 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
+   png_uint_32 skip = 0;
+
    png_debug(1, "in png_handle_unknown\n");
 
-   /* In the future we can have code here that calls user-supplied
-    * callback functions for unknown chunks before they are ignored or
-    * cause an error.
-    */
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IDAT;
+#endif
+      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* not an IDAT */
+         png_ptr->mode |= PNG_AFTER_IDAT;
+   }
+
    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
 
    if (!(png_ptr->chunk_name[0] & 0x20))
    {
-      png_chunk_error(png_ptr, "unknown critical chunk");
-
-      /* to quiet compiler warnings about unused info_ptr */
-      if (info_ptr == NULL)
-         return;
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+      if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+           HANDLE_CHUNK_ALWAYS
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+           && png_ptr->read_user_chunk_fn == (png_user_chunk_ptr)NULL
+#endif
+        )
+#endif
+          png_chunk_error(png_ptr, "unknown critical chunk");
    }
 
-   if (png_ptr->mode & PNG_HAVE_IDAT)
-      png_ptr->mode |= PNG_AFTER_IDAT;
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+   if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
+   {
+       png_unknown_chunk chunk;
 
-   png_crc_finish(png_ptr, length);
+#ifdef PNG_MAX_MALLOC_64K
+       if (length > (png_uint_32)65535L)
+       {
+           png_warning(png_ptr, "unknown chunk too large to fit in memory");
+           skip = length - (png_uint_32)65535L;
+           length = (png_uint_32)65535L;
+       }
+#endif
+       strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
+       chunk.data = (png_bytep)png_malloc(png_ptr, length);
+       png_crc_read(png_ptr, chunk.data, length);
+       chunk.size = length;
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+       if(png_ptr->read_user_chunk_fn != (png_user_chunk_ptr)NULL)
+       {
+          /* callback to user unknown chunk handler */
+          if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
+          {
+             if (!(png_ptr->chunk_name[0] & 0x20))
+                if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+                     HANDLE_CHUNK_ALWAYS)
+                   png_chunk_error(png_ptr, "unknown critical chunk");
+             png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
+          }
+       }
+       else
+#endif
+          png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
+       png_free(png_ptr, chunk.data);
+   }
+   else
+#endif
+      skip = length;
+
+   png_crc_finish(png_ptr, skip);
 
+#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+   if (info_ptr == NULL)
+     /* quiet compiler warnings about unused info_ptr */ ;
+#endif
 }
 
 /* This function is called to verify that a chunk name is valid.
@@ -1458,7 +2144,7 @@
 
 #define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
 
-void
+void /* PRIVATE */
 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
 {
    png_debug(1, "in png_check_chunk_name\n");
@@ -1479,9 +2165,9 @@
    a zero indicates the pixel is to be skipped.  This is in addition
    to any alpha or transparency value associated with the pixel.  If
    you want all pixels to be combined, pass 0xff (255) in mask.  */
-void
-png_combine_row(png_structp png_ptr, png_bytep row,
-   int mask)
+#ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+void /* PRIVATE */
+png_combine_row(png_structp png_ptr, png_bytep row, int mask)
 {
    png_debug(1,"in png_combine_row\n");
    if (mask == 0xff)
@@ -1527,7 +2213,7 @@
                {
                   int value;
 
-                  value = (*sp >> shift) & 0x1;
+                  value = (*sp >> shift) & 0x01;
                   *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
                   *dp |= (png_byte)(value << shift);
                }
@@ -1580,7 +2266,7 @@
             {
                if (m & mask)
                {
-                  value = (*sp >> shift) & 0x3;
+                  value = (*sp >> shift) & 0x03;
                   *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
                   *dp |= (png_byte)(value << shift);
                }
@@ -1681,13 +2367,24 @@
       }
    }
 }
+#endif /* !PNG_HAVE_ASSEMBLER_COMBINE_ROW */
 
-#if defined(PNG_READ_INTERLACING_SUPPORTED)
-void
-png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
-   png_uint_32 transformations)
-{
-   png_debug(1,"in png_do_read_interlace\n");
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+#ifndef PNG_HAVE_ASSEMBLER_READ_INTERLACE   /* else in pngvcrd.c, pnggccrd.c */
+void /* PRIVATE */
+png_do_read_interlace(png_structp png_ptr)
+{
+   png_row_infop row_info = &(png_ptr->row_info);
+   png_bytep row = png_ptr->row_buf + 1;
+   int pass = png_ptr->pass;
+   png_uint_32 transformations = png_ptr->transformations;
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+   /* offset to next interlace block */
+   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+#endif
+
+   png_debug(1,"in png_do_read_interlace (stock C version)\n");
    if (row != NULL && row_info != NULL)
    {
       png_uint_32 final_width;
@@ -1710,8 +2407,8 @@
 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
             if (transformations & PNG_PACKSWAP)
             {
-                sshift = (int)((row_info->width + 7) & 7);
-                dshift = (int)((final_width + 7) & 7);
+                sshift = (int)((row_info->width + 7) & 0x07);
+                dshift = (int)((final_width + 7) & 0x07);
                 s_start = 7;
                 s_end = 0;
                 s_inc = -1;
@@ -1719,8 +2416,8 @@
             else
 #endif
             {
-                sshift = 7 - (int)((row_info->width + 7) & 7);
-                dshift = 7 - (int)((final_width + 7) & 7);
+                sshift = 7 - (int)((row_info->width + 7) & 0x07);
+                dshift = 7 - (int)((final_width + 7) & 0x07);
                 s_start = 0;
                 s_end = 7;
                 s_inc = 1;
@@ -1728,7 +2425,7 @@
 
             for (i = 0; i < row_info->width; i++)
             {
-               v = (png_byte)((*sp >> sshift) & 0x1);
+               v = (png_byte)((*sp >> sshift) & 0x01);
                for (j = 0; j < jstop; j++)
                {
                   *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
@@ -1763,8 +2460,8 @@
 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
             if (transformations & PNG_PACKSWAP)
             {
-               sshift = (int)(((row_info->width + 3) & 3) << 1);
-               dshift = (int)(((final_width + 3) & 3) << 1);
+               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
+               dshift = (int)(((final_width + 3) & 0x03) << 1);
                s_start = 6;
                s_end = 0;
                s_inc = -2;
@@ -1772,8 +2469,8 @@
             else
 #endif
             {
-               sshift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
-               dshift = (int)((3 - ((final_width + 3) & 3)) << 1);
+               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
+               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
                s_start = 0;
                s_end = 6;
                s_inc = 2;
@@ -1784,7 +2481,7 @@
                png_byte v;
                int j;
 
-               v = (png_byte)((*sp >> sshift) & 0x3);
+               v = (png_byte)((*sp >> sshift) & 0x03);
                for (j = 0; j < jstop; j++)
                {
                   *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
@@ -1819,8 +2516,8 @@
 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
             if (transformations & PNG_PACKSWAP)
             {
-               sshift = (int)(((row_info->width + 1) & 1) << 2);
-               dshift = (int)(((final_width + 1) & 1) << 2);
+               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
+               dshift = (int)(((final_width + 1) & 0x01) << 2);
                s_start = 4;
                s_end = 0;
                s_inc = -4;
@@ -1828,8 +2525,8 @@
             else
 #endif
             {
-               sshift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
-               dshift = (int)((1 - ((final_width + 1) & 1)) << 2);
+               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
+               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
                s_start = 0;
                s_end = 4;
                s_inc = 4;
@@ -1867,6 +2564,7 @@
             png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
             png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
             png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
+
             int jstop = png_pass_inc[pass];
             png_uint_32 i;
 
@@ -1890,17 +2588,22 @@
       row_info->rowbytes = ((final_width *
          (png_uint_32)row_info->pixel_depth + 7) >> 3);
    }
-}
+#if !defined(PNG_READ_PACKSWAP_SUPPORTED)
+   /* silence compiler warning */
+   if (transformations)
+      return;
 #endif
+}
+#endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
 
-void
+#ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+void /* PRIVATE */
 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
    png_bytep prev_row, int filter)
 {
    png_debug(1, "in png_read_filter_row\n");
-   png_debug2(2,"row = %d, filter = %d\n", png_ptr->row_number, filter);
-
-
+   png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
    switch (filter)
    {
       case PNG_FILTER_VALUE_NONE:
@@ -1909,7 +2612,7 @@
       {
          png_uint_32 i;
          png_uint_32 istop = row_info->rowbytes;
-         png_uint_32 bpp = (row_info->pixel_depth + 7) / 8;
+         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
          png_bytep rp = row + bpp;
          png_bytep lp = row;
 
@@ -1940,20 +2643,20 @@
          png_bytep rp = row;
          png_bytep pp = prev_row;
          png_bytep lp = row;
-         png_uint_32 bpp = (row_info->pixel_depth + 7) / 8;
+         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
          png_uint_32 istop = row_info->rowbytes - bpp;
 
          for (i = 0; i < bpp; i++)
          {
             *rp = (png_byte)(((int)(*rp) +
-               ((int)(*pp++) / 2)) & 0xff);
+               ((int)(*pp++) / 2 )) & 0xff);
             rp++;
          }
 
          for (i = 0; i < istop; i++)
          {
             *rp = (png_byte)(((int)(*rp) +
-               (int)(*pp++ + *lp++) / 2) & 0xff);
+               (int)(*pp++ + *lp++) / 2 ) & 0xff);
             rp++;
          }
          break;
@@ -1965,7 +2668,7 @@
          png_bytep pp = prev_row;
          png_bytep lp = row;
          png_bytep cp = prev_row;
-         png_uint_32 bpp = (row_info->pixel_depth + 7) / 8;
+         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
          png_uint_32 istop=row_info->rowbytes - bpp;
 
          for (i = 0; i < bpp; i++)
@@ -2017,10 +2720,27 @@
          break;
    }
 }
+#endif /* !PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */
 
-void
+void /* PRIVATE */
 png_read_finish_row(png_structp png_ptr)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* start of interlace block */
+   const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* offset to next interlace block */
+   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* start of interlace block in the y direction */
+   const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* offset to next interlace block in the y direction */
+   const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
    png_debug(1, "in png_read_finish_row\n");
    png_ptr->row_number++;
    if (png_ptr->row_number < png_ptr->num_rows)
@@ -2061,6 +2781,9 @@
 
    if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
    {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IDAT;
+#endif
       char extra;
       int ret;
 
@@ -2081,7 +2804,7 @@
 
                png_reset_crc(png_ptr);
                png_crc_read(png_ptr, png_ptr->chunk_name, 4);
-               if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+               if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
                   png_error(png_ptr, "Not enough image data");
 
             }
@@ -2121,9 +2844,25 @@
    png_ptr->mode |= PNG_AFTER_IDAT;
 }
 
-void
+void /* PRIVATE */
 png_read_start_row(png_structp png_ptr)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* start of interlace block */
+   const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* offset to next interlace block */
+   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* start of interlace block in the y direction */
+   const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* offset to next interlace block in the y direction */
+   const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
    int max_pixel_depth;
    png_uint_32 row_bytes;
 
@@ -2232,13 +2971,31 @@
       else
       {
          if (max_pixel_depth <= 8)
-            max_pixel_depth = 24;
+           {
+             if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+               max_pixel_depth = 32;
+             else
+               max_pixel_depth = 24;
+           }
+         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            max_pixel_depth = 64;
          else
             max_pixel_depth = 48;
       }
    }
 #endif
 
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
+defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+   if(png_ptr->transformations & PNG_USER_TRANSFORM)
+     {
+       int user_pixel_depth=png_ptr->user_transform_depth*
+         png_ptr->user_transform_channels;
+       if(user_pixel_depth > max_pixel_depth)
+         max_pixel_depth=user_pixel_depth;
+     }
+#endif
+
    /* align the width on the next larger 8 pixels.  Mainly used
       for interlacing */
    row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
@@ -2261,12 +3018,12 @@
 
    png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
 
-   png_debug1(3, "width = %d,\n", png_ptr->width);
-   png_debug1(3, "height = %d,\n", png_ptr->height);
-   png_debug1(3, "iwidth = %d,\n", png_ptr->iwidth);
-   png_debug1(3, "num_rows = %d\n", png_ptr->num_rows);
-   png_debug1(3, "rowbytes = %d,\n", png_ptr->rowbytes);
-   png_debug1(3, "irowbytes = %d,\n", png_ptr->irowbytes);
+   png_debug1(3, "width = %lu,\n", png_ptr->width);
+   png_debug1(3, "height = %lu,\n", png_ptr->height);
+   png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
+   png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
+   png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
+   png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
 
    png_ptr->flags |= PNG_FLAG_ROW_INIT;
 }

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/png.5
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/png.5	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/png.5	Sat Jul 13 21:26:53 2002
@@ -1,4 +1,4 @@
-.TH PNG 5 "January 14, 1999"
+.TH PNG 5 "January 31, 2001"
 .SH NAME
 png \- Portable Network Graphics (PNG) format
 .SH DESCRIPTION
@@ -20,7 +20,16 @@
 .SH "SEE ALSO"
 .IR libpng(3), zlib(3), deflate(5), and zlib(5)
 .LP
-PNG specification:
+PNG 1.2 specification, July 1999:
+.IP
+.br
+http://www.libpng.org/pub/png
+.br
+or ftp://ftp.uu.net/graphics/png/documents
+.LP
+PNG 1.0 specification, October 1996:
+.IP
+.br
 RFC 2083
 .IP
 .br
@@ -32,12 +41,19 @@
 .SH AUTHORS
 This man page: Glenn Randers-Pehrson
 .LP
+Portable Network Graphics (PNG) Specification Version 1.2 (July 8, 1999):
+Glenn Randers-Pehrson and others (png-list at ccrc.wustl.edu).
+.LP
 Portable Network Graphics (PNG) Specification Version 1.0 (October 1, 1996):
-Thomas Boutell and others (png-list at dworkin.wustl.edu).
+Thomas Boutell and others (png-list at ccrc.wustl.edu).
 .LP
 
+
 .SH COPYRIGHT NOTICE
-The PNG specification is copyright (c) 1996 Massachussets Institute of
+The PNG-1.2 specification is copyright (c) 1999 Glenn Randers-Pehrson.
+See the specification for conditions of use and distribution.
+.LP
+The PNG-1.0 specification is copyright (c) 1996 Massachussets Institute of
 Technology.  See the specification for conditions of use and distribution.
 .LP
 .\" end of man page

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwutil.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwutil.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngwutil.c	Sat Jul 13 21:26:53 2002
@@ -1,11 +1,11 @@
 
 /* pngwutil.c - utilities to write a PNG file
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  */
 
 #define PNG_INTERNAL
@@ -15,7 +15,7 @@
  * with unsigned numbers for convenience, although one supported
  * ancillary chunk uses signed (two's complement) numbers.
  */
-void
+void /* PRIVATE */
 png_save_uint_32(png_bytep buf, png_uint_32 i)
 {
    buf[0] = (png_byte)((i >> 24) & 0xff);
@@ -29,7 +29,7 @@
  * complement format.  If this isn't the case, then this routine needs to
  * be modified to write data in two's complement format.
  */
-void
+void /* PRIVATE */
 png_save_int_32(png_bytep buf, png_int_32 i)
 {
    buf[0] = (png_byte)((i >> 24) & 0xff);
@@ -43,7 +43,7 @@
  * The parameter is declared unsigned int, not png_uint_16,
  * just to avoid potential problems on pre-ANSI C compilers.
  */
-void
+void /* PRIVATE */
 png_save_uint_16(png_bytep buf, unsigned int i)
 {
    buf[0] = (png_byte)((i >> 8) & 0xff);
@@ -59,7 +59,7 @@
  * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
  * functions instead.
  */
-void
+void PNGAPI
 png_write_chunk(png_structp png_ptr, png_bytep chunk_name,
    png_bytep data, png_size_t length)
 {
@@ -72,12 +72,12 @@
  * The total_length is the sum of the lengths of all the data you will be
  * passing in png_write_chunk_data().
  */
-void
+void PNGAPI
 png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
    png_uint_32 length)
 {
    png_byte buf[4];
-   png_debug2(0, "Writing %s chunk (%d bytes)\n", chunk_name, length);
+   png_debug2(0, "Writing %s chunk (%lu bytes)\n", chunk_name, length);
 
    /* write the length */
    png_save_uint_32(buf, length);
@@ -95,7 +95,7 @@
  * sum of the lengths from these calls *must* add up to the total_length
  * given to png_write_chunk_start().
  */
-void
+void PNGAPI
 png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length)
 {
    /* write the data, and run the CRC over it */
@@ -107,7 +107,7 @@
 }
 
 /* Finish a chunk started with png_write_chunk_start(). */
-void
+void PNGAPI
 png_write_chunk_end(png_structp png_ptr)
 {
    png_byte buf[4];
@@ -124,23 +124,251 @@
  * we should call png_set_sig_bytes() to tell libpng how many of the
  * bytes have already been written.
  */
-void
+void /* PRIVATE */
 png_write_sig(png_structp png_ptr)
 {
+   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
    /* write the rest of the 8 byte signature */
-   png_write_data(png_ptr, &png_sig[png_ptr->sig_bytes],
+   png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
       (png_size_t)8 - png_ptr->sig_bytes);
+   if(png_ptr->sig_bytes < 3)
+      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
 }
 
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED)
+/*
+ * This pair of functions encapsulates the operation of (a) compressing a
+ * text string, and (b) issuing it later as a series of chunk data writes.
+ * The compression_state structure is shared context for these functions
+ * set up by the caller in order to make the whole mess thread-safe.
+ */
+
+typedef struct
+{
+    char *input;   /* the uncompressed input data */
+    int input_len;   /* its length */
+    int num_output_ptr; /* number of output pointers used */
+    int max_output_ptr; /* size of output_ptr */
+    png_charpp output_ptr; /* array of pointers to output */
+} compression_state;
+
+/* compress given text into storage in the png_ptr structure */
+static int /* PRIVATE */
+png_text_compress(png_structp png_ptr,
+        png_charp text, png_size_t text_len, int compression,
+        compression_state *comp)
+{
+   int ret;
+
+   comp->num_output_ptr = comp->max_output_ptr = 0;
+   comp->output_ptr = NULL;
+   comp->input = NULL;
+
+   /* we may just want to pass the text right through */
+   if (compression == PNG_TEXT_COMPRESSION_NONE)
+   {
+       comp->input = text;
+       comp->input_len = text_len;
+       return((int)text_len);
+   }
+
+   if (compression >= PNG_TEXT_COMPRESSION_LAST)
+   {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+      char msg[50];
+      sprintf(msg, "Unknown compression type %d", compression);
+      png_warning(png_ptr, msg);
+#else
+      png_warning(png_ptr, "Unknown compression type");
+#endif
+   }
+
+   /* We can't write the chunk until we find out how much data we have,
+    * which means we need to run the compressor first and save the
+    * output.  This shouldn't be a problem, as the vast majority of
+    * comments should be reasonable, but we will set up an array of
+    * malloc'd pointers to be sure.
+    *
+    * If we knew the application was well behaved, we could simplify this
+    * greatly by assuming we can always malloc an output buffer large
+    * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
+    * and malloc this directly.  The only time this would be a bad idea is
+    * if we can't malloc more than 64K and we have 64K of random input
+    * data, or if the input string is incredibly large (although this
+    * wouldn't cause a failure, just a slowdown due to swapping).
+    */
+
+   /* set up the compression buffers */
+   png_ptr->zstream.avail_in = (uInt)text_len;
+   png_ptr->zstream.next_in = (Bytef *)text;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+   png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
+
+   /* this is the same compression loop as in png_write_row() */
+   do
+   {
+      /* compress the data */
+      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
+      if (ret != Z_OK)
+      {
+         /* error */
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+      /* check to see if we need more room */
+      if (!png_ptr->zstream.avail_out && png_ptr->zstream.avail_in)
+      {
+         /* make sure the output array has room */
+         if (comp->num_output_ptr >= comp->max_output_ptr)
+         {
+            int old_max;
+
+            old_max = comp->max_output_ptr;
+            comp->max_output_ptr = comp->num_output_ptr + 4;
+            if (comp->output_ptr != NULL)
+            {
+               png_charpp old_ptr;
+
+               old_ptr = comp->output_ptr;
+               comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                  (png_uint_32)(comp->max_output_ptr * sizeof (png_charpp)));
+               png_memcpy(comp->output_ptr, old_ptr,
+           old_max * sizeof (png_charp));
+               png_free(png_ptr, old_ptr);
+            }
+            else
+               comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                  (png_uint_32)(comp->max_output_ptr * sizeof (png_charp)));
+         }
+
+         /* save the data */
+         comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr,
+            (png_uint_32)png_ptr->zbuf_size);
+         png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
+            png_ptr->zbuf_size);
+         comp->num_output_ptr++;
+
+         /* and reset the buffer */
+         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+         png_ptr->zstream.next_out = png_ptr->zbuf;
+      }
+   /* continue until we don't have any more to compress */
+   } while (png_ptr->zstream.avail_in);
+
+   /* finish the compression */
+   do
+   {
+      /* tell zlib we are finished */
+      ret = deflate(&png_ptr->zstream, Z_FINISH);
+
+      if (ret == Z_OK)
+      {
+         /* check to see if we need more room */
+         if (!(png_ptr->zstream.avail_out))
+         {
+            /* check to make sure our output array has room */
+            if (comp->num_output_ptr >= comp->max_output_ptr)
+            {
+               int old_max;
+
+               old_max = comp->max_output_ptr;
+               comp->max_output_ptr = comp->num_output_ptr + 4;
+               if (comp->output_ptr != NULL)
+               {
+                  png_charpp old_ptr;
+
+                  old_ptr = comp->output_ptr;
+                  /* This could be optimized to realloc() */
+                  comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                     (png_uint_32)(comp->max_output_ptr * sizeof (png_charpp)));
+                  png_memcpy(comp->output_ptr, old_ptr,
+              old_max * sizeof (png_charp));
+                  png_free(png_ptr, old_ptr);
+               }
+               else
+                  comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                     (png_uint_32)(comp->max_output_ptr * sizeof (png_charp)));
+            }
+
+            /* save off the data */
+            comp->output_ptr[comp->num_output_ptr] =
+               (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size);
+            png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
+               png_ptr->zbuf_size);
+            comp->num_output_ptr++;
+
+            /* and reset the buffer pointers */
+            png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+            png_ptr->zstream.next_out = png_ptr->zbuf;
+         }
+      }
+      else if (ret != Z_STREAM_END)
+      {
+         /* we got an error */
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+   } while (ret != Z_STREAM_END);
+
+   /* text length is number of buffers plus last buffer */
+   text_len = png_ptr->zbuf_size * comp->num_output_ptr;
+   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
+      text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
+
+   return((int)text_len);
+}
+
+/* ship the compressed text out via chunk writes */
+static void /* PRIVATE */
+png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
+{
+   int i;
+
+   /* handle the no-compression case */
+   if (comp->input)
+   {
+       png_write_chunk_data(png_ptr, (png_bytep)comp->input, comp->input_len);
+       return;
+   }
+
+   /* write saved output buffers, if any */
+   for (i = 0; i < comp->num_output_ptr; i++)
+   {
+      png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i],
+         png_ptr->zbuf_size);
+      png_free(png_ptr, comp->output_ptr[i]);
+      comp->output_ptr[i]=NULL;
+   }
+   if (comp->max_output_ptr != 0)
+      png_free(png_ptr, comp->output_ptr);
+      comp->output_ptr=NULL;
+   /* write anything left in zbuf */
+   if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
+      png_write_chunk_data(png_ptr, png_ptr->zbuf,
+         png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+
+   /* reset zlib for another zTXt/iTXt or the image data */
+   deflateReset(&png_ptr->zstream);
+
+}
+#endif
+
 /* Write the IHDR chunk, and update the png_struct with the necessary
  * information.  Note that the rest of this code depends upon this
  * information being correct.
  */
-void
+void /* PRIVATE */
 png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
    int bit_depth, int color_type, int compression_type, int filter_type,
    int interlace_type)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IHDR;
+#endif
    png_byte buf[13]; /* buffer to store the IHDR info */
 
    png_debug(1, "in png_write_IHDR\n");
@@ -193,7 +421,24 @@
       compression_type = PNG_COMPRESSION_TYPE_BASE;
    }
 
-   if (filter_type != PNG_FILTER_TYPE_BASE)
+   /* Write filter_method 64 (intrapixel differencing) only if
+    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+    * 2. Libpng did not write a PNG signature (this filter_method is only
+    *    used in PNG datastreams that are embedded in MNG datastreams) and
+    * 3. The application called png_permit_mng_features with a mask that
+    *    included PNG_FLAG_MNG_FILTER_64 and
+    * 4. The filter_method is 64 and
+    * 5. The color_type is RGB or RGBA
+    */
+   if (
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+      !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+      ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
+      (color_type == PNG_COLOR_TYPE_RGB || 
+       color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
+      (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
+#endif
+      filter_type != PNG_FILTER_TYPE_BASE)
    {
       png_warning(png_ptr, "Invalid filter type specified");
       filter_type = PNG_FILTER_TYPE_BASE;
@@ -214,6 +459,7 @@
    png_ptr->bit_depth = (png_byte)bit_depth;
    png_ptr->color_type = (png_byte)color_type;
    png_ptr->interlaced = (png_byte)interlace_type;
+   png_ptr->filter_type = (png_byte)filter_type;
    png_ptr->width = width;
    png_ptr->height = height;
 
@@ -234,7 +480,7 @@
    buf[12] = (png_byte)interlace_type;
 
    /* write the chunk */
-   png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
+   png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13);
 
    /* initialize zlib with PNG info */
    png_ptr->zstream.zalloc = png_zalloc;
@@ -276,31 +522,39 @@
  * correct order for PNG, so people can redefine it to any convenient
  * structure.
  */
-void
+void /* PRIVATE */
 png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_PLTE;
+#endif
    png_uint_32 i;
    png_colorp pal_ptr;
    png_byte buf[3];
 
    png_debug(1, "in png_write_PLTE\n");
-   if (num_pal == 0 || num_pal > 256)
-   {
-      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      {
-         png_error(png_ptr, "Invalid number of colors in palette");
-      }
-      else
-      {
-         png_warning(png_ptr, "Invalid number of colors in palette");
-         return;
-      }
+   if ((
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+        !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
+#endif
+        num_pal == 0) || num_pal > 256)
+     {
+       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+         {
+           png_error(png_ptr, "Invalid number of colors in palette");
+         }
+       else
+         {
+           png_warning(png_ptr, "Invalid number of colors in palette");
+           return;
+         }
    }
 
    png_ptr->num_palette = (png_uint_16)num_pal;
    png_debug1(3, "num_palette = %d\n", png_ptr->num_palette);
 
-   png_write_chunk_start(png_ptr, png_PLTE, num_pal * 3);
+   png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, num_pal * 3);
+#ifndef PNG_NO_POINTER_INDEXING
    for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
    {
       buf[0] = pal_ptr->red;
@@ -308,49 +562,89 @@
       buf[2] = pal_ptr->blue;
       png_write_chunk_data(png_ptr, buf, (png_size_t)3);
    }
+#else
+   /* This is a little slower but some buggy compilers need to do this instead */
+   pal_ptr=palette;
+   for (i = 0; i < num_pal; i++)
+   {
+      buf[0] = pal_ptr[i].red;
+      buf[1] = pal_ptr[i].green;
+      buf[2] = pal_ptr[i].blue;
+      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+   }
+#endif
    png_write_chunk_end(png_ptr);
    png_ptr->mode |= PNG_HAVE_PLTE;
 }
 
 /* write an IDAT chunk */
-void
+void /* PRIVATE */
 png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IDAT;
+#endif
    png_debug(1, "in png_write_IDAT\n");
-   png_write_chunk(png_ptr, png_IDAT, data, length);
+   png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
    png_ptr->mode |= PNG_HAVE_IDAT;
 }
 
 /* write an IEND chunk */
-void
+void /* PRIVATE */
 png_write_IEND(png_structp png_ptr)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IEND;
+#endif
    png_debug(1, "in png_write_IEND\n");
-   png_write_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
+   png_write_chunk(png_ptr, (png_bytep)png_IEND, NULL, (png_size_t)0);
    png_ptr->mode |= PNG_HAVE_IEND;
 }
 
 #if defined(PNG_WRITE_gAMA_SUPPORTED)
 /* write a gAMA chunk */
-void
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void /* PRIVATE */
 png_write_gAMA(png_structp png_ptr, double file_gamma)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_gAMA;
+#endif
    png_uint_32 igamma;
    png_byte buf[4];
 
    png_debug(1, "in png_write_gAMA\n");
-   /* file_gamma is saved in 1/1000000ths */
+   /* file_gamma is saved in 1/100,000ths */
    igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
    png_save_uint_32(buf, igamma);
-   png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
+   png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
 }
 #endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_gAMA;
+#endif
+   png_byte buf[4];
+
+   png_debug(1, "in png_write_gAMA\n");
+   /* file_gamma is saved in 1/100,000ths */
+   png_save_uint_32(buf, file_gamma);
+   png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
+}
+#endif
+#endif
 
 #if defined(PNG_WRITE_sRGB_SUPPORTED)
 /* write a sRGB chunk */
-void
+void /* PRIVATE */
 png_write_sRGB(png_structp png_ptr, int srgb_intent)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sRGB;
+#endif
    png_byte buf[1];
 
    png_debug(1, "in png_write_sRGB\n");
@@ -358,15 +652,146 @@
          png_warning(png_ptr,
             "Invalid sRGB rendering intent specified");
    buf[0]=(png_byte)srgb_intent;
-   png_write_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
+   png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1);
+}
+#endif
+
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+/* write an iCCP chunk */
+void /* PRIVATE */
+png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
+   png_charp profile, int profile_len)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_iCCP;
+#endif
+   png_size_t name_len;
+   png_charp new_name;
+   compression_state comp;
+
+   png_debug(1, "in png_write_iCCP\n");
+   if (name == NULL || (name_len = png_check_keyword(png_ptr, name,
+      &new_name)) == 0)
+   {
+      png_warning(png_ptr, "Empty keyword in iCCP chunk");
+      return;
+   }
+
+   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+      png_warning(png_ptr, "Unknown compression type in iCCP chunk");
+
+   if (profile == NULL)
+      profile_len = 0;
+
+   if (profile_len)
+       profile_len = png_text_compress(png_ptr, profile, (png_size_t)profile_len,
+          PNG_COMPRESSION_TYPE_BASE, &comp);
+
+   /* make sure we include the NULL after the name and the compression type */
+   png_write_chunk_start(png_ptr, (png_bytep)png_iCCP,
+          (png_uint_32)name_len+profile_len+2);
+   new_name[name_len+1]=0x00;
+   png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2);
+
+   if (profile_len)
+      png_write_compressed_data_out(png_ptr, &comp);
+
+   png_write_chunk_end(png_ptr);
+   png_free(png_ptr, new_name);
+}
+#endif
+
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+/* write a sPLT chunk */
+void /* PRIVATE */
+png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sPLT;
+#endif
+   png_size_t name_len;
+   png_charp new_name;
+   png_byte entrybuf[10];
+   int entry_size = (spalette->depth == 8 ? 6 : 10);
+   int palette_size = entry_size * spalette->nentries;
+   png_sPLT_entryp ep;
+#ifdef PNG_NO_POINTER_INDEXING
+   int i;
+#endif
+
+   png_debug(1, "in png_write_sPLT\n");
+   if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr,
+      spalette->name, &new_name))==0)
+   {
+      png_warning(png_ptr, "Empty keyword in sPLT chunk");
+      return;
+   }
+
+   /* make sure we include the NULL after the name */
+   png_write_chunk_start(png_ptr, (png_bytep) png_sPLT,
+          (png_uint_32)(name_len + 2 + palette_size));
+   png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 1);
+   png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, 1);
+
+   /* loop through each palette entry, writing appropriately */
+#ifndef PNG_NO_POINTER_INDEXING
+   for (ep = spalette->entries; ep<spalette->entries+spalette->nentries; ep++)
+   {
+       if (spalette->depth == 8)
+       {
+           entrybuf[0] = (png_byte)ep->red;
+           entrybuf[1] = (png_byte)ep->green;
+           entrybuf[2] = (png_byte)ep->blue;
+           entrybuf[3] = (png_byte)ep->alpha;
+           png_save_uint_16(entrybuf + 4, ep->frequency);
+       }
+       else
+       {
+           png_save_uint_16(entrybuf + 0, ep->red);
+           png_save_uint_16(entrybuf + 2, ep->green);
+           png_save_uint_16(entrybuf + 4, ep->blue);
+           png_save_uint_16(entrybuf + 6, ep->alpha);
+           png_save_uint_16(entrybuf + 8, ep->frequency);
+       }
+       png_write_chunk_data(png_ptr, entrybuf, entry_size);
+   }
+#else
+   ep=spalette->entries;
+   for (i=0; i>spalette->nentries; i++)
+   {
+       if (spalette->depth == 8)
+       {
+           entrybuf[0] = (png_byte)ep[i].red;
+           entrybuf[1] = (png_byte)ep[i].green;
+           entrybuf[2] = (png_byte)ep[i].blue;
+           entrybuf[3] = (png_byte)ep[i].alpha;
+           png_save_uint_16(entrybuf + 4, ep[i].frequency);
+       }
+       else
+       {
+           png_save_uint_16(entrybuf + 0, ep[i].red);
+           png_save_uint_16(entrybuf + 2, ep[i].green);
+           png_save_uint_16(entrybuf + 4, ep[i].blue);
+           png_save_uint_16(entrybuf + 6, ep[i].alpha);
+           png_save_uint_16(entrybuf + 8, ep[i].frequency);
+       }
+       png_write_chunk_data(png_ptr, entrybuf, entry_size);
+   }
+#endif
+
+   png_write_chunk_end(png_ptr);
+   png_free(png_ptr, new_name);
 }
 #endif
 
 #if defined(PNG_WRITE_sBIT_SUPPORTED)
 /* write the sBIT chunk */
-void
+void /* PRIVATE */
 png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sBIT;
+#endif
    png_byte buf[4];
    png_size_t size;
 
@@ -376,7 +801,8 @@
    {
       png_byte maxbits;
 
-      maxbits = color_type==PNG_COLOR_TYPE_PALETTE ? 8 : png_ptr->usr_bit_depth;
+      maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
+                png_ptr->usr_bit_depth);
       if (sbit->red == 0 || sbit->red > maxbits ||
           sbit->green == 0 || sbit->green > maxbits ||
           sbit->blue == 0 || sbit->blue > maxbits)
@@ -410,26 +836,33 @@
       buf[size++] = sbit->alpha;
    }
 
-   png_write_chunk(png_ptr, png_sBIT, buf, size);
+   png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size);
 }
 #endif
 
 #if defined(PNG_WRITE_cHRM_SUPPORTED)
 /* write the cHRM chunk */
-void
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void /* PRIVATE */
 png_write_cHRM(png_structp png_ptr, double white_x, double white_y,
    double red_x, double red_y, double green_x, double green_y,
    double blue_x, double blue_y)
 {
-   png_uint_32 itemp;
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_cHRM;
+#endif
    png_byte buf[32];
+   png_uint_32 itemp;
 
    png_debug(1, "in png_write_cHRM\n");
-   /* each value is saved int 1/1000000ths */
+   /* each value is saved in 1/100,000ths */
    if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
        white_x + white_y > 1.0)
    {
       png_warning(png_ptr, "Invalid cHRM white point specified");
+#if !defined(PNG_NO_CONSOLE_IO)
+      fprintf(stderr,"white_x=%f, white_y=%f\n",white_x, white_y);
+#endif
       return;
    }
    itemp = (png_uint_32)(white_x * 100000.0 + 0.5);
@@ -470,16 +903,72 @@
    itemp = (png_uint_32)(blue_y * 100000.0 + 0.5);
    png_save_uint_32(buf + 28, itemp);
 
-   png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32);
+   png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
 }
 #endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
+   png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y,
+   png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
+   png_fixed_point blue_y)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_cHRM;
+#endif
+   png_byte buf[32];
+
+   png_debug(1, "in png_write_cHRM\n");
+   /* each value is saved in 1/100,000ths */
+   if (white_x > 80000L || white_y > 80000L || white_x + white_y > 100000L)
+   {
+      png_warning(png_ptr, "Invalid fixed cHRM white point specified");
+#if !defined(PNG_NO_CONSOLE_IO)
+      fprintf(stderr,"white_x=%ld, white_y=%ld\n",white_x, white_y);
+#endif
+      return;
+   }
+   png_save_uint_32(buf, white_x);
+   png_save_uint_32(buf + 4, white_y);
+
+   if (red_x > 80000L || red_y > 80000L || red_x + red_y > 100000L)
+   {
+      png_warning(png_ptr, "Invalid cHRM fixed red point specified");
+      return;
+   }
+   png_save_uint_32(buf + 8, red_x);
+   png_save_uint_32(buf + 12, red_y);
+
+   if (green_x > 80000L || green_y > 80000L || green_x + green_y > 100000L)
+   {
+      png_warning(png_ptr, "Invalid fixed cHRM green point specified");
+      return;
+   }
+   png_save_uint_32(buf + 16, green_x);
+   png_save_uint_32(buf + 20, green_y);
+
+   if (blue_x > 80000L || blue_y > 80000L || blue_x + blue_y > 100000L)
+   {
+      png_warning(png_ptr, "Invalid fixed cHRM blue point specified");
+      return;
+   }
+   png_save_uint_32(buf + 24, blue_x);
+   png_save_uint_32(buf + 28, blue_y);
+
+   png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
+}
+#endif
+#endif
 
 #if defined(PNG_WRITE_tRNS_SUPPORTED)
 /* write the tRNS chunk */
-void
+void /* PRIVATE */
 png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
    int num_trans, int color_type)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_tRNS;
+#endif
    png_byte buf[6];
 
    png_debug(1, "in png_write_tRNS\n");
@@ -491,13 +980,13 @@
          return;
       }
       /* write the chunk out as it is */
-      png_write_chunk(png_ptr, png_tRNS, trans, (png_size_t)num_trans);
+      png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans, (png_size_t)num_trans);
    }
    else if (color_type == PNG_COLOR_TYPE_GRAY)
    {
       /* one 16 bit value */
       png_save_uint_16(buf, tran->gray);
-      png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
+      png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2);
    }
    else if (color_type == PNG_COLOR_TYPE_RGB)
    {
@@ -505,7 +994,7 @@
       png_save_uint_16(buf, tran->red);
       png_save_uint_16(buf + 2, tran->green);
       png_save_uint_16(buf + 4, tran->blue);
-      png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
+      png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6);
    }
    else
    {
@@ -516,42 +1005,53 @@
 
 #if defined(PNG_WRITE_bKGD_SUPPORTED)
 /* write the background chunk */
-void
+void /* PRIVATE */
 png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_bKGD;
+#endif
    png_byte buf[6];
 
    png_debug(1, "in png_write_bKGD\n");
    if (color_type == PNG_COLOR_TYPE_PALETTE)
    {
-      if (back->index > png_ptr->num_palette)
+      if (
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+          (png_ptr->num_palette ||
+          (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
+#endif
+         back->index > png_ptr->num_palette)
       {
          png_warning(png_ptr, "Invalid background palette index");
          return;
       }
       buf[0] = back->index;
-      png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
+      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1);
    }
    else if (color_type & PNG_COLOR_MASK_COLOR)
    {
       png_save_uint_16(buf, back->red);
       png_save_uint_16(buf + 2, back->green);
       png_save_uint_16(buf + 4, back->blue);
-      png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
+      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6);
    }
    else
    {
       png_save_uint_16(buf, back->gray);
-      png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
+      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2);
    }
 }
 #endif
 
 #if defined(PNG_WRITE_hIST_SUPPORTED)
 /* write the histogram */
-void
+void /* PRIVATE */
 png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_hIST;
+#endif
    int i;
    png_byte buf[3];
 
@@ -564,7 +1064,7 @@
       return;
    }
 
-   png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
+   png_write_chunk_start(png_ptr, (png_bytep)png_hIST, (png_uint_32)(num_hist * 2));
    for (i = 0; i < num_hist; i++)
    {
       png_save_uint_16(buf, hist[i]);
@@ -574,8 +1074,8 @@
 }
 #endif
 
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) || \
-    defined(PNG_WRITE_pCAL_SUPPORTED)
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
 /* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
  * and if invalid, correct the keyword rather than discarding the entire
  * chunk.  The PNG 1.0 specification requires keywords 1-79 characters in
@@ -586,38 +1086,39 @@
  * by the calling routine.  This avoids problems with trying to write to
  * static keywords without having to have duplicate copies of the strings.
  */
-png_size_t
+png_size_t /* PRIVATE */
 png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
 {
    png_size_t key_len;
    png_charp kp, dp;
    int kflag;
+   int kwarn=0;
 
    png_debug(1, "in png_check_keyword\n");
    *new_key = NULL;
 
    if (key == NULL || (key_len = png_strlen(key)) == 0)
    {
-      png_chunk_warning(png_ptr, "zero length keyword");
+      png_warning(png_ptr, "zero length keyword");
       return ((png_size_t)0);
    }
 
    png_debug1(2, "Keyword to be checked is '%s'\n", key);
 
-   *new_key = (png_charp)png_malloc(png_ptr, (png_uint_32)(key_len + 1));
+   *new_key = (png_charp)png_malloc(png_ptr, (png_uint_32)(key_len + 2));
 
    /* Replace non-printing characters with a blank and print a warning */
    for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++)
    {
       if (*kp < 0x20 || (*kp > 0x7E && (png_byte)*kp < 0xA1))
       {
-#if !defined(PNG_NO_STDIO)
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
          char msg[40];
 
          sprintf(msg, "invalid keyword character 0x%02X", *kp);
-         png_chunk_warning(png_ptr, msg);
+         png_warning(png_ptr, msg);
 #else
-         png_chunk_warning(png_ptr, "invalid character in keyword");
+         png_warning(png_ptr, "invalid character in keyword");
 #endif
          *dp = ' ';
       }
@@ -632,7 +1133,7 @@
    kp = *new_key + key_len - 1;
    if (*kp == ' ')
    {
-      png_chunk_warning(png_ptr, "trailing spaces removed from keyword");
+      png_warning(png_ptr, "trailing spaces removed from keyword");
 
       while (*kp == ' ')
       {
@@ -645,7 +1146,7 @@
    kp = *new_key;
    if (*kp == ' ')
    {
-      png_chunk_warning(png_ptr, "leading spaces removed from keyword");
+      png_warning(png_ptr, "leading spaces removed from keyword");
 
       while (*kp == ' ')
       {
@@ -667,6 +1168,7 @@
       else if (*kp == ' ')
       {
          key_len--;
+         kwarn=1;
       }
       else
       {
@@ -675,15 +1177,19 @@
       }
    }
    *dp = '\0';
+   if(kwarn)
+      png_warning(png_ptr, "extra interior spaces removed from keyword");
 
    if (key_len == 0)
    {
-      png_chunk_warning(png_ptr, "zero length keyword");
+      png_free(png_ptr, *new_key);
+      *new_key=NULL;
+      png_warning(png_ptr, "Zero length keyword");
    }
 
    if (key_len > 79)
    {
-      png_chunk_warning(png_ptr, "keyword length must be 1 - 79 characters");
+      png_warning(png_ptr, "keyword length must be 1 - 79 characters");
       new_key[79] = '\0';
       key_len = 79;
    }
@@ -694,10 +1200,13 @@
 
 #if defined(PNG_WRITE_tEXt_SUPPORTED)
 /* write a tEXt chunk */
-void
+void /* PRIVATE */
 png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
    png_size_t text_len)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_tEXt;
+#endif
    png_size_t key_len;
    png_charp new_key;
 
@@ -710,9 +1219,17 @@
 
    if (text == NULL || *text == '\0')
       text_len = 0;
+   else
+      text_len = png_strlen(text);
 
    /* make sure we include the 0 after the key */
-   png_write_chunk_start(png_ptr, png_tEXt, (png_uint_32)key_len+text_len+1);
+   png_write_chunk_start(png_ptr, (png_bytep)png_tEXt, (png_uint_32)key_len+text_len+1);
+   /*
+    * We leave it to the application to meet PNG-1.0 requirements on the
+    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
+    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
+    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+    */
    png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
    if (text_len)
       png_write_chunk_data(png_ptr, (png_bytep)text, text_len);
@@ -724,17 +1241,17 @@
 
 #if defined(PNG_WRITE_zTXt_SUPPORTED)
 /* write a compressed text chunk */
-void
+void /* PRIVATE */
 png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
    png_size_t text_len, int compression)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_zTXt;
+#endif
    png_size_t key_len;
    char buf[1];
    png_charp new_key;
-   int i, ret;
-   png_charpp output_ptr = NULL; /* array of pointers to output */
-   int num_output_ptr = 0; /* number of output pointers used */
-   int max_output_ptr = 0; /* size of output_ptr */
+   compression_state comp;
 
    png_debug(1, "in png_write_zTXt\n");
 
@@ -751,187 +1268,118 @@
       return;
    }
 
-   png_free(png_ptr, new_key);
-
-   if (compression >= PNG_TEXT_COMPRESSION_LAST)
-   {
-#if !defined(PNG_NO_STDIO)
-      char msg[50];
-      sprintf(msg, "Unknown zTXt compression type %d", compression);
-      png_warning(png_ptr, msg);
-#else
-      png_warning(png_ptr, "Unknown zTXt compression type");
-#endif
-      compression = PNG_TEXT_COMPRESSION_zTXt;
-   }
-
-   /* We can't write the chunk until we find out how much data we have,
-    * which means we need to run the compressor first and save the
-    * output.  This shouldn't be a problem, as the vast majority of
-    * comments should be reasonable, but we will set up an array of
-    * malloc'd pointers to be sure.
-    *
-    * If we knew the application was well behaved, we could simplify this
-    * greatly by assuming we can always malloc an output buffer large
-    * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
-    * and malloc this directly.  The only time this would be a bad idea is
-    * if we can't malloc more than 64K and we have 64K of random input
-    * data, or if the input string is incredibly large (although this
-    * wouldn't cause a failure, just a slowdown due to swapping).
-    */
+   text_len = png_strlen(text);
 
-   /* set up the compression buffers */
-   png_ptr->zstream.avail_in = (uInt)text_len;
-   png_ptr->zstream.next_in = (Bytef *)text;
-   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-   png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
+   png_free(png_ptr, new_key);
 
-   /* this is the same compression loop as in png_write_row() */
-   do
-   {
-      /* compress the data */
-      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
-      if (ret != Z_OK)
-      {
-         /* error */
-         if (png_ptr->zstream.msg != NULL)
-            png_error(png_ptr, png_ptr->zstream.msg);
-         else
-            png_error(png_ptr, "zlib error");
-      }
-      /* check to see if we need more room */
-      if (!png_ptr->zstream.avail_out && png_ptr->zstream.avail_in)
-      {
-         /* make sure the output array has room */
-         if (num_output_ptr >= max_output_ptr)
-         {
-            int old_max;
+   /* compute the compressed data; do it now for the length */
+   text_len = png_text_compress(png_ptr, text, text_len, compression,
+       &comp);
 
-            old_max = max_output_ptr;
-            max_output_ptr = num_output_ptr + 4;
-            if (output_ptr != NULL)
-            {
-               png_charpp old_ptr;
+   /* write start of chunk */
+   png_write_chunk_start(png_ptr, (png_bytep)png_zTXt, (png_uint_32)
+      (key_len+text_len+2));
+   /* write key */
+   png_write_chunk_data(png_ptr, (png_bytep)key, key_len + 1);
+   buf[0] = (png_byte)compression;
+   /* write compression */
+   png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
+   /* write the compressed data */
+   png_write_compressed_data_out(png_ptr, &comp);
 
-               old_ptr = output_ptr;
-               output_ptr = (png_charpp)png_malloc(png_ptr,
-                  (png_uint_32)(max_output_ptr * sizeof (png_charpp)));
-               png_memcpy(output_ptr, old_ptr, old_max * sizeof (png_charp));
-               png_free(png_ptr, old_ptr);
-            }
-            else
-               output_ptr = (png_charpp)png_malloc(png_ptr,
-                  (png_uint_32)(max_output_ptr * sizeof (png_charp)));
-         }
+   /* close the chunk */
+   png_write_chunk_end(png_ptr);
+}
+#endif
 
-         /* save the data */
-         output_ptr[num_output_ptr] = (png_charp)png_malloc(png_ptr,
-            (png_uint_32)png_ptr->zbuf_size);
-         png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
-            png_ptr->zbuf_size);
-         num_output_ptr++;
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+/* write an iTXt chunk */
+void /* PRIVATE */
+png_write_iTXt(png_structp png_ptr, int compression, png_charp key,
+    png_charp lang, png_charp lang_key, png_charp text)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_iTXt;
+#endif
+   png_size_t lang_len, key_len, lang_key_len, text_len;
+   png_charp new_lang, new_key;
+   png_byte cbuf[2];
+   compression_state comp;
 
-         /* and reset the buffer */
-         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-         png_ptr->zstream.next_out = png_ptr->zbuf;
-      }
-   /* continue until we don't have any more to compress */
-   } while (png_ptr->zstream.avail_in);
+   png_debug(1, "in png_write_iTXt\n");
 
-   /* finish the compression */
-   do
+   if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
    {
-      /* tell zlib we are finished */
-      ret = deflate(&png_ptr->zstream, Z_FINISH);
-      if (ret != Z_OK && ret != Z_STREAM_END)
-      {
-         /* we got an error */
-         if (png_ptr->zstream.msg != NULL)
-            png_error(png_ptr, png_ptr->zstream.msg);
-         else
-            png_error(png_ptr, "zlib error");
-      }
-
-      /* check to see if we need more room */
-      if (!(png_ptr->zstream.avail_out) && ret == Z_OK)
-      {
-         /* check to make sure our output array has room */
-         if (num_output_ptr >= max_output_ptr)
-         {
-            int old_max;
-
-            old_max = max_output_ptr;
-            max_output_ptr = num_output_ptr + 4;
-            if (output_ptr != NULL)
-            {
-               png_charpp old_ptr;
-
-               old_ptr = output_ptr;
-               /* This could be optimized to rrd_realloc() */
-               output_ptr = (png_charpp)png_malloc(png_ptr,
-                  (png_uint_32)(max_output_ptr * sizeof (png_charpp)));
-               png_memcpy(output_ptr, old_ptr, old_max * sizeof (png_charp));
-               png_free(png_ptr, old_ptr);
-            }
-            else
-               output_ptr = (png_charpp)png_malloc(png_ptr,
-                  (png_uint_32)(max_output_ptr * sizeof (png_charp)));
-         }
+      png_warning(png_ptr, "Empty keyword in iTXt chunk");
+      return;
+   }
+   if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang,
+      &new_lang))==0)
+   {
+      png_warning(png_ptr, "Empty language field in iTXt chunk");
+      return;
+   }
+   lang_key_len = png_strlen(lang_key);
+   text_len = png_strlen(text);
 
-         /* save off the data */
-         output_ptr[num_output_ptr] = (png_charp)png_malloc(png_ptr,
-            (png_uint_32)png_ptr->zbuf_size);
-         png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
-            png_ptr->zbuf_size);
-         num_output_ptr++;
+   if (text == NULL || *text == '\0')
+      text_len = 0;
 
-         /* and reset the buffer pointers */
-         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-         png_ptr->zstream.next_out = png_ptr->zbuf;
-      }
-   } while (ret != Z_STREAM_END);
+   /* compute the compressed data; do it now for the length */
+   text_len = png_text_compress(png_ptr, text, text_len, compression-2,
+      &comp);
+
+   /* make sure we include the compression flag, the compression byte,
+    * and the NULs after the key, lang, and lang_key parts */
+
+   png_write_chunk_start(png_ptr, (png_bytep)png_iTXt,
+          (png_uint_32)(
+        5 /* comp byte, comp flag, terminators for key, lang and lang_key */
+        + key_len
+        + lang_len
+        + lang_key_len
+        + text_len));
+
+   /*
+    * We leave it to the application to meet PNG-1.0 requirements on the
+    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
+    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
+    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+    */
+   png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
 
-   /* text length is number of buffers plus last buffer */
-   text_len = png_ptr->zbuf_size * num_output_ptr;
-   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
-      text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
+   /* set the compression flag */
+   if (compression == PNG_ITXT_COMPRESSION_NONE || \
+       compression == PNG_TEXT_COMPRESSION_NONE)
+       cbuf[0] = 0;
+   else /* compression == PNG_ITXT_COMPRESSION_zTXt */
+       cbuf[0] = 1;
+   /* set the compression method */
+   cbuf[1] = 0;
+   png_write_chunk_data(png_ptr, cbuf, 2);
+
+   png_write_chunk_data(png_ptr, (png_bytep)new_lang, lang_len + 1);
+   png_write_chunk_data(png_ptr, (png_bytep)lang_key, lang_key_len+1);
+   png_write_chunk_data(png_ptr, '\0', 1);
 
-   /* write start of chunk */
-   png_write_chunk_start(png_ptr, png_zTXt, (png_uint_32)(key_len+text_len+2));
-   /* write key */
-   png_write_chunk_data(png_ptr, (png_bytep)key, key_len + 1);
-   buf[0] = (png_byte)compression;
-   /* write compression */
-   png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
+   png_write_compressed_data_out(png_ptr, &comp);
 
-   /* write saved output buffers, if any */
-   for (i = 0; i < num_output_ptr; i++)
-   {
-      png_write_chunk_data(png_ptr,(png_bytep)output_ptr[i],png_ptr->zbuf_size);
-      png_free(png_ptr, output_ptr[i]);
-   }
-   if (max_output_ptr != 0)
-      png_free(png_ptr, output_ptr);
-   /* write anything left in zbuf */
-   if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
-      png_write_chunk_data(png_ptr, png_ptr->zbuf,
-         png_ptr->zbuf_size - png_ptr->zstream.avail_out);
-   /* close the chunk */
    png_write_chunk_end(png_ptr);
-
-   /* reset zlib for another zTXt or the image data */
-   deflateReset(&png_ptr->zstream);
+   png_free(png_ptr, new_key);
+   png_free(png_ptr, new_lang);
 }
 #endif
 
-
 #if defined(PNG_WRITE_oFFs_SUPPORTED)
 /* write the oFFs chunk */
-void
+void /* PRIVATE */
 png_write_oFFs(png_structp png_ptr, png_uint_32 x_offset,
    png_uint_32 y_offset,
    int unit_type)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_oFFs;
+#endif
    png_byte buf[9];
 
    png_debug(1, "in png_write_oFFs\n");
@@ -942,16 +1390,19 @@
    png_save_uint_32(buf + 4, y_offset);
    buf[8] = (png_byte)unit_type;
 
-   png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
+   png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9);
 }
 #endif
 
 #if defined(PNG_WRITE_pCAL_SUPPORTED)
-/* write the pCAL chunk (png-scivis-19970203) */
-void
+/* write the pCAL chunk (described in the PNG extensions document) */
+void /* PRIVATE */
 png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
    png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_pCAL;
+#endif
    png_size_t purpose_len, units_len, total_len;
    png_uint_32p params_len;
    png_byte buf[10];
@@ -976,12 +1427,12 @@
    for (i = 0; i < nparams; i++)
    {
       params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
-      png_debug2(3, "pCAL parameter %d length = %d\n", i, params_len[i]);
+      png_debug2(3, "pCAL parameter %d length = %lu\n", i, params_len[i]);
       total_len += (png_size_t)params_len[i];
    }
 
    png_debug1(3, "pCAL total length = %d\n", total_len);
-   png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len);
+   png_write_chunk_start(png_ptr, (png_bytep)png_pCAL, (png_uint_32)total_len);
    png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len);
    png_save_int_32(buf, X0);
    png_save_int_32(buf + 4, X1);
@@ -1003,13 +1454,83 @@
 }
 #endif
 
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+/* write the sCAL chunk */
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
+void /* PRIVATE */
+png_write_sCAL(png_structp png_ptr, int unit, double width,double height)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sCAL;
+#endif
+   png_size_t total_len;
+   char wbuf[32], hbuf[32];
+
+   png_debug(1, "in png_write_sCAL\n");
+
+#if defined(_WIN32_WCE)
+/* sprintf() function is not supported on WindowsCE */
+   {
+      wchar_t wc_buf[32];
+      swprintf(wc_buf, TEXT("%12.12e"), width);
+      WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, wbuf, 32, NULL, NULL);
+      swprintf(wc_buf, TEXT("%12.12e"), height);
+      WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, hbuf, 32, NULL, NULL);
+   }
+#else
+   sprintf(wbuf, "%12.12e", width);
+   sprintf(hbuf, "%12.12e", height);
+#endif
+   total_len = 1 + png_strlen(wbuf)+1 + png_strlen(hbuf);
+
+   png_debug1(3, "sCAL total length = %d\n", total_len);
+   png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len);
+   png_write_chunk_data(png_ptr, (png_bytep)&unit, 1);
+   png_write_chunk_data(png_ptr, (png_bytep)wbuf, strlen(wbuf)+1);
+   png_write_chunk_data(png_ptr, (png_bytep)hbuf, strlen(hbuf));
+
+   png_write_chunk_end(png_ptr);
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width,
+   png_charp height)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sCAL;
+#endif
+   png_size_t total_len;
+   char wbuf[32], hbuf[32];
+
+   png_debug(1, "in png_write_sCAL_s\n");
+
+   strcpy(wbuf,(const char *)width);
+   strcpy(hbuf,(const char *)height);
+   total_len = 1 + png_strlen(wbuf)+1 + png_strlen(hbuf);
+
+   png_debug1(3, "sCAL total length = %d\n", total_len);
+   png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len);
+   png_write_chunk_data(png_ptr, (png_bytep)&unit, 1);
+   png_write_chunk_data(png_ptr, (png_bytep)wbuf, strlen(wbuf)+1);
+   png_write_chunk_data(png_ptr, (png_bytep)hbuf, strlen(hbuf));
+
+   png_write_chunk_end(png_ptr);
+}
+#endif
+#endif
+#endif
+
 #if defined(PNG_WRITE_pHYs_SUPPORTED)
 /* write the pHYs chunk */
-void
+void /* PRIVATE */
 png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
    png_uint_32 y_pixels_per_unit,
    int unit_type)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_pHYs;
+#endif
    png_byte buf[9];
 
    png_debug(1, "in png_write_pHYs\n");
@@ -1020,7 +1541,7 @@
    png_save_uint_32(buf + 4, y_pixels_per_unit);
    buf[8] = (png_byte)unit_type;
 
-   png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
+   png_write_chunk(png_ptr, (png_bytep)png_pHYs, buf, (png_size_t)9);
 }
 #endif
 
@@ -1028,9 +1549,12 @@
 /* Write the tIME chunk.  Use either png_convert_from_struct_tm()
  * or png_convert_from_time_t(), or fill in the structure yourself.
  */
-void
+void /* PRIVATE */
 png_write_tIME(png_structp png_ptr, png_timep mod_time)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_tIME;
+#endif
    png_byte buf[7];
 
    png_debug(1, "in png_write_tIME\n");
@@ -1049,14 +1573,30 @@
    buf[5] = mod_time->minute;
    buf[6] = mod_time->second;
 
-   png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
+   png_write_chunk(png_ptr, (png_bytep)png_tIME, buf, (png_size_t)7);
 }
 #endif
 
 /* initializes the row writing capability of libpng */
-void
+void /* PRIVATE */
 png_write_start_row(png_structp png_ptr)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* start of interlace block */
+   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* offset to next interlace block */
+   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* start of interlace block in the y direction */
+   int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* offset to next interlace block in the y direction */
+   int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
    png_size_t buf_size;
 
    png_debug(1, "in png_write_start_row\n");
@@ -1132,9 +1672,25 @@
 }
 
 /* Internal use only.  Called when finished processing a row of data. */
-void
+void /* PRIVATE */
 png_write_finish_row(png_structp png_ptr)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* start of interlace block */
+   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* offset to next interlace block */
+   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* start of interlace block in the y direction */
+   int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* offset to next interlace block in the y direction */
+   int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
    int ret;
 
    png_debug(1, "in png_write_finish_row\n");
@@ -1196,20 +1752,23 @@
       /* tell the compressor we are done */
       ret = deflate(&png_ptr->zstream, Z_FINISH);
       /* check for an error */
-      if (ret != Z_OK && ret != Z_STREAM_END)
+      if (ret == Z_OK)
+      {
+         /* check to see if we need more room */
+         if (!(png_ptr->zstream.avail_out))
+         {
+            png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+            png_ptr->zstream.next_out = png_ptr->zbuf;
+            png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+         }
+      }
+      else if (ret != Z_STREAM_END)
       {
          if (png_ptr->zstream.msg != NULL)
             png_error(png_ptr, png_ptr->zstream.msg);
          else
             png_error(png_ptr, "zlib error");
       }
-      /* check to see if we need more room */
-      if (!(png_ptr->zstream.avail_out) && ret == Z_OK)
-      {
-         png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
-         png_ptr->zstream.next_out = png_ptr->zbuf;
-         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-      }
    } while (ret != Z_STREAM_END);
 
    /* write any extra space */
@@ -1230,9 +1789,19 @@
  * sp will always be >= dp, so we should never overwrite anything.
  * See the default: case for the easiest code to understand.
  */
-void
+void /* PRIVATE */
 png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* start of interlace block */
+   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* offset to next interlace block */
+   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+#endif
+
    png_debug(1, "in png_do_write_interlace\n");
    /* we don't have to do anything on the last pass (6) */
 #if defined(PNG_USELESS_TESTS_SUPPORTED)
@@ -1261,7 +1830,7 @@
                i += png_pass_inc[pass])
             {
                sp = row + (png_size_t)(i >> 3);
-               value = (int)(*sp >> (7 - (int)(i & 7))) & 0x1;
+               value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
                d |= (value << shift);
 
                if (shift == 0)
@@ -1295,7 +1864,7 @@
                i += png_pass_inc[pass])
             {
                sp = row + (png_size_t)(i >> 2);
-               value = (*sp >> ((3 - (int)(i & 3)) << 1)) & 0x3;
+               value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
                d |= (value << shift);
 
                if (shift == 0)
@@ -1328,7 +1897,7 @@
                i += png_pass_inc[pass])
             {
                sp = row + (png_size_t)(i >> 1);
-               value = (*sp >> ((1 - (int)(i & 1)) << 2)) & 0xf;
+               value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
                d |= (value << shift);
 
                if (shift == 0)
@@ -1391,7 +1960,7 @@
 #define PNG_HISHIFT 10
 #define PNG_LOMASK ((png_uint_32)0xffffL)
 #define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
-void
+void /* PRIVATE */
 png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
 {
    png_bytep prev_row, best_row, row_buf;
@@ -1435,7 +2004,7 @@
    /* We don't need to test the 'no filter' case if this is the only filter
     * that has been chosen, as it doesn't actually do anything to the data.
     */
-   if (filter_to_do & PNG_FILTER_NONE &&
+   if ((filter_to_do & PNG_FILTER_NONE) &&
        filter_to_do != PNG_FILTER_NONE)
    {
       png_bytep rp;
@@ -2003,12 +2572,13 @@
 
 
 /* Do the actual writing of a previously filtered row. */
-void
+void /* PRIVATE */
 png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
 {
    png_debug(1, "in png_write_filtered_row\n");
    png_debug1(2, "filter = %d\n", filtered_row[0]);
    /* set up the zlib input buffer */
+
    png_ptr->zstream.next_in = filtered_row;
    png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
    /* repeat until we have compressed all the data */
@@ -2059,5 +2629,5 @@
    {
       png_write_flush(png_ptr);
    }
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+#endif
 }

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/README
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/README	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/README	Sat Jul 13 21:26:54 2002
@@ -1,14 +1,19 @@
-README for libpng 1.0.3 - January 14, 1999 (shared library 2.1)
+README for libpng 1.0.9 - January 31, 2001 (shared library 2.1)
 See the note about version numbers near the top of png.h
 
 See INSTALL for instructions on how to install libpng.
 
-This is the first official release of libpng.  Don't let the fact that
-it's the first release fool you.  The libpng library has been in
-extensive use and testing for about two and a half years.  However, it's
-finally gotten to the stage where there haven't been significant
+Libpng comes in two distribution formats.  Get libpng-*.tar.gz if you
+want UNIX-style line endings in the text files, or lpng*.zip if you want
+DOS-style line endings.
+
+Version 0.89 was the first official release of libpng.  Don't let the
+fact that it's the first release fool you.  The libpng library has been in
+extensive use and testing since mid-1995.  By late 1997 it had
+finally gotten to the stage where there hadn't been significant
 changes to the API in some time, and people have a bad feeling about
-libraries with versions < 1.0.
+libraries with versions < 1.0.  Version 1.0.0 was released in
+March 1998.
 
 ****
 Note that some of the changes to the png_info structure render this
@@ -28,8 +33,8 @@
 It is important to note that the APIs do not make current programs
 that access the info struct directly incompatible with the new
 library.  However, it is strongly suggested that new programs use
-the new APIs (as shown in example.c), and older programs be converted
-to the new format, to facilitate upgrades in the future.
+the new APIs (as shown in example.c and pngtest.c), and older programs
+be converted to the new format, to facilitate upgrades in the future.
 ****
 
 Additions since 0.90 include the ability to compile libpng as a
@@ -49,8 +54,9 @@
 critical or an ancillary chunk.
 
 The changes made to the library, and bugs fixed are based on discussions
-on the PNG implementation mailing list <png-implement at dworking.wustl.edu>
-and not on material submitted to Guy.
+on the PNG implementation mailing list <png-implement at ccrc.wustl.edu>
+and not on material submitted privately to Guy, Andreas, or Glenn.  They will
+forward any good suggestions to the list.
 
 For a detailed description on using libpng, read libpng.txt.  For
 examples of libpng in a program, see example.c and pngtest.c.  For usage
@@ -98,8 +104,8 @@
 This release was created and will be supported by myself (of course
 based in a large way on Guy's and Andreas' earlier work), and the PNG group.
 
-randeg at alumni.rpi.edu
-png-implement at dworkin.wustl.edu
+randeg at alum.rpi.edu
+png-implement at ccrc.wustl.edu
 
 You can't reach Guy, the original libpng author, at the addresses
 given in previous versions of this document.  He and Andreas will read mail
@@ -108,7 +114,7 @@
 Please do not send general questions about PNG.  Send them to
 the address in the specification (png-group at w3.org).  At the same
 time, please do not send libpng questions to that address, send them to me
-or to png-implement at dworkin.wustl.edu.  I'll
+or to png-implement at ccrc.wustl.edu.  I'll
 get them in the end anyway.  If you have a question about something
 in the PNG specification that is related to using libpng, send it
 to me.  Send me any questions that start with "I was using libpng,
@@ -123,24 +129,27 @@
 
 Files in this distribution:
 
+      ANNOUNCE      =>  Announcement of this version, with recent changes
       CHANGES       =>  Description of changes between libpng versions
+      KNOWNBUG      =>  List of known bugs and deficiencies
+      LICENSE       =>  License to use and redistribute libpng
       README        =>  This file
       TODO          =>  Things not implemented in the current library
-      ansi2knr.1    =>  Manual page for ansi2knr
-      ansi2knr.c    =>  Converts files to K&R style function declarations
-      build.bat     =>  MS-DOS batch file for Borland compiler
-      descrip.mms   =>  VMS project file
+      Y2KINFO       =>  Statement of Y2K compliance
       example.c     =>  Example code for using libpng functions
-      libpng.3      =>  manual page for libpng
+      libpng.3      =>  manual page for libpng (includes libpng.txt)
       libpng.txt    =>  Description of libpng and its functions
       libpngpf.3    =>  manual page for libpng's private functions
       png.5         =>  manual page for the PNG format
       png.c         =>  Basic interface functions common to library
       png.h         =>  Library function and interface declarations
       pngconf.h     =>  System specific library configuration
+      pngasmrd.h    =>  Header file for assembler-coded functions
       pngerror.c    =>  Error/warning message I/O functions
       pngget.c      =>  Functions for retrieving info from struct
       pngmem.c      =>  Memory handling functions
+      pngbar.png    =>  PNG logo, 88x31
+      pngnow.png    =>  PNG logo, 98x31
       pngpread.c    =>  Progressive reading functions
       pngread.c     =>  Read data/helper high-level functions
       pngrio.c      =>  Lowest-level data read I/O functions
@@ -154,40 +163,77 @@
       pngwrite.c    =>  High-level write functions
       pngwtran.c    =>  Write data transformations
       pngwutil.c    =>  Write utility functions
+      contrib       =>  Contributions
+       gregbook         =>  source code for PNG reading and writing, from
+                            Greg Roelofs' "PNG: The Definitive Guide",
+                            O'Reilly, 1999
+       msvctest     =>  Builds and runs pngtest using a MSVC workspace
+       pngminus     =>  Simple pnm2png and png2pnm programs
+       pngsuite     =>  Test images
+       visupng      =>  Contains a MSVC workspace for VisualPng
+      projects      =>  Contains project files and workspaces for building DLL
+       borland          =>  Contains a Borland workspace for building libpng
+                            and zlib
+       msvc             =>  Contains a Microsoft Visual C++ (MSVC) workspace
+                            for building libpng and zlib
+       wince            =>  Contains a Microsoft Visual C++ (Windows CD Toolkit)
+                            workspace for building libpng and zlib on WindowsCE
       scripts       =>  Directory containing scripts for building libpng:
-        descrip.mms   =>  VMS makefile for MMS or MMK
-        makefile.std  =>  Generic UNIX makefile
-        makefile.knr  =>  Archaic UNIX Makefile that converts files with ansi2knr
-        makefile.dec  =>  DEC Alpha UNIX makefile
-        makefile.hux  =>  HPUX (10.20 and 11.00) makefile
-        makefile.sgi  =>  Silicon Graphics IRIX makefile
-        makefile.sun  =>  Sun makefile
-        makefile.s2x  =>  Solaris 2.X makefile (gcc, creates libpng.so.2.1.0)
-        makefile.lnx  =>  Linux/ELF makefile (gcc, creates libpng.so.2.1.0)
-        makefile.mip  =>  MIPS makefile
-        makefile.aco  =>  Acorn makefile
-        makefile.ama  =>  Amiga makefile
-        smakefile.ppc =>  AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
-                          (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
-        makefile.atr  =>  Atari makefile
-        makefile.bor  =>  Borland makefile
-        build.bat     =>  MS-DOS batch file for Borland compiler
-        makefile.dj2  =>  DJGPP 2 makefile
-        makefile.msc  =>  Microsoft C makefile
-        makefile.w32  =>  makefile for Microsoft Visual C++ 4.0 and later
-        makefile.tc3  =>  Turbo C 3.0 makefile
-        makefile.os2  =>  OS/2 Makefile (gcc and emx, requires pngos2.def)
-        makefile.wat  =>  Watcom 10a+ Makefile, 32-bit flat memory model
-        pngos2.def    =>  OS/2 module definition file used by makefile.os2
-        makevms.com   =>  VMS build script
-        pngdll.mak    =>  To make a png32bd.dll with Borland C++ 4.5
-        pngdef.pas    =>  Defines for a png32bd.dll with Borland C++ 4.5
+       descrip.mms      =>  VMS makefile for MMS or MMK
+       makefile.std     =>  Generic UNIX makefile (cc, creates static libpng.a)
+       makefile.linux   =>  Linux/ELF makefile
+                            (gcc, creates libpng.so.2.1.0.9)
+       makefile.gcmmx   =>  Linux/ELF makefile (gcc, creates
+                            libpng.so.2.1.0.9, uses assembler code
+                            tuned for Intel MMX platform)
+       makefile.gcc     =>  Generic makefile (gcc, creates static libpng.a)
+       makefile.knr     =>  Archaic UNIX Makefile that converts files with
+                            ansi2knr (Requires ansi2knr.c from
+                            ftp://ftp.cs.wisc.edu/ghost)
+       makefile.aix     =>  AIX makefile
+       makefile.cygwin  =>  Cygwin/gcc makefile
+       makefile.dec     =>  DEC Alpha UNIX makefile
+       makefile.hpux    =>  HPUX (10.20 and 11.00) makefile
+       makefile.ibmc    =>  IBM C/C++ version 3.x for Win32 and OS/2 (static)
+       makefile.intel   =>  Intel C/C++ version 4.0 and later
+       libpng.icc       =>  Project file, IBM VisualAge/C++ 4.0 or later
+       makefile.macosx  =>  MACOS X Makefile
+       makefile.sgi     =>  Silicon Graphics IRIX (cc, creates static lib)
+       makefile.sggcc   =>  Silicon Graphics (gcc, creates libpng.so.2.1.0.9)
+       makefile.sunos   =>  Sun makefile
+       makefile.solaris =>  Solaris 2.X makefile
+                            (gcc, creates libpng.so.2.1.0.9)
+       makefile.sco     =>  For SCO OSr5  ELF and Unixware 7 with Native cc
+       makefile.mips    =>  MIPS makefile
+       makefile.acorn   =>  Acorn makefile
+       makefile.amiga   =>  Amiga makefile
+       smakefile.ppc    =>  AMIGA smakefile for SAS C V6.58/7.00 PPC
+                            compiler (Requires SCOPTIONS, copied from
+                            scripts/SCOPTIONS.ppc)
+       makefile.atari   =>  Atari makefile
+       makefile.beos    =>  BEOS makefile for X86
+       makefile.bor     =>  Borland makefile (uses bcc)
+       makefile.bc32    =>  32-bit Borland C++ (all modules compiled in C mode)
+       makefile.bd32    =>  To make a png32bd.dll with Borland C++ 4.5
+       makefile.tc3     =>  Turbo C 3.0 makefile
+       makefile.dj2     =>  DJGPP 2 makefile
+       makefile.msc     =>  Microsoft C makefile
+       makefile.vcawin32 => makefile for Microsoft Visual C++ 5.0 and
+                            later (uses assembler code tuned for Intel MMX
+                            platform)
+       makefile.vcwin32 =>  makefile for Microsoft Visual C++ 4.0 and
+                            later (does not use assembler code)
+       makefile.os2     =>  OS/2 Makefile (gcc and emx, requires pngos2.def)
+       pngos2.def       =>  OS/2 module definition file used by makefile.os2
+       makefile.watcom  =>  Watcom 10a+ Makefile, 32-bit flat memory model
+       makevms.com      =>  VMS build script
+       pngdef.pas       =>  Defines for a png32bd.dll with Borland C++ 4.5
+       SCOPTIONS.ppc    =>  Used with smakefile.ppc
 
 Good luck, and happy coding.
 
 -Glenn Randers-Pehrson
- Internet: randeg at alumni.rpi.edu
- Web: http://www.rpi.edu/~randeg/index.html
+ Internet: randeg at alum.rpi.edu
 
 -Andreas Eric Dilger
  Internet: adilger at enel.ucalgary.ca

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/libpngpf.3
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/libpngpf.3	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/libpngpf.3	Sat Jul 13 21:26:54 2002
@@ -1,339 +1,541 @@
-.TH LIBPNGPF 3 "January 14, 1999"
+.TH LIBPNGPF 3 "January 31, 2001"
 .SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.0.3 - January 14, 1999
+libpng \- Portable Network Graphics (PNG) Reference Library 1.0.9
 (private functions)
 .SH SYNOPSIS
-#include <png.h>
+\fB#include <png.h>\fP
 
-void png_build_gamma_table (png_structp png_ptr);
+\fI\fB
 
-void png_build_grayscale_palette (int bit_depth, png_colorp
-palette);
+\fBvoid png_build_gamma_table (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_calculate_crc (png_structp png_ptr, png_bytep ptr,
-png_size_t length);
-void png_check_chunk_name (png_structp png_ptr, png_bytep
-chunk_name);
+\fI\fB
 
-png_size_t png_check_keyword (png_structp png_ptr, png_charp
-key, png_charpp new_key);
+\fBvoid png_build_grayscale_palette (int \fP\fIbit_depth\fP\fB, png_colorp \fIpalette\fP\fB);\fP
 
-void png_combine_row (png_structp png_ptr, png_bytep row, int
-mask);
+\fI\fB
 
-void png_correct_palette (png_structp png_ptr, png_colorp
-palette, int num_palette);
+\fBvoid png_calculate_crc (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIptr\fP\fB, png_size_t \fIlength\fP\fB);\fP
 
-int png_crc_error (png_structp png_ptr);
+\fI\fB
 
-int png_crc_finish (png_structp png_ptr, png_uint_32 skip);
+\fBvoid png_check_chunk_name (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIchunk_name\fP\fB);\fP
 
-void png_crc_read (png_structp png_ptr, png_bytep buf,
-png_size_t length);
+\fI\fB
 
-png_voidp png_create_struct (int type, png_malloc_ptr malloc_fn);
+\fBpng_size_t png_check_keyword (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charpp \fInew_key\fP\fB);\fP
 
-png_voidp png_create_struct_2 (int type);
+\fI\fB
 
-void png_destroy_struct (png_voidp struct_ptr);
+\fBvoid png_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fImask\fP\fB);\fP
 
-void png_destroy_struct_2 (png_voidp struct_ptr, png_free_ptr
-free_fn);
+\fI\fB
 
-void png_do_background (png_row_infop row_info, png_bytep row,
-png_color_16p trans_values, png_color_16p background,
-png_color_16p background_1, png_bytep gamma_table, png_bytep
-gamma_from_1, png_bytep gamma_to_1, png_uint_16pp gamma_16,
-png_uint_16pp gamma_16_from_1, png_uint_16pp gamma_16_to_1, int
-gamma_shift);
+\fBvoid png_correct_palette (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP
 
-void png_do_bgr (png_row_infop row_info, png_bytep row);
+\fI\fB
 
-void png_do_chop (png_row_infop row_info, png_bytep row);
+\fBint png_crc_error (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_do_dither (png_row_infop row_info, png_bytep row,
-png_bytep palette_lookup, png_bytep dither_lookup);
+\fI\fB
 
-void png_do_expand (png_row_infop row_info, png_bytep row,
-png_color_16p trans_value);
+\fBint png_crc_finish (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIskip\fP\fB);\fP
 
-void png_do_expand_palette (png_row_infop row_info, png_bytep
-row, png_colorp palette, png_bytep trans, int num_trans);
+\fI\fB
 
-void png_do_gamma (png_row_infop row_info, png_bytep row,
-png_bytep gamma_table, png_uint_16pp gamma_16_table, int
-gamma_shift);
+\fBvoid png_crc_read (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuf\fP\fB, png_size_t \fIlength\fP\fB);\fP
 
-void png_do_gray_to_rgb (png_row_infop row_info, png_bytep
-row);
+\fI\fB
 
-void png_do_invert (png_row_infop row_info, png_bytep row);
+\fBpng_voidp png_create_struct (int \fP\fItype\fP\fB, png_malloc_ptr \fImalloc_fn\fP\fB);\fP
 
-void png_do_pack (png_row_infop row_info, png_bytep row,
-png_uint_32 bit_depth);
+\fI\fB
 
-void png_do_packswap (png_row_infop row_info, png_bytep row);
+\fBpng_voidp png_create_struct_2 (int \fItype\fP\fB);\fP
 
-void png_do_read_filler (png_row_infop row_info, png_bytep row,
-png_uint_32 filler, png_uint_32 flags);
+\fI\fB
 
-void png_do_read_interlace (png_row_infop row_info, png_bytep
-row, int pass, png_uint_32 transformations);
+\fBpng_charp png_decompress_chunk (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcomp_type\fP\fB, png_charp \fP\fIchunkdata\fP\fB, png_size_t \fP\fIchunklength\fP\fB, png_size_t \fP\fIprefix_length\fP\fB, png_size_t \fI*data_length\fP\fB);\fP
 
-void png_do_read_invert_alpha (png_row_infop row_info,
-png_bytep row);
+\fI\fB
 
-void png_do_read_swap_alpha (png_row_infop row_info, png_bytep
-row);
+\fBvoid png_destroy_struct (png_voidp \fIstruct_ptr\fP\fB);\fP
 
-void png_do_read_transformations (png_structp png_ptr);
+\fI\fB
 
-int png_do_rgb_to_gray (png_row_infop row_info, png_bytep
-row);
+\fBvoid png_destroy_struct_2 (png_voidp \fP\fIstruct_ptr\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
 
-void png_do_shift (png_row_infop row_info, png_bytep row,
-png_color_8p bit_depth);
+\fI\fB
 
-void png_do_strip_filler (png_row_infop row_info, png_bytep
-row, png_uint_32 flags);
+\fBvoid png_do_background (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_16p \fP\fItrans_values\fP\fB, png_color_16p \fP\fIbackground\fP\fB, png_color_16p \fP\fIbackground_1\fP\fB, png_bytep \fP\fIgamma_table\fP\fB, png_bytep \fP\fIgamma_from_1\fP\fB, png_bytep \fP\fIgamma_to_1\fP\fB, png_uint_16pp \fP\fIgamma_16\fP\fB, png_uint_16pp \fP\fIgamma_16_from_1\fP\fB, png_uint_16pp \fP\fIgamma_16_to_1\fP\fB, int \fIgamma_shift\fP\fB);\fP
 
-void png_do_swap (png_row_infop row_info, png_bytep row);
+\fI\fB
 
-void png_do_unpack (png_row_infop row_info, png_bytep row);
+\fBvoid png_do_bgr (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-void png_do_unshift (png_row_infop row_info, png_bytep row,
-png_color_8p sig_bits);
+\fI\fB
 
-void png_do_write_interlace (png_row_infop row_info, png_bytep
-row, int pass);
+\fBvoid png_do_chop (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-void png_do_write_invert_alpha (png_row_infop row_info,
-png_bytep row);
+\fI\fB
 
-void png_do_write_swap_alpha (png_row_infop row_info, png_bytep
-row);
+\fBvoid png_do_dither (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIpalette_lookup\fP\fB, png_bytep \fIdither_lookup\fP\fB);\fP
 
-void png_do_write_transformations (png_structp png_ptr);
+\fI\fB
 
-void *png_far_to_near (png_structp png_ptr,png_voidp ptr,
-int check);
+\fBvoid png_do_expand (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_16p \fItrans_value\fP\fB);\fP
 
-void png_flush (png_structp png_ptr);
+\fI\fB
 
-png_int_32 png_get_int_32 (png_bytep buf);
+\fBvoid png_do_expand_palette (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_colorp \fP\fIpalette\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fInum_trans\fP\fB);\fP
 
-png_uint_16 png_get_uint_16 (png_bytep buf);
+\fI\fB
 
-png_uint_32 png_get_uint_32 (png_bytep buf);
+\fBvoid png_do_gamma (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIgamma_table\fP\fB, png_uint_16pp \fP\fIgamma_16_table\fP\fB, int \fIgamma_shift\fP\fB);\fP
 
-void png_handle_bKGD (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_cHRM (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fBvoid png_do_gray_to_rgb (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-void png_handle_gAMA (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_hIST (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fBvoid png_do_invert (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-void png_handle_IEND (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_IHDR (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fBvoid png_do_pack (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fIbit_depth\fP\fB);\fP
 
-void png_handle_oFFs (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_pCAL (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fBvoid png_do_packswap (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-void png_handle_pHYs (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_PLTE (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fBvoid png_do_read_filler (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, png_uint_32 \fIflags\fP\fB);\fP
 
-void png_handle_sBIT (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_sRGB (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fBvoid png_do_read_interlace (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fP\fIpass\fP\fB, png_uint_32 \fItransformations\fP\fB);\fP
 
-void png_handle_tEXt (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_tIME (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fBvoid png_do_read_invert_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-void png_handle_tRNS (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_unknown (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 length);
+\fBvoid png_do_read_swap_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-void png_handle_zTXt (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_info_destroy (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_do_read_transformations (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_init_read_transformations (png_structp png_ptr);
+\fI\fB
 
-void png_process_IDAT_data (png_structp png_ptr, png_bytep
-buffer, png_size_t buffer_length);
+\fBint png_do_rgb_to_gray (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-void png_process_some_data (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-void png_push_check_crc (png_structp png_ptr);
+\fBvoid png_do_shift (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_8p \fIbit_depth\fP\fB);\fP
 
-void png_push_crc_finish (png_structp png_ptr);
+\fI\fB
 
-void png_push_crc_skip (png_structp png_ptr, png_uint_32
-length);
+\fBvoid png_do_strip_filler (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fIflags\fP\fB);\fP
 
-void png_push_fill_buffer (png_structp png_ptr, png_bytep
-buffer, png_size_t length);
+\fI\fB
 
-void png_push_handle_tEXt (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 length);
+\fBvoid png_do_swap (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-void png_push_handle_unknown (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 length);
+\fI\fB
 
-void png_push_handle_zTXt (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 length);
+\fBvoid png_do_unpack (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-void png_push_have_end (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-void png_push_have_info (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_do_unshift (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_8p \fIsig_bits\fP\fB);\fP
 
-void png_push_have_row (png_structp png_ptr, png_bytep row);
+\fI\fB
 
-void png_push_process_row (png_structp png_ptr);
+\fBvoid png_do_write_interlace (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fIpass\fP\fB);\fP
 
-void png_push_read_chunk (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-void png_push_read_end (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_do_write_invert_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-void png_push_read_IDAT (png_structp png_ptr);
+\fI\fB
 
-void png_push_read_sig (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_do_write_swap_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-void png_push_read_tEXt (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-void png_push_read_zTXt (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_do_write_transformations (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_push_restore_buffer (png_structp png_ptr, png_bytep
-buffer, png_size_t buffer_length);
+\fI\fB
 
-void png_push_save_buffer (png_structp png_ptr);
+\fBvoid *png_far_to_near (png_structp png_ptr,png_voidp \fP\fIptr\fP\fB, int \fIcheck\fP\fB);\fP
 
-void png_read_data (png_structp png_ptr, png_bytep data,
-png_size_t length);
+\fI\fB
 
-void png_read_filter_row (png_structp png_ptr, png_row_infop
-row_info, png_bytep row, png_bytep prev_row, int filter);
+\fBvoid png_flush (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_read_finish_row (png_structp png_ptr);
+\fI\fB
 
-void png_read_init (png_structp png_ptr);
+\fBpng_int_32 png_get_int_32 (png_bytep \fIbuf\fP\fB);\fP
 
-void png_read_push_finish_row (png_structp png_ptr);
+\fI\fB
 
-void png_read_start_row (png_structp png_ptr);
+\fBpng_uint_16 png_get_uint_16 (png_bytep \fIbuf\fP\fB);\fP
 
-void png_read_transform_info (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-void png_reset_crc (png_structp png_ptr);
+\fBpng_uint_32 png_get_uint_32 (png_bytep \fIbuf\fP\fB);\fP
 
-void png_save_int_32 (png_bytep buf, png_int_32 i);
+\fI\fB
 
-void png_save_uint_16 (png_bytep buf, unsigned int i);
+\fBint png_handle_as_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIchunk_name\fP\fB);\fP
 
-void png_save_uint_32 (png_bytep buf, png_uint_32 i);
+\fI\fB
 
-void png_write_bKGD (png_structp png_ptr, png_color_16p values,
-int color_type);
+\fBvoid png_handle_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_write_cHRM (png_structp png_ptr, double white_x,
-double white_y, double red_x, double red_y, double green_x,
-double green_y, double blue_x, double blue_y);
+\fI\fB
 
-void png_write_data (png_structp png_ptr, png_bytep data,
-png_size_t length);
-void png_write_filtered_row (png_structp png_ptr, png_bytep
-filtered_row);
+\fBvoid png_handle_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_write_find_filter (png_structp png_ptr, png_row_infop
-row_info);
+\fI\fB
 
-void png_write_finish_row (png_structp png_ptr);
+\fBvoid png_handle_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_write_gAMA (png_structp png_ptr, double file_gamma);
+\fI\fB
 
-void png_write_hIST (png_structp png_ptr, png_uint_16p hist,
-int num_hist);
+\fBvoid png_handle_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_write_init (png_structp png_ptr);
+\fI\fB
 
-void png_write_IDAT (png_structp png_ptr, png_bytep data,
-png_size_t length);
+\fBvoid png_handle_IEND (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_write_IEND (png_structp png_ptr);
+\fI\fB
 
-void png_write_IHDR (png_structp png_ptr, png_uint_32 width,
-png_uint_32 height, int bit_depth, int color_type, int
-compression_type, int filter_type, int interlace_type);
+\fBvoid png_handle_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_write_oFFs (png_structp png_ptr, png_uint_32 x_offset,
-png_uint_32 y_offset, int unit_type);
+\fI\fB
 
-void png_write_pCAL (png_structp png_ptr, png_charp purpose,
-png_int_32 X0, png_int_32 X1, int type, int nparams, png_charp
-units, png_charpp params);
+\fBvoid png_handle_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_write_pHYs (png_structp png_ptr, png_uint_32
-x_pixels_per_unit, png_uint_32 y_pixels_per_unit, int
-unit_type);
+\fI\fB
 
-void png_write_PLTE (png_structp png_ptr, png_colorp palette,
-png_uint_32 num_pal);
+\fBvoid png_handle_iTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_write_sBIT (png_structp png_ptr, png_color_8p sbit,
-int color_type);
+\fI\fB
 
-void png_write_sig (png_structp png_ptr);
+\fBvoid png_handle_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_write_sRGB (png_structp png_ptr, int intent);
+\fI\fB
 
-void png_write_start_row (png_structp png_ptr);
+\fBvoid png_handle_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_write_tEXt (png_structp png_ptr, png_charp key,
-png_charp text, png_size_t text_len);
+\fI\fB
 
-void png_write_tIME (png_structp png_ptr, png_timep mod_time);
+\fBvoid png_handle_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_write_tRNS (png_structp png_ptr, png_bytep trans,
-png_color_16p values, int number, int color_type);
+\fI\fB
 
-void png_write_zTXt (png_structp png_ptr, png_charp key,
-png_charp text, png_size_t text_len, int compression);
+\fBvoid png_handle_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-voidpf png_zalloc (voidpf png_ptr, uInt items, uInt size);
+\fI\fB
 
-void png_zfree (voidpf png_ptr, voidpf ptr);
+\fBvoid png_handle_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_info_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_init_read_transformations (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_process_IDAT_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_length\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_process_some_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_check_crc (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_crc_finish (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_crc_skip (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_fill_buffer (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_handle_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_handle_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_handle_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_have_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_have_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_have_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_process_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_read_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_read_IDAT (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_read_sig (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_read_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_read_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_restore_buffer (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_length\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_save_buffer (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_filter_row (png_structp \fP\fIpng_ptr\fP\fB, png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIprev_row\fP\fB, int \fIfilter\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_finish_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_push_finish_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_start_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_reset_crc (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_save_int_32 (png_bytep \fP\fIbuf\fP\fB, png_int_32 \fIi\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_save_uint_16 (png_bytep \fP\fIbuf\fP\fB, unsigned int \fIi\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_save_uint_32 (png_bytep \fP\fIbuf\fP\fB, png_uint_32 \fIi\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_color_16p \fP\fIvalues\fP\fB, int \fIcolor_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_cHRM (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIwhite_x\fP\fB, png_uint_32 \fP\fIwhite_y\fP\fB, png_uint_32 \fP\fIred_x\fP\fB, png_uint_32 \fP\fIred_y\fP\fB, png_uint_32 \fP\fIgreen_x\fP\fB, png_uint_32 \fP\fIgreen_y\fP\fB, png_uint_32 \fP\fIblue_x\fP\fB, png_uint_32 \fIblue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fBvoid png_write_filtered_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIfiltered_row\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_find_filter (png_structp \fP\fIpng_ptr\fP\fB, png_row_infop \fIrow_info\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_finish_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_gAMA (png_structp \fP\fIpng_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIint_file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_uint_16p \fP\fIhist\fP\fB, int \fInum_hist\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_charp \fP\fIprofile\fP\fB, int \fIproflen\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_IDAT (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_IEND (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fP\fIfilter_type\fP\fB, int \fIinterlace_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_iTXt (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcompression\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fIlang\fP\fB, png_charp \fP\fItranslated_key\fP\fB, png_charp \fItext)\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIx_offset\fP\fB, png_uint_32 \fP\fIy_offset\fP\fB, int \fIunit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIx_pixels_per_unit\fP\fB, png_uint_32 \fP\fIy_pixels_per_unit\fP\fB, int \fIunit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, png_uint_32 \fInum_pal\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fP\fIsbit\fP\fB, int \fIcolor_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, double \fP\fIwidth\fP\fB, double \fIheight\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_sCAL_s (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, png_charp \fP\fIwidth\fP\fB, png_charp \fIheight\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_sig (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_sRGB (png_structp \fP\fIpng_ptr\fP\fB, int \fIintent\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_spalette_p \fIpalette\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_start_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fItext\fP\fB, png_size_t \fItext_len\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, png_color_16p \fP\fIvalues\fP\fB, int \fP\fInumber\fP\fB, int \fIcolor_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fItext\fP\fB, png_size_t \fP\fItext_len\fP\fB, int \fIcompression\fP\fB);\fP
+
+\fI\fB
+
+\fBvoidpf png_zalloc (voidpf \fP\fIpng_ptr\fP\fB, uInt \fP\fIitems\fP\fB, uInt \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_zfree (voidpf \fP\fIpng_ptr\fP\fB, voidpf \fIptr\fP\fB);\fP
+
+\fI\fB
 
 .SH DESCRIPTION
 The functions listed above are used privately by libpng

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/TODO
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/TODO	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/TODO	Sat Jul 13 21:26:55 2002
@@ -1,16 +1,13 @@
 TODO - list of things to do for libpng:
 
 Final bug fixes.
-Fix problem with C++ and EXTERN "C".
+Improve API by hiding the png_struct and png_info structs.
+Finish work on the no-floating-point version (including gamma compensation)
 Better C++ wrapper/full C++ implementation?
-Keep up with public chunks.
-sPLT chunk handling.
+Fix problem with C++ and EXTERN "C".
 cHRM transformation.
-Support for application-defined chunk handlers.
 Improve setjmp/longjmp usage or remove it in favor of returning error codes.
-High-level API for reading images.
 Add "grayscale->palette" transformation and "palette->grayscale" detection.
-Color to gray transformation.
 Improved dithering.
 Multi-lingual error and warning message support.
 Complete sRGB transformation (presently it simply uses gamma=0.45455).
@@ -18,7 +15,10 @@
 Better documentation.
 Better filter selection
    (counting huffman bits/precompression?  filter inertia?  filter costs?).
-Optional palette (sPLT) creation.
 Histogram creation.
 Text conversion between different code pages (Latin-1 -> Mac and DOS).
-Improve API by hiding the info_ptr.
+Should we always malloc 2^bit_depth PLTE/tRNS/hIST entries for safety?
+Build gamma tables using fixed point (and do away with floating point entirely).
+Use greater precision when changing to linear gamma for compositing against
+  background and doing rgb-to-gray transformation.
+Investigate pre-incremented loop counters and other loop constructions.

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/ANNOUNCE
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/ANNOUNCE	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/ANNOUNCE	Sat Jul 13 21:26:55 2002
@@ -1,53 +1,60 @@
 
-Libpng 1.0.3 - January 14, 1999
+Libpng 1.0.9 - January 31, 2001
 
 This is a public release of libpng, intended for use in production codes.
 
-Changes since the previous public release (1.0.2):
+Changes since the last public release (1.0.8):
 
-libpng-1.0.3:
-
-  Replaced and extended code that was removed from png_set_filler() in 1.0.1a.
-  Fixed a bug in png_do_filler() that made it fail to write filler bytes in
-    the left-most pixel of each row (Kevin Bracey).
-  Changed "static pngcharp tIME_string" to "static char tIME_string[30]"
-    in pngtest.c (Duncan Simpson).
-  Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk
-    even when no tIME chunk was present in the source file.
-  Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit.
-  Fixed a problem in png_read_push_finish_row(), which would not skip some
-    passes that it should skip, for images that are less than 3 pixels high.
-  Interchanged the order of calls to png_do_swap() and png_do_shift()
-    in pngwtran.c (John Cromer).
-  Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h .
-  Changed "bad adaptive filter type" from error to warning in pngrutil.c .
-  Fixed a documentation error about default filtering with 8-bit indexed-color.
-  Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO
-    (L. Peter Deutsch).
-  Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions.
-  Added png_get_copyright() and png_get_header_version() functions.
-  Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c
-  Added information about debugging in libpng.txt and libpng.3 .
-  Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and makefile.sco.
-  Removed lines after Dynamic Dependencies" in makefile.aco .
-  Revised makefile.dec to make a shared library (Jeremie Petit).
-  Removed trailing blanks from all files. 
-  Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h
-  Added "if" tests to silence complaints about unused png_ptr in png.h and png.c
-  Changed "check_if_png" function in example.c to return true (nonzero) if PNG.
-  Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig()
-    which is obsolete.
-  Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice)
-  Added a statement of Y2K compliance in png.h, libpng.1, and Y2KINFO.
+  Fixed typo in scripts/makefile.hpux
+  Fixed seqence-point bug in contrib/pngminus/png2pnm (Martin Zinser)
+  Updated makevms.com in scripts and contrib/* and contrib/* (Martin Zinser)
+  Changed "cdrom.com" in documentation to "libpng.org"
+  Revised pnggccrd.c to get it all working, and updated makefile.gcmmx (Greg).
+  Changed type of "params" from voidp to png_voidp in png_read|write_png().
+  Added MNG_EXTENSIONS_SUPPORTED macro and support for some proposed MNG
+     features, for testing purposes.
+  Make sure PNGAPI and PNG_IMPEXP are defined in pngconf.h.
+  Revised the 3 instances of WRITEFILE in pngtest.c.
+  Updated png.rc in dll/msvc project
+  Revised makefile.dec to define and use LIBPATH and INCPATH
+  Increased size of global png_libpng_ver[] array from 12 to 18 chars.
+  Made global png_libpng_ver[], png_sig[] and png_pass_*[] arrays const.
+  Removed duplicate png_crc_finish() from png_handle_bKGD() function.
+  Added a warning when application calls png_read_update_info() multiple times.
+  Revised makefile.cygwin
+  Fixed bugs in iCCP support in pngrutil.c and pngwutil.c.
+  Replaced png_set_empty_plte_permitted() with png_permit_mng_features().
+  Relocated "msvc" and "wince" project subdirectories into "projects"
+    subdirectory and added projects/borland project subdirectory.
+  Set VS_FF_PRERELEASE and VS_FF_PATCHED flags in msvc/png.rc when appropriate.
+  Add error message in png_set_compression_buffer_size() when malloc fails.
+  Revised PNG_LIBPNG_BUILD_TYPE macro in png.h, used in the msvc project.
+  Removed the png_flush() in pngwrite.c that crashes some applications
+    that don't set png_output_flush_fn.
+  Added makefile.macosx and makefile.aix to scripts directory.
+  Change png_chunk_warning to png_warning in png_check_keyword().
+  Increased the first part of msg buffer from 16 to 18 in png_chunk_error().
+  Added support for filter method 64 (for PNG datastreams embedded in MNG)
+  Revised png_set_filter() to accept filter method 64 when appropriate.
+  Added new PNG_HAVE_PNG_SIGNATURE bit to png_ptr->mode and use it to
+    help prevent applications from using MNG features in PNG datastreams.
+  Revised libpng.3/libpng.txt.  Changed "filter type" to "filter method".
+  Fixed error handling of unknown compression type in png_decompress_chunk().
+  In pngconf.h, define __cdecl when _MSC_VER is defined.
+  Changed PNG_TEXT_COMPRESSION_zTXt to PNG_COMPRESSION_TYPE_BASE several places.
+  Revised memory management in png_set_hIST and png_handle_hIST in a backward
+    compatible manner.  PLTE and tRNS were revised similarly.
+  Revised the iCCP chunk reader to ignore trailing garbage.
+  Moved pngasmrd.h into pngconf.h.
+  Improved handling of out-of-spec garbage iCCP chunks generated by PhotoShop.
+  Added png_set_invalid to wince and msvc project module definition files.
+  Fixed bug with progressive reading of narrow interlaced images in pngpread.c
+  Do not typedef png_FILE_io in pngconf.h when PNG_NO_STDIO is defined.
+  Updated makefile.sgi to make shared library.
+  Added check of cygwin's ALL_STATIC in pngconf.h
+  Added "-nommx" parameter to contrib/gregbook/rpng2-win and rpng2-x demos.
 
 Send comments/corrections/commendations to
-png-implement at dworkin.wustl.edu or to randeg at alumni.rpi.edu
+png-implement at ccrc.wustl.edu or to randeg at alum.rpi.edu
 
 Glenn R-P
-
-Send comments/corrections/commendations to
-png-implement at dworkin.wustl.edu or to randeg at alumni.rpi.edu
-
-Glenn Randers-Pehrson
-libpng maintainer
-PNG Development Group

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/Makefile.am
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/Makefile.am	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/Makefile.am	Sat Jul 13 21:26:56 2002
@@ -1,17 +1,12 @@
 ## Process this file with automake to produce Makefile.in
 
-#AUTOMAKE_OPTIONS        = foreign
-
-# where we keep local rules for automake
-#ACLOCAL_M4 = $(top_srcdir)/config/aclocal.m4
-#AUTOHEADER = @AUTOHEADER@ --localdir=$(top_srcdir)/config
-
 ZLIB_LIB_DIR = @ZLIB_LIB_DIR@
 
 INCLUDES = -I$(top_srcdir)/$(ZLIB_LIB_DIR)
 
-EXTRA_DIST= ANNOUNCE CHANGES INSTALL KNOWNBUG README README.rrdtool TODO Y2KINFO example.c libpng.3\
-		libpng.txt libpngpf.3 png.5 png.dsp png.dsw 
+EXTRA_DIST= ANNOUNCE CHANGES INSTALL KNOWNBUG README README.rrdtool \
+            TODO Y2KINFO example.c libpng.3 \
+    	    libpng.txt libpngpf.3 png.5 png.dsp png.dsw 
 
 noinst_LTLIBRARIES = librrd_png.la
 

Modified: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngrtran.c
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngrtran.c	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/pngrtran.c	Sat Jul 13 21:26:56 2002
@@ -1,11 +1,11 @@
 
 /* pngrtran.c - transforms the data in a row for PNG readers
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.9 - January 31, 2001
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2001 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This file contains functions optionally called by an application
  * in order to tell libpng how to handle data when reading a PNG.
@@ -17,7 +17,7 @@
 #include "png.h"
 
 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
-void
+void PNGAPI
 png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
 {
    png_debug(1, "in png_set_crc_action\n");
@@ -69,9 +69,10 @@
    }
 }
 
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+    defined(PNG_FLOATING_POINT_SUPPORTED)
 /* handle alpha and tRNS via a background color */
-void
+void PNGAPI
 png_set_background(png_structp png_ptr,
    png_color_16p background_color, int background_gamma_code,
    int need_expand, double background_gamma)
@@ -92,19 +93,19 @@
    /* Note:  if need_expand is set and color_type is either RGB or RGB_ALPHA
     * (in which case need_expand is superfluous anyway), the background color
     * might actually be gray yet not be flagged as such. This is not a problem
-    * for the current code, which uses PNG_FLAG_BACKGROUND_IS_GRAY only to
+    * for the current code, which uses PNG_BACKGROUND_IS_GRAY only to
     * decide when to do the png_do_gray_to_rgb() transformation.
     */
    if ((need_expand && !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) ||
        (!need_expand && background_color->red == background_color->green &&
         background_color->red == background_color->blue))
-      png_ptr->flags |= PNG_FLAG_BACKGROUND_IS_GRAY;
+      png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
 }
 #endif
 
 #if defined(PNG_READ_16_TO_8_SUPPORTED)
 /* strip 16 bit depth files to 8 bit depth */
-void
+void PNGAPI
 png_set_strip_16(png_structp png_ptr)
 {
    png_debug(1, "in png_set_strip_16\n");
@@ -113,7 +114,7 @@
 #endif
 
 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
-void
+void PNGAPI
 png_set_strip_alpha(png_structp png_ptr)
 {
    png_debug(1, "in png_set_strip_alpha\n");
@@ -140,7 +141,7 @@
 typedef png_dsort FAR *       png_dsortp;
 typedef png_dsort FAR * FAR * png_dsortpp;
 
-void
+void PNGAPI
 png_set_dither(png_structp png_ptr, png_colorp palette,
    int num_palette, int maximum_colors, png_uint_16p histogram,
    int full_dither)
@@ -366,7 +367,7 @@
                      {
                         int j, next_j;
 
-                        if (num_new_palette & 1)
+                        if (num_new_palette & 0x01)
                         {
                            j = p->left;
                            next_j = p->right;
@@ -504,13 +505,13 @@
 }
 #endif
 
-#if defined(PNG_READ_GAMMA_SUPPORTED)
+#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
 /* Transform the image from the file_gamma to the screen_gamma.  We
  * only do transformations on images where the file_gamma and screen_gamma
  * are not close reciprocals, otherwise it slows things down slightly, and
  * also needlessly introduces small errors.
  */
-void
+void PNGAPI
 png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
 {
    png_debug(1, "in png_set_gamma\n");
@@ -522,20 +523,58 @@
 #endif
 
 #if defined(PNG_READ_EXPAND_SUPPORTED)
-/* Expand paletted images to rgb, expand grayscale images of
- * less than 8 bit depth to 8 bit depth, and expand tRNS chunks
+/* Expand paletted images to RGB, expand grayscale images of
+ * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
  * to alpha channels.
  */
-void
+void PNGAPI
 png_set_expand(png_structp png_ptr)
 {
    png_debug(1, "in png_set_expand\n");
    png_ptr->transformations |= PNG_EXPAND;
 }
-#endif
+
+/* GRR 19990627:  the following three functions currently are identical
+ *  to png_set_expand().  However, it is entirely reasonable that someone
+ *  might wish to expand an indexed image to RGB but *not* expand a single,
+ *  fully transparent palette entry to a full alpha channel--perhaps instead
+ *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
+ *  the transparent color with a particular RGB value, or drop tRNS entirely.
+ *  IOW, a future version of the library may make the transformations flag
+ *  a bit more fine-grained, with separate bits for each of these three
+ *  functions.
+ *
+ *  More to the point, these functions make it obvious what libpng will be
+ *  doing, whereas "expand" can (and does) mean any number of things.
+ */
+
+/* Expand paletted images to RGB. */
+void PNGAPI
+png_set_palette_to_rgb(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_expand\n");
+   png_ptr->transformations |= PNG_EXPAND;
+}
+
+/* Expand grayscale images of less than 8-bit depth to 8 bits. */
+void PNGAPI
+png_set_gray_1_2_4_to_8(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_expand\n");
+   png_ptr->transformations |= PNG_EXPAND;
+}
+
+/* Expand tRNS chunks to alpha channels. */
+void PNGAPI
+png_set_tRNS_to_alpha(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_expand\n");
+   png_ptr->transformations |= PNG_EXPAND;
+}
+#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
 
 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
-void
+void PNGAPI
 png_set_gray_to_rgb(png_structp png_ptr)
 {
    png_debug(1, "in png_set_gray_to_rgb\n");
@@ -544,12 +583,24 @@
 #endif
 
 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+#if defined(PNG_FLOATING_POINT_SUPPORTED)
 /* Convert a RGB image to a grayscale of the same width.  This allows us,
  * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
  */
-void
-png_set_rgb_to_gray(png_structp png_ptr, int error_action, float red,
-  float green)
+
+void PNGAPI
+png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
+   double green)
+{
+      int red_fixed = (int)((float)red*100000.0 + 0.5);
+      int green_fixed = (int)((float)green*100000.0 + 0.5);
+      png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
+}
+#endif
+
+void PNGAPI
+png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
+   png_fixed_point red, png_fixed_point green)
 {
    png_debug(1, "in png_set_rgb_to_gray\n");
    switch(error_action)
@@ -570,41 +621,54 @@
    }
 #endif
    {
-      png_byte red_byte = (png_byte)(red*255.0 + 0.5);
-      png_byte green_byte = (png_byte)(green*255.0 + 0.5);
-      if(red < 0.0 || green < 0.0)
+      png_uint_16 red_int, green_int;
+      if(red < 0 || green < 0)
+      {
+         red_int   =  6968; /* .212671 * 32768 + .5 */
+         green_int = 23434; /* .715160 * 32768 + .5 */
+      }
+      else if(red + green < 100000L)
       {
-         red_byte = 54;
-         green_byte = 183;
+        red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
+        green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
       }
-      else if(red_byte + green_byte > 255)
+      else
       {
          png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
-         red_byte = 54;
-         green_byte = 183;
+         red_int   =  6968;
+         green_int = 23434;
       }
-      png_ptr->rgb_to_gray_red_coeff   = red_byte;
-      png_ptr->rgb_to_gray_green_coeff = green_byte;
-      png_ptr->rgb_to_gray_blue_coeff  = 255 - red_byte - green_byte;
+      png_ptr->rgb_to_gray_red_coeff   = red_int;
+      png_ptr->rgb_to_gray_green_coeff = green_int;
+      png_ptr->rgb_to_gray_blue_coeff  = (png_uint_16)(32768-red_int-green_int);
    }
 }
 #endif
 
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
-void
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
+void PNGAPI
 png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
    read_user_transform_fn)
 {
    png_debug(1, "in png_set_read_user_transform_fn\n");
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
    png_ptr->transformations |= PNG_USER_TRANSFORM;
    png_ptr->read_user_transform_fn = read_user_transform_fn;
+#endif
+#ifdef PNG_LEGACY_SUPPORTED
+   if(read_user_transform_fn)
+      png_warning(png_ptr,
+        "This version of libpng does not support user transforms");
+#endif
 }
 #endif
 
 /* Initialize everything needed for the read.  This includes modifying
  * the palette.
  */
-void
+void /* PRIVATE */
 png_init_read_transformations(png_structp png_ptr)
 {
    png_debug(1, "in png_init_read_transformations\n");
@@ -618,7 +682,8 @@
 #endif
 
 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
-   if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)
+   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+       (png_ptr->transformations & PNG_EXPAND))
    {
       if (!(color_type & PNG_COLOR_MASK_COLOR))  /* i.e., GRAY or GRAY_ALPHA */
       {
@@ -668,7 +733,7 @@
               int i,istop;
               istop=(int)png_ptr->num_trans;
               for (i=0; i<istop; i++)
-                 png_ptr->trans[i] = 255 - png_ptr->trans[i];
+                 png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
            }
         }
 #endif
@@ -680,7 +745,7 @@
 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
    png_ptr->background_1 = png_ptr->background;
 #endif
-#if defined(PNG_READ_GAMMA_SUPPORTED)
+#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
    if (png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY))
    {
       png_build_gamma_table(png_ptr);
@@ -693,7 +758,6 @@
             png_colorp palette = png_ptr->palette;
             int num_palette = png_ptr->num_palette;
             int i;
-
             if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
             {
                back.red = png_ptr->gamma_table[png_ptr->background.red];
@@ -751,7 +815,6 @@
                back_1.blue = (png_byte)(pow(
                   (double)png_ptr->background.blue/255, g) * 255.0 + .5);
             }
-
             for (i = 0; i < num_palette; i++)
             {
                if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
@@ -859,8 +922,8 @@
 #endif
 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
    /* No GAMMA transformation */
-   if (png_ptr->transformations & PNG_BACKGROUND &&
-       color_type == PNG_COLOR_TYPE_PALETTE)
+   if ((png_ptr->transformations & PNG_BACKGROUND) &&
+       (color_type == PNG_COLOR_TYPE_PALETTE))
    {
       int i;
       int istop = (int)png_ptr->num_trans;
@@ -893,7 +956,7 @@
 
 #if defined(PNG_READ_SHIFT_SUPPORTED)
    if ((png_ptr->transformations & PNG_SHIFT) &&
-      color_type == PNG_COLOR_TYPE_PALETTE)
+      (color_type == PNG_COLOR_TYPE_PALETTE))
    {
       png_uint_16 i;
       png_uint_16 istop = png_ptr->num_palette;
@@ -916,13 +979,18 @@
    }
 #endif
  }
+#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
+ && !defined(PNG_READ_BACKGROUND_SUPPORTED)
+   if(png_ptr)
+      return;
+#endif
 }
 
 /* Modify the info structure to reflect the transformations.  The
  * info should be updated so a PNG file could be written with it,
  * assuming the transformations result in valid PNG data.
  */
-void
+void /* PRIVATE */
 png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
 {
    png_debug(1, "in png_read_transform_info\n");
@@ -960,11 +1028,18 @@
 
 #if defined(PNG_READ_GAMMA_SUPPORTED)
    if (png_ptr->transformations & PNG_GAMMA)
+   {
+#ifdef PNG_FLOATING_POINT_SUPPORTED
       info_ptr->gamma = png_ptr->gamma;
 #endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+      info_ptr->int_gamma = png_ptr->int_gamma;
+#endif
+   }
+#endif
 
 #if defined(PNG_READ_16_TO_8_SUPPORTED)
-   if ((png_ptr->transformations & PNG_16_TO_8) && info_ptr->bit_depth == 16)
+   if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
       info_ptr->bit_depth = 8;
 #endif
 
@@ -981,7 +1056,7 @@
 #endif
 
 #if defined(PNG_READ_PACK_SUPPORTED)
-   if ((png_ptr->transformations & PNG_PACK) && info_ptr->bit_depth < 8)
+   if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
       info_ptr->bit_depth = 8;
 #endif
 
@@ -1012,29 +1087,50 @@
 
 #if defined(PNG_READ_FILLER_SUPPORTED)
    /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
-   if (png_ptr->transformations & PNG_FILLER &&
-       (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
-        info_ptr->color_type == PNG_COLOR_TYPE_GRAY))
-      ++info_ptr->channels;
+   if ((png_ptr->transformations & PNG_FILLER) &&
+       ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+       (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
+   {
+      info_ptr->channels++;
+#if 0 /* if adding a true alpha channel not just filler */
+      info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+#endif
+   }
+#endif
+
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
+defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+   if(png_ptr->transformations & PNG_USER_TRANSFORM)
+     {
+       if(info_ptr->bit_depth < png_ptr->user_transform_depth)
+         info_ptr->bit_depth = png_ptr->user_transform_depth;
+       if(info_ptr->channels < png_ptr->user_transform_channels)
+         info_ptr->channels = png_ptr->user_transform_channels;
+     }
 #endif
 
    info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
       info_ptr->bit_depth);
    info_ptr->rowbytes = ((info_ptr->width * info_ptr->pixel_depth + 7) >> 3);
+
+#if !defined(PNG_READ_EXPAND_SUPPORTED)
+   if(png_ptr)
+      return;
+#endif
 }
 
 /* Transform the row.  The order of transformations is significant,
  * and is very touchy.  If you add a transformation, take care to
  * decide how it fits in with the other transformations here.
  */
-void
+void /* PRIVATE */
 png_do_read_transformations(png_structp png_ptr)
 {
    png_debug(1, "in png_do_read_transformations\n");
 #if !defined(PNG_USELESS_TESTS_SUPPORTED)
    if (png_ptr->row_buf == NULL)
    {
-#if !defined(PNG_NO_STDIO)
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
       char msg[50];
 
       sprintf(msg, "NULL row buffer for row %ld, pass %d", png_ptr->row_number,
@@ -1121,8 +1217,8 @@
 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
    /* if gray -> RGB, do so now only if background is non-gray; else do later
     * for performance reasons */
-   if (png_ptr->transformations & PNG_GRAY_TO_RGB &&
-       !(png_ptr->flags & PNG_FLAG_BACKGROUND_IS_GRAY))
+   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+       !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
       png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
 #endif
 
@@ -1195,8 +1291,8 @@
 
 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
    /* if gray -> RGB, do so now only if we did not do so above */
-   if (png_ptr->transformations & PNG_GRAY_TO_RGB &&
-       png_ptr->flags & PNG_FLAG_BACKGROUND_IS_GRAY)
+   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
       png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
 #endif
 
@@ -1223,6 +1319,7 @@
 
 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
    if (png_ptr->transformations & PNG_USER_TRANSFORM)
+    {
       if(png_ptr->read_user_transform_fn != NULL)
         (*(png_ptr->read_user_transform_fn)) /* user read transform function */
           (png_ptr,                    /* png_ptr */
@@ -1234,6 +1331,17 @@
              /*  png_byte channels;          number of channels (1-4) */
              /*  png_byte pixel_depth;       bits per pixel (depth*channels) */
            png_ptr->row_buf + 1);      /* start of pixel data for row */
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+      if(png_ptr->user_transform_depth)
+         png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
+      if(png_ptr->user_transform_channels)
+         png_ptr->row_info.channels = png_ptr->user_transform_channels;
+#endif
+      png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
+         png_ptr->row_info.channels);
+      png_ptr->row_info.rowbytes = (png_ptr->row_info.width *
+         png_ptr->row_info.pixel_depth+7)>>3;
+   }
 #endif
 
 }
@@ -1245,7 +1353,7 @@
  * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
  * png_do_shift() after this.
  */
-void
+void /* PRIVATE */
 png_do_unpack(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_unpack\n");
@@ -1264,10 +1372,10 @@
          {
             png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
             png_bytep dp = row + (png_size_t)row_width - 1;
-            png_uint_32 shift = 7 - (int)((row_width + 7) & 7);
+            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
             for (i = 0; i < row_width; i++)
             {
-               *dp = (png_byte)((*sp >> shift) & 0x1);
+               *dp = (png_byte)((*sp >> shift) & 0x01);
                if (shift == 7)
                {
                   shift = 0;
@@ -1285,10 +1393,10 @@
 
             png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
             png_bytep dp = row + (png_size_t)row_width - 1;
-            png_uint_32 shift = (int)((3 - ((row_width + 3) & 3)) << 1);
+            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
             for (i = 0; i < row_width; i++)
             {
-               *dp = (png_byte)((*sp >> shift) & 0x3);
+               *dp = (png_byte)((*sp >> shift) & 0x03);
                if (shift == 6)
                {
                   shift = 0;
@@ -1305,10 +1413,10 @@
          {
             png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
             png_bytep dp = row + (png_size_t)row_width - 1;
-            png_uint_32 shift = (int)((1 - ((row_width + 1) & 1)) << 2);
+            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
             for (i = 0; i < row_width; i++)
             {
-               *dp = (png_byte)((*sp >> shift) & 0xf);
+               *dp = (png_byte)((*sp >> shift) & 0x0f);
                if (shift == 4)
                {
                   shift = 0;
@@ -1335,7 +1443,7 @@
  * a row of bit depth 8, but only 5 are significant, this will shift
  * the values back to 0 through 31.
  */
-void
+void /* PRIVATE */
 png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
 {
    png_debug(1, "in png_do_unshift\n");
@@ -1397,8 +1505,8 @@
             png_bytep bp = row;
             png_uint_32 i;
             png_uint_32 istop = row_info->rowbytes;
-            png_byte mask = (png_byte)(((int)0xf0 >> shift[0]) & (int)0xf0) |
-               (png_byte)((int)0xf >> shift[0]);
+            png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
+               (png_byte)((int)0xf >> shift[0]));
 
             for (i = 0; i < istop; i++)
             {
@@ -1441,7 +1549,7 @@
 
 #if defined(PNG_READ_16_TO_8_SUPPORTED)
 /* chop rows of bit depth 16 down to 8 */
-void
+void /* PRIVATE */
 png_do_chop(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_chop\n");
@@ -1495,7 +1603,7 @@
 #endif
 
 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
-void
+void /* PRIVATE */
 png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_read_swap_alpha\n");
@@ -1587,7 +1695,7 @@
 #endif
 
 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
-void
+void /* PRIVATE */
 png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_read_invert_alpha\n");
@@ -1607,10 +1715,16 @@
 
             for (i = 0; i < row_width; i++)
             {
-               *(--dp) = 255 - *(--sp);
+               *(--dp) = (png_byte)(255 - *(--sp));
+
+/*             This does nothing:
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
+               We can replace it with:
+*/
+               sp-=3;
+               dp=sp;
             }
          }
          /* This inverts the alpha channel in RRGGBBAA */
@@ -1622,14 +1736,20 @@
 
             for (i = 0; i < row_width; i++)
             {
-               *(--dp) = 255 - *(--sp);
-               *(--dp) = 255 - *(--sp);
+               *(--dp) = (png_byte)(255 - *(--sp));
+               *(--dp) = (png_byte)(255 - *(--sp));
+
+/*             This does nothing:
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
+               We can replace it with:
+*/
+               sp-=6;
+               dp=sp;
             }
          }
       }
@@ -1644,7 +1764,7 @@
 
             for (i = 0; i < row_width; i++)
             {
-               *(--dp) = 255 - *(--sp);
+               *(--dp) = (png_byte)(255 - *(--sp));
                *(--dp) = *(--sp);
             }
          }
@@ -1657,10 +1777,14 @@
 
             for (i = 0; i < row_width; i++)
             {
-               *(--dp) = 255 - *(--sp);
-               *(--dp) = 255 - *(--sp);
+               *(--dp) = (png_byte)(255 - *(--sp));
+               *(--dp) = (png_byte)(255 - *(--sp));
+/*
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
+*/
+               sp-=2;
+               dp=sp;
             }
          }
       }
@@ -1670,7 +1794,7 @@
 
 #if defined(PNG_READ_FILLER_SUPPORTED)
 /* Add filler channel if we have RGB color */
-void
+void /* PRIVATE */
 png_do_read_filler(png_row_infop row_info, png_bytep row,
    png_uint_32 filler, png_uint_32 flags)
 {
@@ -1737,7 +1861,7 @@
             *(--dp) = lo_filler;
             row_info->channels = 2;
             row_info->pixel_depth = 32;
-            row_info->rowbytes = row_width * 2;
+            row_info->rowbytes = row_width * 4;
          }
          /* This changes the data from GG to XXGG */
          else
@@ -1752,8 +1876,8 @@
                *(--dp) = lo_filler;
             }
             row_info->channels = 2;
-            row_info->pixel_depth = 16;
-            row_info->rowbytes = row_width * 2;
+            row_info->pixel_depth = 32;
+            row_info->rowbytes = row_width * 4;
          }
       }
    } /* COLOR_TYPE == GRAY */
@@ -1817,7 +1941,7 @@
             *(--dp) = lo_filler;
             row_info->channels = 4;
             row_info->pixel_depth = 64;
-            row_info->rowbytes = row_width * 4;
+            row_info->rowbytes = row_width * 8;
          }
          /* This changes the data from RRGGBB to XXRRGGBB */
          else
@@ -1837,7 +1961,7 @@
             }
             row_info->channels = 4;
             row_info->pixel_depth = 64;
-            row_info->rowbytes = row_width * 4;
+            row_info->rowbytes = row_width * 8;
          }
       }
    } /* COLOR_TYPE == RGB */
@@ -1846,7 +1970,7 @@
 
 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
 /* expand grayscale files to RGB, with or without alpha */
-void
+void /* PRIVATE */
 png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
 {
    png_uint_32 i;
@@ -1869,8 +1993,7 @@
             {
                *(dp--) = *sp;
                *(dp--) = *sp;
-               *(dp--) = *sp;
-               sp--;
+               *(dp--) = *(sp--);
             }
          }
          else
@@ -1883,10 +2006,8 @@
                *(dp--) = *(sp - 1);
                *(dp--) = *sp;
                *(dp--) = *(sp - 1);
-               *(dp--) = *sp;
-               *(dp--) = *(sp - 1);
-               sp--;
-               sp--;
+               *(dp--) = *(sp--);
+               *(dp--) = *(sp--);
             }
          }
       }
@@ -1901,8 +2022,7 @@
                *(dp--) = *(sp--);
                *(dp--) = *sp;
                *(dp--) = *sp;
-               *(dp--) = *sp;
-               sp--;
+               *(dp--) = *(sp--);
             }
          }
          else
@@ -1917,10 +2037,8 @@
                *(dp--) = *(sp - 1);
                *(dp--) = *sp;
                *(dp--) = *(sp - 1);
-               *(dp--) = *sp;
-               *(dp--) = *(sp - 1);
-               sp--;
-               sp--;
+               *(dp--) = *(sp--);
+               *(dp--) = *(sp--);
             }
          }
       }
@@ -1935,7 +2053,7 @@
 #endif
 
 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-/* reduce RGB files to grayscale, with or without alpha 
+/* reduce RGB files to grayscale, with or without alpha
  * using the equation given in Poynton's ColorFAQ at
  * <http://www.inforamp.net/~poynton/>
  * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net
@@ -1943,18 +2061,18 @@
  *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
  *
  *  We approximate this with
- * 
- *     Y = 0.211 * R    + 0.715 * G    + 0.074 * B
+ *
+ *     Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
  *
  *  which can be expressed with integers as
  *
- *     Y = (54 * R + 183 * G + 19 * B)/256
+ *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
  *
  *  The calculation is to be done in a linear colorspace.
  *
  *  Other integer coefficents can be used via png_set_rgb_to_gray().
  */
-int
+int /* PRIVATE */
 png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
 
 {
@@ -1970,9 +2088,9 @@
 #endif
       (row_info->color_type & PNG_COLOR_MASK_COLOR))
    {
-      png_byte rc = png_ptr->rgb_to_gray_red_coeff;
-      png_byte gc = png_ptr->rgb_to_gray_green_coeff;
-      png_byte bc = png_ptr->rgb_to_gray_blue_coeff;
+      png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
+      png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
+      png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
 
       if (row_info->color_type == PNG_COLOR_TYPE_RGB)
       {
@@ -1993,7 +2111,7 @@
                   {
                      rgb_error |= 1;
                      *(dp++) = png_ptr->gamma_from_1[
-                       (rc*red+gc*green+bc*blue)>>8];
+                       (rc*red+gc*green+bc*blue)>>15];
                   }
                   else
                      *(dp++) = *(sp-1);
@@ -2012,14 +2130,14 @@
                   if(red != green || red != blue)
                   {
                      rgb_error |= 1;
-                     *(dp++) = (rc*red+gc*green+bc*blue)>>8;
+                     *(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15);
                   }
                   else
                      *(dp++) = *(sp-1);
                }
             }
          }
- 
+
          else /* RGB bit_depth == 16 */
          {
 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
@@ -2032,9 +2150,9 @@
                {
                   png_uint_16 red, green, blue, w;
 
-                  red   = ((*(sp))<<8) | *(sp+1); sp+=2;
-                  green = ((*(sp))<<8) | *(sp+1); sp+=2;
-                  blue  = ((*(sp))<<8) | *(sp+1); sp+=2;
+                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
 
                   if(red == green && red == blue)
                      w = red;
@@ -2044,17 +2162,17 @@
                                   png_ptr->gamma_shift][red>>8];
                      png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
                                   png_ptr->gamma_shift][green>>8];
-                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >> 
+                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
                                   png_ptr->gamma_shift][blue>>8];
-                     png_uint_16 gray16  =  (rc * red_1 + gc * green_1
-                                  + bc * blue_1)>>8;
+                     png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
+                                  + bc*blue_1)>>15);
                      w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
                          png_ptr->gamma_shift][gray16 >> 8];
                      rgb_error |= 1;
                   }
-                  
-                  *(dp++) = (w>>8) & 0xff;
-                  *(dp++) = w & 0xff;
+
+                  *(dp++) = (png_byte)((w>>8) & 0xff);
+                  *(dp++) = (png_byte)(w & 0xff);
                }
             }
             else
@@ -2066,15 +2184,15 @@
                {
                   png_uint_16 red, green, blue, gray16;
 
-                  red   = ((*(sp))<<8) | *(sp+1); sp+=2;
-                  green = ((*(sp))<<8) | *(sp+1); sp+=2;
-                  blue  = ((*(sp))<<8) | *(sp+1); sp+=2;
+                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
 
                   if(red != green || red != blue)
                      rgb_error |= 1;
-                  gray16  =  (rc * red + gc * green + bc * blue)>>8;
-                  *(dp++) = (gray16>>8) & 0xff;
-                  *(dp++) = gray16 & 0xff;
+                  gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
+                  *(dp++) = (png_byte)((gray16>>8) & 0xff);
+                  *(dp++) = (png_byte)(gray16 & 0xff);
                }
             }
          }
@@ -2096,7 +2214,7 @@
                   if(red != green || red != blue)
                      rgb_error |= 1;
                   *(dp++) =  png_ptr->gamma_from_1
-                             [(rc*red + gc*green + bc*blue)>>8];
+                             [(rc*red + gc*green + bc*blue)>>15];
                   *(dp++) = *(sp++);  /* alpha */
                }
             }
@@ -2112,7 +2230,7 @@
                   png_byte blue  = *(sp++);
                   if(red != green || red != blue)
                      rgb_error |= 1;
-                  *(dp++) =  (gc*red + gc*green + bc*blue)>>8;
+                  *(dp++) =  (png_byte)((gc*red + gc*green + bc*blue)>>8);
                   *(dp++) = *(sp++);  /* alpha */
                }
             }
@@ -2129,9 +2247,9 @@
                {
                   png_uint_16 red, green, blue, w;
 
-                  red   = ((*(sp))<<8) | *(sp+1); sp+=2;
-                  green = ((*(sp))<<8) | *(sp+1); sp+=2;
-                  blue  = ((*(sp))<<8) | *(sp+1); sp+=2;
+                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
 
                   if(red == green && red == blue)
                      w = red;
@@ -2141,17 +2259,17 @@
                                   png_ptr->gamma_shift][red>>8];
                      png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
                                   png_ptr->gamma_shift][green>>8];
-                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >> 
+                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
                                   png_ptr->gamma_shift][blue>>8];
-                     png_uint_16 gray16  =  (rc * red_1 + gc * green_1
-                                  + bc * blue_1)>>8;
+                     png_uint_16 gray16  = (png_uint_16)((rc * red_1
+                                  + gc * green_1 + bc * blue_1)>>15);
                      w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
                          png_ptr->gamma_shift][gray16 >> 8];
                      rgb_error |= 1;
                   }
-                  
-                  *(dp++) = (w>>8) & 0xff;
-                  *(dp++) = w & 0xff;
+
+                  *(dp++) = (png_byte)((w>>8) & 0xff);
+                  *(dp++) = (png_byte)(w & 0xff);
                   *(dp++) = *(sp++);  /* alpha */
                   *(dp++) = *(sp++);
                }
@@ -2164,14 +2282,14 @@
                for (i = 0; i < row_width; i++)
                {
                   png_uint_16 red, green, blue, gray16;
-                  red   = (*(sp)<<8) | *(sp+1); sp+=2;
-                  green = (*(sp)<<8) | *(sp+1); sp+=2;
-                  blue  = (*(sp)<<8) | *(sp+1); sp+=2;
+                  red   = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+                  green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+                  blue  = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
                   if(red != green || red != blue)
                      rgb_error |= 1;
-                  gray16  =  (rc * red + gc * green + bc * blue)>>8;
-                  *(dp++) = (gray16>>8) & 0xff;
-                  *(dp++) = gray16 & 0xff;
+                  gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
+                  *(dp++) = (png_byte)((gray16>>8) & 0xff);
+                  *(dp++) = (png_byte)(gray16 & 0xff);
                   *(dp++) = *(sp++);  /* alpha */
                   *(dp++) = *(sp++);
                }
@@ -2194,7 +2312,7 @@
  * paletted.  Most useful for gamma correction and simplification
  * of code.
  */
-void
+void /* PRIVATE */
 png_build_grayscale_palette(int bit_depth, png_colorp palette)
 {
    int num_palette;
@@ -2240,12 +2358,13 @@
 
 /* This function is currently unused.  Do we really need it? */
 #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
-void
+void /* PRIVATE */
 png_correct_palette(png_structp png_ptr, png_colorp palette,
    int num_palette)
 {
    png_debug(1, "in png_correct_palette\n");
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+    defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
    if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
    {
       png_color back, back_1;
@@ -2424,7 +2543,7 @@
  * "background" is already in the screen gamma, while "background_1" is
  * at a gamma of 1.0.  Paletted files have already been taken care of.
  */
-void
+void /* PRIVATE */
 png_do_background(png_row_infop row_info, png_bytep row,
    png_color_16p trans_values, png_color_16p background,
    png_color_16p background_1,
@@ -2457,7 +2576,7 @@
                   shift = 7;
                   for (i = 0; i < row_width; i++)
                   {
-                     if ((png_uint_16)((*sp >> shift) & 0x1)
+                     if ((png_uint_16)((*sp >> shift) & 0x01)
                         == trans_values->gray)
                      {
                         *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
@@ -2482,7 +2601,7 @@
                      shift = 6;
                      for (i = 0; i < row_width; i++)
                      {
-                        if ((png_uint_16)((*sp >> shift) & 0x3)
+                        if ((png_uint_16)((*sp >> shift) & 0x03)
                             == trans_values->gray)
                         {
                            *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
@@ -2490,9 +2609,9 @@
                         }
                         else
                         {
-                           png_byte p = (*sp >> shift) & 0x3;
-                           png_byte g = (gamma_table [p | (p << 2) | (p << 4) |
-                               (p << 6)] >> 6) & 0x3;
+                           png_byte p = (png_byte)((*sp >> shift) & 0x03);
+                           png_byte g = (png_byte)((gamma_table [p | (p << 2) |
+                               (p << 4) | (p << 6)] >> 6) & 0x03);
                            *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
                            *sp |= (png_byte)(g << shift);
                         }
@@ -2512,7 +2631,7 @@
                      shift = 6;
                      for (i = 0; i < row_width; i++)
                      {
-                        if ((png_uint_16)((*sp >> shift) & 0x3)
+                        if ((png_uint_16)((*sp >> shift) & 0x03)
                             == trans_values->gray)
                         {
                            *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
@@ -2538,7 +2657,7 @@
                      shift = 4;
                      for (i = 0; i < row_width; i++)
                      {
-                        if ((png_uint_16)((*sp >> shift) & 0xf)
+                        if ((png_uint_16)((*sp >> shift) & 0x0f)
                             == trans_values->gray)
                         {
                            *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
@@ -2546,8 +2665,9 @@
                         }
                         else
                         {
-                           png_byte p = (*sp >> shift) & 0xf;
-                           png_byte g = (gamma_table[p | (p << 4)] >> 4) & 0xf;
+                           png_byte p = (png_byte)((*sp >> shift) & 0x0f);
+                           png_byte g = (png_byte)((gamma_table[p |
+                             (p << 4)] >> 4) & 0x0f);
                            *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
                            *sp |= (png_byte)(g << shift);
                         }
@@ -2567,7 +2687,7 @@
                      shift = 4;
                      for (i = 0; i < row_width; i++)
                      {
-                        if ((png_uint_16)((*sp >> shift) & 0xf)
+                        if ((png_uint_16)((*sp >> shift) & 0x0f)
                             == trans_values->gray)
                         {
                            *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
@@ -2626,7 +2746,7 @@
                      {
                         png_uint_16 v;
 
-                        v = ((png_uint_16)(*sp) << 8) + *(sp + 1);
+                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
                         if (v == trans_values->gray)
                         {
                            /* background is already in screen gamma */
@@ -2649,7 +2769,7 @@
                      {
                         png_uint_16 v;
 
-                        v = ((png_uint_16)(*sp) << 8) + *(sp + 1);
+                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
                         if (v == trans_values->gray)
                         {
                            *sp = (png_byte)((background->gray >> 8) & 0xff);
@@ -2713,9 +2833,9 @@
                   sp = row;
                   for (i = 0; i < row_width; i++, sp += 6)
                   {
-                     png_uint_16 r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
-                     png_uint_16 g = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
-                     png_uint_16 b = ((png_uint_16)(*(sp + 4)) << 8) + *(sp + 5);
+                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                     png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+                     png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
                      if (r == trans_values->red && g == trans_values->green &&
                         b == trans_values->blue)
                      {
@@ -2747,9 +2867,9 @@
                   sp = row;
                   for (i = 0; i < row_width; i++, sp += 6)
                   {
-                     png_uint_16 r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
-                     png_uint_16 g = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
-                     png_uint_16 b = ((png_uint_16)(*(sp + 4)) << 8) + *(sp + 5);
+                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
+                     png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+                     png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
 
                      if (r == trans_values->red && g == trans_values->green &&
                         b == trans_values->blue)
@@ -2833,7 +2953,7 @@
                   dp = row;
                   for (i = 0; i < row_width; i++, sp += 4, dp += 2)
                   {
-                     png_uint_16 a = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
+                     png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
 
                      if (a == (png_uint_16)0xffff)
                      {
@@ -2868,7 +2988,7 @@
                   dp = row;
                   for (i = 0; i < row_width; i++, sp += 4, dp += 2)
                   {
-                     png_uint_16 a = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
+                     png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
                      if (a == (png_uint_16)0xffff)
                      {
                         png_memcpy(dp, sp, 2);
@@ -2882,7 +3002,7 @@
                      {
                         png_uint_16 g, v;
 
-                        g = ((png_uint_16)(*sp) << 8) + *(sp + 1);
+                        g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
                         png_composite_16(v, g, a, background_1->gray);
                         *dp = (png_byte)((v >> 8) & 0xff);
                         *(dp + 1) = (png_byte)(v & 0xff);
@@ -3051,11 +3171,11 @@
                      {
                         png_uint_16 v;
 
-                        png_uint_16 r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
-                        png_uint_16 g = ((png_uint_16)(*(sp + 2)) << 8)
-                            + *(sp + 3);
-                        png_uint_16 b = ((png_uint_16)(*(sp + 4)) << 8)
-                            + *(sp + 5);
+                        png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                        png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+                            + *(sp + 3));
+                        png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+                            + *(sp + 5));
 
                         png_composite_16(v, r, a, background->red);
                         *dp = (png_byte)((v >> 8) & 0xff);
@@ -3090,11 +3210,11 @@
 #if defined(PNG_READ_GAMMA_SUPPORTED)
 /* Gamma correct the image, avoiding the alpha channel.  Make sure
  * you do this after you deal with the transparency issue on grayscale
- * or rgb images. If your bit depth is 8, use gamma_table, if it
+ * or RGB images. If your bit depth is 8, use gamma_table, if it
  * is 16, use gamma_16_table and gamma_shift.  Build these with
  * build_gamma_table().
  */
-void
+void /* PRIVATE */
 png_do_gamma(png_row_infop row_info, png_bytep row,
    png_bytep gamma_table, png_uint_16pp gamma_16_table,
    int gamma_shift)
@@ -3224,10 +3344,11 @@
                   int c = *sp & 0x0c;
                   int d = *sp & 0x03;
 
-                  *sp = ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
+                  *sp = (png_byte)(
+                        ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
                         ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
                         ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
-                        ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6)       );
+                        ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
                   sp++;
                }
             }
@@ -3239,8 +3360,8 @@
                   int msb = *sp & 0xf0;
                   int lsb = *sp & 0x0f;
 
-                  *sp = (((int)gamma_table[msb | (msb >> 4)]) & 0xf0) |
-                        (((int)gamma_table[(lsb << 4) | lsb]) >> 4);
+                  *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
+                          | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
                   sp++;
                }
             }
@@ -3272,10 +3393,10 @@
 #endif
 
 #if defined(PNG_READ_EXPAND_SUPPORTED)
-/* Expands a palette row to an rgb or rgba row depending
+/* Expands a palette row to an RGB or RGBA row depending
  * upon whether you supply trans and num_trans.
  */
-void
+void /* PRIVATE */
 png_do_expand_palette(png_row_infop row_info, png_bytep row,
    png_colorp palette, png_bytep trans, int num_trans)
 {
@@ -3299,10 +3420,10 @@
             {
                sp = row + (png_size_t)((row_width - 1) >> 3);
                dp = row + (png_size_t)row_width - 1;
-               shift = 7 - (int)((row_width + 7) & 7);
+               shift = 7 - (int)((row_width + 7) & 0x07);
                for (i = 0; i < row_width; i++)
                {
-                  if ((*sp >> shift) & 0x1)
+                  if ((*sp >> shift) & 0x01)
                      *dp = 1;
                   else
                      *dp = 0;
@@ -3322,10 +3443,10 @@
             {
                sp = row + (png_size_t)((row_width - 1) >> 2);
                dp = row + (png_size_t)row_width - 1;
-               shift = (int)((3 - ((row_width + 3) & 3)) << 1);
+               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
                for (i = 0; i < row_width; i++)
                {
-                  value = (*sp >> shift) & 0x3;
+                  value = (*sp >> shift) & 0x03;
                   *dp = (png_byte)value;
                   if (shift == 6)
                   {
@@ -3343,10 +3464,10 @@
             {
                sp = row + (png_size_t)((row_width - 1) >> 1);
                dp = row + (png_size_t)row_width - 1;
-               shift = (int)((row_width & 1) << 2);
+               shift = (int)((row_width & 0x01) << 2);
                for (i = 0; i < row_width; i++)
                {
-                  value = (*sp >> shift) & 0xf;
+                  value = (*sp >> shift) & 0x0f;
                   *dp = (png_byte)value;
                   if (shift == 4)
                   {
@@ -3418,7 +3539,7 @@
 /* If the bit depth < 8, it is expanded to 8.  Also, if the
  * transparency value is supplied, an alpha channel is built.
  */
-void
+void /* PRIVATE */
 png_do_expand(png_row_infop row_info, png_bytep row,
    png_color_16p trans_value)
 {
@@ -3434,7 +3555,7 @@
    {
       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
       {
-         png_uint_16 gray = trans_value ? trans_value->gray : 0;
+         png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
 
          if (row_info->bit_depth < 8)
          {
@@ -3442,13 +3563,13 @@
             {
                case 1:
                {
-                  gray *= 0xff;
+                  gray = (png_uint_16)(gray*0xff);
                   sp = row + (png_size_t)((row_width - 1) >> 3);
                   dp = row + (png_size_t)row_width - 1;
-                  shift = 7 - (int)((row_width + 7) & 7);
+                  shift = 7 - (int)((row_width + 7) & 0x07);
                   for (i = 0; i < row_width; i++)
                   {
-                     if ((*sp >> shift) & 0x1)
+                     if ((*sp >> shift) & 0x01)
                         *dp = 0xff;
                      else
                         *dp = 0;
@@ -3466,13 +3587,13 @@
                }
                case 2:
                {
-                  gray *= 0x55;
+                  gray = (png_uint_16)(gray*0x55);
                   sp = row + (png_size_t)((row_width - 1) >> 2);
                   dp = row + (png_size_t)row_width - 1;
-                  shift = (int)((3 - ((row_width + 3) & 3)) << 1);
+                  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
                   for (i = 0; i < row_width; i++)
                   {
-                     value = (*sp >> shift) & 0x3;
+                     value = (*sp >> shift) & 0x03;
                      *dp = (png_byte)(value | (value << 2) | (value << 4) |
                         (value << 6));
                      if (shift == 6)
@@ -3489,13 +3610,13 @@
                }
                case 4:
                {
-                  gray *= 0x11;
+                  gray = (png_uint_16)(gray*0x11);
                   sp = row + (png_size_t)((row_width - 1) >> 1);
                   dp = row + (png_size_t)row_width - 1;
-                  shift = (int)((1 - ((row_width + 1) & 1)) << 2);
+                  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
                   for (i = 0; i < row_width; i++)
                   {
-                     value = (*sp >> shift) & 0xf;
+                     value = (*sp >> shift) & 0x0f;
                      *dp = (png_byte)(value | (value << 4));
                      if (shift == 4)
                      {
@@ -3617,7 +3738,7 @@
 #endif
 
 #if defined(PNG_READ_DITHER_SUPPORTED)
-void
+void /* PRIVATE */
 png_do_dither(png_row_infop row_info, png_bytep row,
     png_bytep palette_lookup, png_bytep dither_lookup)
 {
@@ -3709,6 +3830,7 @@
 }
 #endif
 
+#ifdef PNG_FLOATING_POINT_SUPPORTED
 #if defined(PNG_READ_GAMMA_SUPPORTED)
 static int png_gamma_shift[] =
    {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
@@ -3718,7 +3840,7 @@
  * the future.  Note also how the gamma_16 tables are segmented so that
  * we don't need to allocate > 64K chunks for a full 16-bit table.
  */
-void
+void /* PRIVATE */
 png_build_gamma_table(png_structp png_ptr)
 {
   png_debug(1, "in png_build_gamma_table\n");
@@ -3745,7 +3867,7 @@
 
 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
     defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-      if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
+      if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
       {
 
          g = 1.0 / (png_ptr->gamma);
@@ -3759,7 +3881,7 @@
                g) * 255.0 + .5);
          }
 
-         
+
          png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
             (png_uint_32)256);
 
@@ -3928,4 +4050,66 @@
  }
 }
 #endif
+/* To do: install integer version of png_build_gamma_table here */
+#endif
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+/* undoes intrapixel differencing  */
+void /* PRIVATE */
+png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_read_intrapixel\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       (row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      int bytes_per_pixel;
+      png_uint_32 row_width = row_info->width;
+      if (row_info->bit_depth == 8)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 3;
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 4;
+         else
+            return;
 
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
+            *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
+         }
+      }
+      else if (row_info->bit_depth == 16)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 6;
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 8;
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            png_uint_32 s0=*(rp  )<<8 | *(rp+1);
+            png_uint_32 s1=*(rp+2)<<8 | *(rp+3);
+            png_uint_32 s2=*(rp+4)<<8 | *(rp+5);
+            png_uint_32 red=(65536+s0+s1)&0xffff;
+            png_uint_32 blue=(65536+s2+s1)&0xffff;
+            *(rp  ) = (png_byte)((red>>8)&0xff);
+            *(rp+1) = (png_byte)(red&0xff);
+            *(rp+4) = (png_byte)((blue>>8)&0xff);
+            *(rp+5) = (png_byte)(blue&0xff);
+         }
+      }
+   }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */

Deleted: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/ansi2knr.1

Deleted: trunk/orca/packages/rrdtool-1.0.33/libpng-1.0.9/ansi2knr.c

Added: trunk/orca/packages/rrdtool-1.0.33/rrdtool.spec
==============================================================================
--- trunk/orca/packages/rrdtool-1.0.33/rrdtool.spec	(original)
+++ trunk/orca/packages/rrdtool-1.0.33/rrdtool.spec	Sat Jul 13 21:26:58 2002
@@ -0,0 +1,54 @@
+%define name rrdtool
+%define ver 1.0.21
+%define extension tar.gz
+
+Summary: Round Robin Database Tools
+Name: %name
+Version: %{ver}
+Release: 2
+Copyright: GPL
+Group: Applications/Networking
+Source: %{name}-%{ver}.%{extension}
+Patch0: rrdtool-perldestdir.patch
+Patch1: rrdtool-tcldestdir.patch
+URL: http://ee-staff.ethz.ch/~oetiker/webtools/rrdtool/
+Buildroot: /tmp/%{name}-%{ver}-root
+
+%description
+It is pretty easy to gather status information from all sorts of things,
+ranging from the temperature in your office to the number of octets which
+have passed through the FDDI interface of your router. But it is not so
+trivial to store this data in a efficient and systematic manner. This is
+where RRDtool kicks in. It lets you log and analyze the data you gather from
+all kinds of data-sources (DS). The data analysis part of RRDtool is based
+on the ability to quickly generate graphical representations of the data
+values collected over a definable time period.
+
+%prep
+%setup
+%patch0 -p1
+%patch1 -p1
+%build
+./configure --with-tcllib=/usr/lib --prefix=/usr
+make
+
+%install
+make install DESTDIR=${RPM_BUILD_ROOT}
+# install tcl interface...
+make site-tcl-install DESTDIR=${RPM_BUILD_ROOT}
+# rpm uses /doc for its file restructuring...
+mv ${RPM_BUILD_ROOT}/usr/doc ${RPM_BUILD_ROOT}/usr/txt
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%doc CHANGES CONTRIBUTORS COPYING COPYRIGHT NT-BUILD-TIPS.txt README TODO 
+%doc ${RPM_BUILD_ROOT}/usr/contrib/
+%doc ${RPM_BUILD_ROOT}/usr/txt/
+%doc ${RPM_BUILD_ROOT}/usr/examples/
+%doc ${RPM_BUILD_ROOT}/usr/html/
+/usr/man/
+/usr/bin/
+/usr/lib/
+

Modified: trunk/orca/packages/Storable-1.0.11/t/dump.pl
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/dump.pl	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/dump.pl	Sat Jul 13 21:26:59 2002
@@ -1,15 +1,21 @@
-;# $Id: dump.pl,v 0.6 1998/06/04 16:08:27 ram Exp $
+;# $Id: dump.pl,v 1.0 2000/09/01 19:40:41 ram Exp $
 ;#
-;#  Copyright (c) 1995-1998, Raphael Manfredi
+;#  Copyright (c) 1995-2000, Raphael Manfredi
 ;#  
-;#  You may redistribute only under the terms of the Artistic License,
-;#  as specified in the README file that comes with the distribution.
+;#  You may redistribute only under the same terms as Perl 5, as specified
+;#  in the README file that comes with the distribution.
 ;#
 ;# $Log: dump.pl,v $
-;# Revision 0.6  1998/06/04 16:08:27  ram
-;# Baseline for first beta release.
+;# Revision 1.0  2000/09/01 19:40:41  ram
+;# Baseline for first official release.
 ;#
 
+sub ok {
+	my ($num, $ok) = @_;
+	print "not " unless $ok;
+	print "ok $num\n";
+}
+
 package dump;
 use Carp;
 

Modified: trunk/orca/packages/Storable-1.0.11/t/freeze.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/freeze.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/freeze.t	Sat Jul 13 21:26:59 2002
@@ -1,18 +1,15 @@
 #!./perl
 
-# $Id: freeze.t,v 0.6.1.1 1998/06/12 09:47:08 ram Exp $
+# $Id: freeze.t,v 1.0 2000/09/01 19:40:41 ram Exp $
 #
-#  Copyright (c) 1995-1998, Raphael Manfredi
+#  Copyright (c) 1995-2000, Raphael Manfredi
 #  
-#  You may redistribute only under the terms of the Artistic License,
-#  as specified in the README file that comes with the distribution.
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
 #
 # $Log: freeze.t,v $
-# Revision 0.6.1.1  1998/06/12 09:47:08  ram
-# patch1: added test for the LVALUE bug workaround
-#
-# Revision 0.6  1998/06/04  16:08:31  ram
-# Baseline for first beta release.
+# Revision 1.0  2000/09/01 19:40:41  ram
+# Baseline for first official release.
 #
 
 require 't/dump.pl';

Added: trunk/orca/packages/Storable-1.0.11/t/blessed.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/blessed.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/blessed.t	Sat Jul 13 21:27:00 2002
@@ -0,0 +1,93 @@
+#!./perl
+
+# $Id: blessed.t,v 1.0 2000/09/01 19:40:41 ram Exp $
+#
+#  Copyright (c) 1995-2000, Raphael Manfredi
+#  
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
+#
+# $Log: blessed.t,v $
+# Revision 1.0  2000/09/01 19:40:41  ram
+# Baseline for first official release.
+#
+
+require 't/dump.pl';
+sub ok;
+
+use Storable qw(freeze thaw);
+
+print "1..10\n";
+
+package SHORT_NAME;
+
+sub make { bless [], shift }
+
+package SHORT_NAME_WITH_HOOK;
+
+sub make { bless [], shift }
+
+sub STORABLE_freeze {
+	my $self = shift;
+	return ("", $self);
+}
+
+sub STORABLE_thaw {
+	my $self = shift;
+	my $cloning = shift;
+	my ($x, $obj) = @_;
+	die "STORABLE_thaw" unless $obj eq $self;
+}
+
+package main;
+
+# Still less than 256 bytes, so long classname logic not fully exercised
+# Wait until Perl removes the restriction on identifier lengths.
+my $name = "LONG_NAME_" . 'xxxxxxxxxxxxx::' x 14 . "final";
+
+eval <<EOC;
+package $name;
+
+\@ISA = ("SHORT_NAME");
+EOC
+die $@ if $@;
+ok 1, $@ eq '';
+
+eval <<EOC;
+package ${name}_WITH_HOOK;
+
+\@ISA = ("SHORT_NAME_WITH_HOOK");
+EOC
+ok 2, $@ eq '';
+
+# Construct a pool of objects
+my @pool;
+
+for (my $i = 0; $i < 10; $i++) {
+	push(@pool, SHORT_NAME->make);
+	push(@pool, SHORT_NAME_WITH_HOOK->make);
+	push(@pool, $name->make);
+	push(@pool, "${name}_WITH_HOOK"->make);
+}
+
+my $x = freeze \@pool;
+ok 3, 1;
+
+my $y = thaw $x;
+ok 4, ref $y eq 'ARRAY';
+ok 5, @{$y} == @pool;
+
+ok 6, ref $y->[0] eq 'SHORT_NAME';
+ok 7, ref $y->[1] eq 'SHORT_NAME_WITH_HOOK';
+ok 8, ref $y->[2] eq $name;
+ok 9, ref $y->[3] eq "${name}_WITH_HOOK";
+
+my $good = 1;
+for (my $i = 0; $i < 10; $i++) {
+	do { $good = 0; last } unless ref $y->[4*$i]   eq 'SHORT_NAME';
+	do { $good = 0; last } unless ref $y->[4*$i+1] eq 'SHORT_NAME_WITH_HOOK';
+	do { $good = 0; last } unless ref $y->[4*$i+2] eq $name;
+	do { $good = 0; last } unless ref $y->[4*$i+3] eq "${name}_WITH_HOOK";
+}
+ok 10, $good;
+

Added: trunk/orca/packages/Storable-1.0.11/t/compat-0.6.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/compat-0.6.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/compat-0.6.t	Sat Jul 13 21:27:00 2002
@@ -0,0 +1,143 @@
+#!./perl
+
+# $Id: compat-0.6.t,v 1.0.1.1 2001/02/17 12:26:21 ram Exp $
+#
+#  Copyright (c) 1995-2000, Raphael Manfredi
+#  
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
+#
+# $Log: compat-0.6.t,v $
+# Revision 1.0.1.1  2001/02/17 12:26:21  ram
+# patch8: added EBCDIC version of the test, from Peter Prymmer
+#
+# Revision 1.0  2000/09/01 19:40:41  ram
+# Baseline for first official release.
+#
+
+require 't/dump.pl';
+sub ok;
+
+print "1..8\n";
+
+use Storable qw(freeze nfreeze thaw);
+
+package TIED_HASH;
+
+sub TIEHASH {
+	my $self = bless {}, shift;
+	return $self;
+}
+
+sub FETCH {
+	my $self = shift;
+	my ($key) = @_;
+	$main::hash_fetch++;
+	return $self->{$key};
+}
+
+sub STORE {
+	my $self = shift;
+	my ($key, $val) = @_;
+	$self->{$key} = $val;
+}
+
+package SIMPLE;
+
+sub make {
+	my $self = bless [], shift;
+	my ($x) = @_;
+	$self->[0] = $x;
+	return $self;
+}
+
+package ROOT;
+
+sub make {
+	my $self = bless {}, shift;
+	my $h = tie %hash, TIED_HASH;
+	$self->{h} = $h;
+	$self->{ref} = \%hash;
+	my @pool;
+	for (my $i = 0; $i < 5; $i++) {
+		push(@pool, SIMPLE->make($i));
+	}
+	$self->{obj} = \@pool;
+	my @a = ('string', $h, $self);
+	$self->{a} = \@a;
+	$self->{num} = [1, 0, -3, -3.14159, 456, 4.5];
+	$h->{key1} = 'val1';
+	$h->{key2} = 'val2';
+	return $self;
+};
+
+sub num { $_[0]->{num} }
+sub h   { $_[0]->{h} }
+sub ref { $_[0]->{ref} }
+sub obj { $_[0]->{obj} }
+
+package main;
+
+my $is_EBCDIC = (ord('A') == 193) ? 1 : 0;
+
+my $r = ROOT->make;
+
+my $data = '';
+if (!$is_EBCDIC) {			# ASCII machine
+	while (<DATA>) {
+		next if /^#/;
+	    $data .= unpack("u", $_);
+	}
+} else {
+	while (<DATA>) {
+		next if /^#$/;		# skip comments
+		next if /^#\s+/;	# skip comments
+		next if /^[^#]/;	# skip uuencoding for ASCII machines
+		s/^#//;				# prepare uuencoded data for EBCDIC machines
+		$data .= unpack("u", $_);
+	}
+}
+
+my $expected_length = $is_EBCDIC ? 217 : 278;
+ok 1, length $data == $expected_length;
+
+my $y = thaw($data);
+ok 2, 1;
+ok 3, ref $y eq 'ROOT';
+
+$Storable::canonical = 1;		# Prevent "used once" warning
+$Storable::canonical = 1;
+ok 4, nfreeze($y) eq nfreeze($r);
+
+ok 5, $y->ref->{key1} eq 'val1';
+ok 6, $y->ref->{key2} eq 'val2';
+ok 7, $hash_fetch == 2;
+
+my $num = $r->num;
+my $ok = 1;
+for (my $i = 0; $i < @$num; $i++) {
+	do { $ok = 0; last } unless $num->[$i] == $y->num->[$i];
+}
+ok 8, $ok;
+
+__END__
+#
+# using Storable-0.6 at 11, output of: print pack("u", nfreeze(ROOT->make));
+# original size: 278 bytes
+#
+M`P,````%!`(````&"(%8"(!8"'U8"@@M,RXQ-#$U.5@)```!R%@*`S0N-5A8
+M6`````-N=6T$`P````(*!'9A;#%8````!&ME>3$*!'9A;#)8````!&ME>3)B
+M"51)141?2$%32%A8`````6@$`@````,*!G-T<FEN9U@$``````I8!```````
+M6%A8`````6$$`@````4$`@````$(@%AB!E-)35!,15A8!`(````!"(%88 at 93
+M24U03$586`0"`````0B"6&(&4TE-4$Q%6%@$`@````$(@UAB!E-)35!,15A8
+M!`(````!"(188 at 9324U03$586%A8`````V]B:@0,!``````*6%A8`````W)E
+(9F($4D]/5%@`
+#
+# using Storable-0.6 at 11, output of: print '#' . pack("u", nfreeze(ROOT->make));
+# on OS/390 (cp 1047) original size: 217 bytes
+#
+#M!0,1!-G6UN,#````!00,!!$)X\G%Q&W(P>+(`P````(*!*6!D_$````$DH6H
+#M\0H$I8&3\@````22A:CR`````YF%A at 0"````!@B!"(`(?0H(8/-+\?3Q]?D)
+#M```!R`H#]$OU`````Y6DE`0"````!001!N+)U-?3Q0(````!"(`$$@("````
+#M`0B!!!("`@````$(@@02`@(````!"(,$$@("`````0B$`````Y:"D00`````
+#E!`````&(!`(````#"@:BHYF)E8<$``````0$```````````!@0``

Modified: trunk/orca/packages/Storable-1.0.11/t/retrieve.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/retrieve.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/retrieve.t	Sat Jul 13 21:27:01 2002
@@ -1,18 +1,15 @@
 #!./perl
 
-# $Id: retrieve.t,v 0.6.1.1 2000/02/10 18:47:49 ram Exp $
+# $Id: retrieve.t,v 1.0 2000/09/01 19:40:42 ram Exp $
 #
-#  Copyright (c) 1995-1998, Raphael Manfredi
+#  Copyright (c) 1995-2000, Raphael Manfredi
 #  
-#  You may redistribute only under the terms of the Artistic License,
-#  as specified in the README file that comes with the distribution.
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
 #
 # $Log: retrieve.t,v $
-# Revision 0.6.1.1  2000/02/10 18:47:49  ram
-# patch8: added tests for the new last_op_in_netorder() predicate
-#
-# Revision 0.6  1998/06/04  16:08:33  ram
-# Baseline for first beta release.
+# Revision 1.0  2000/09/01 19:40:42  ram
+# Baseline for first official release.
 #
 
 require 't/dump.pl';

Modified: trunk/orca/packages/Storable-1.0.11/t/tied.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/tied.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/tied.t	Sat Jul 13 21:27:02 2002
@@ -1,22 +1,23 @@
 #!./perl
 
-# $Id: tied.t,v 0.6 1998/06/04 16:08:40 ram Exp $
+# $Id: tied.t,v 1.0 2000/09/01 19:40:42 ram Exp $
 #
-#  Copyright (c) 1995-1998, Raphael Manfredi
+#  Copyright (c) 1995-2000, Raphael Manfredi
 #  
-#  You may redistribute only under the terms of the Artistic License,
-#  as specified in the README file that comes with the distribution.
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
 #
 # $Log: tied.t,v $
-# Revision 0.6  1998/06/04 16:08:40  ram
-# Baseline for first beta release.
+# Revision 1.0  2000/09/01 19:40:42  ram
+# Baseline for first official release.
 #
 
 require 't/dump.pl';
+sub ok;
 
 use Storable qw(freeze thaw);
 
-print "1..15\n";
+print "1..22\n";
 
 ($scalar_fetch, $array_fetch, $hash_fetch) = (0, 0, 0);
 
@@ -96,6 +97,23 @@
 	$$self = $value;
 }
 
+package FAULT;
+
+$fault = 0;
+
+sub TIESCALAR {
+	my $pkg = shift;
+	return bless [@_], $pkg;
+}
+
+sub FETCH {
+	my $self = shift;
+	my ($href, $key) = @$self;
+	$fault++;
+	untie $href->{$key};
+	return $href->{$key} = 1;
+}
+
 package main;
 
 $a = 'toto';
@@ -126,18 +144,16 @@
 @a = ('first', 3, -4, -3.14159, 456, 4.5, $d, \$d,
 	$b, \$a, $a, $c, \$c, \%a, \@array, \%hash, \@tied);
 
-print "not " unless defined($f = freeze(\@a));
-print "ok 1\n";
+ok 1, defined($f = freeze(\@a));
 
 $dumped = &dump(\@a);
-print "ok 2\n";
+ok 2, 1;
 
 $root = thaw($f);
-print "not " unless defined $root;
-print "ok 3\n";
+ok 3, defined $root;
 
 $got = &dump($root);
-print "ok 4\n";
+ok 4, 1;
 
 ### Used to see the manifestation of the bug documented above.
 ### print "original: $dumped";
@@ -145,24 +161,19 @@
 ### print "got: $got";
 ### print "--------\n";
 
-print "not " unless $got eq $dumped; 
-print "ok 5\n";
+ok 5, $got eq $dumped; 
 
 $g = freeze($root);
-print "not " unless length($f) == length($g);
-print "ok 6\n";
+ok 6, length($f) == length($g);
 
 # Ensure the tied items in the retrieved image work
 @old = ($scalar_fetch, $array_fetch, $hash_fetch);
 @tied = ($tscalar, $tarray, $thash) = @{$root->[$#{$root}]};
 @type = qw(SCALAR  ARRAY  HASH);
 
-print "not " unless tied $$tscalar;
-print "ok 7\n";
-print "not " unless tied @{$tarray};
-print "ok 8\n";
-print "not " unless tied %{$thash};
-print "ok 9\n";
+ok 7, tied $$tscalar;
+ok 8, tied @{$tarray};
+ok 9, tied %{$thash};
 
 @new = ($$tscalar, $tarray->[0], $thash->{'attribute'});
 @new = ($scalar_fetch, $array_fetch, $hash_fetch);
@@ -175,3 +186,17 @@
 	printf "ok %d\n", 11 + 2*$i;	# Tests 11,13,15
 }
 
+# Check undef ties
+my $h = {};
+tie $h->{'x'}, 'FAULT', $h, 'x';
+my $hf = freeze($h);
+ok 16, defined $hf;
+ok 17, $FAULT::fault == 0;
+ok 18, $h->{'x'} == 1;
+ok 19, $FAULT::fault == 1;
+
+my $ht = thaw($hf);
+ok 20, defined $ht;
+ok 21, $ht->{'x'} == 1;
+ok 22, $FAULT::fault == 2;
+

Added: trunk/orca/packages/Storable-1.0.11/t/tied_items.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/tied_items.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/tied_items.t	Sat Jul 13 21:27:02 2002
@@ -0,0 +1,57 @@
+#!./perl
+
+# $Id: tied_items.t,v 1.0 2000/09/01 19:40:42 ram Exp $
+#
+#  Copyright (c) 1995-2000, Raphael Manfredi
+#  
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
+#
+# $Log: tied_items.t,v $
+# Revision 1.0  2000/09/01 19:40:42  ram
+# Baseline for first official release.
+#
+
+#
+# Tests ref to items in tied hash/array structures.
+#
+
+require 't/dump.pl';
+sub ok;
+$^W = 0;
+
+print "1..8\n";
+
+use Storable qw(dclone);
+
+$h_fetches = 0;
+
+sub H::TIEHASH { bless \(my $x), "H" }
+sub H::FETCH { $h_fetches++; $_[1] - 70 }
+
+tie %h, "H";
+
+$ref = \$h{77};
+$ref2 = dclone $ref;
+
+ok 1, $h_fetches == 0;
+ok 2, $$ref2 eq $$ref;
+ok 3, $$ref2 == 7;
+ok 4, $h_fetches == 2;
+
+$a_fetches = 0;
+
+sub A::TIEARRAY { bless \(my $x), "A" }
+sub A::FETCH { $a_fetches++; $_[1] - 70 }
+
+tie @a, "A";
+
+$ref = \$a[78];
+$ref2 = dclone $ref;
+
+ok 5, $a_fetches == 0;
+ok 6, $$ref2 eq $$ref;
+ok 7, $$ref2 == 8;
+# I don't understand why it's 3 and not 2
+ok 8, $a_fetches == 3;
+

Added: trunk/orca/packages/Storable-1.0.11/t/utf8.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/utf8.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/utf8.t	Sat Jul 13 21:27:03 2002
@@ -0,0 +1,33 @@
+#!./perl
+
+# $Id: utf8.t,v 1.0.1.2 2000/09/28 21:44:17 ram Exp $
+#
+#  Copyright (c) 1995-2000, Raphael Manfredi
+#  
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
+#
+# $Log: utf8.t,v $
+# Revision 1.0.1.2  2000/09/28 21:44:17  ram
+# patch2: fixed stupid typo
+#
+# Revision 1.0.1.1  2000/09/17 16:48:12  ram
+# patch1: created.
+#
+#
+
+use Storable qw(thaw freeze);
+
+if ($] < 5.006) {
+	print "1..0\n";
+	exit 0;
+}
+
+require 't/dump.pl';
+sub ok;
+
+print "1..1\n";
+
+$x = chr(1234);
+ok 1, $x eq ${thaw freeze \$x};
+

Modified: trunk/orca/packages/Storable-1.0.11/t/canonical.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/canonical.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/canonical.t	Sat Jul 13 21:27:03 2002
@@ -1,18 +1,15 @@
 #!./perl
 
-# $Id: canonical.t,v 0.6.1.1 2000/03/02 22:20:53 ram Exp $
+# $Id: canonical.t,v 1.0 2000/09/01 19:40:41 ram Exp $
 #
-#  Copyright (c) 1995-1998, Raphael Manfredi
+#  Copyright (c) 1995-2000, Raphael Manfredi
 #  
-#  You may redistribute only under the terms of the Artistic License,
-#  as specified in the README file that comes with the distribution.
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
 #  
 # $Log: canonical.t,v $
-# Revision 0.6.1.1  2000/03/02 22:20:53  ram
-# patch9: added test case for "undef" bug in hashes
-#
-# Revision 0.6  1998/06/04  16:08:24  ram
-# Baseline for first beta release.
+# Revision 1.0  2000/09/01 19:40:41  ram
+# Baseline for first official release.
 #
 
 BEGIN { push @INC, "../blib" }

Added: trunk/orca/packages/Storable-1.0.11/t/lock.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/lock.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/lock.t	Sat Jul 13 21:27:04 2002
@@ -0,0 +1,52 @@
+#!./perl
+
+# $Id: lock.t,v 1.0.1.4 2001/01/03 09:41:00 ram Exp $
+#
+#  Copyright (c) 1995-2000, Raphael Manfredi
+#  
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
+#
+# $Log: lock.t,v $
+# Revision 1.0.1.4  2001/01/03 09:41:00  ram
+# patch7: use new CAN_FLOCK routine to determine whether to run tests
+#
+# Revision 1.0.1.3  2000/10/26 17:11:27  ram
+# patch5: just check $^O, there's no need for the whole Config
+#
+# Revision 1.0.1.2  2000/10/23 18:03:07  ram
+# patch4: protected calls to flock() for dos platform
+#
+# Revision 1.0.1.1  2000/09/28 21:44:06  ram
+# patch2: created.
+#
+#
+
+use Storable qw(lock_store lock_retrieve);
+
+unless (&Storable::CAN_FLOCK) {
+	print "1..0 # Skip: fcntl/flock emulation broken on this platform\n";
+	exit 0;
+}
+
+require 't/dump.pl';
+sub ok;
+
+print "1..5\n";
+
+ at a = ('first', undef, 3, -4, -3.14159, 456, 4.5);
+
+#
+# We're just ensuring things work, we're not validating locking.
+#
+
+ok 1, defined lock_store(\@a, 't/store');
+ok 2, $dumped = &dump(\@a);
+
+$root = lock_retrieve('t/store');
+ok 3, ref $root eq 'ARRAY';
+ok 4, @a == @$root;
+ok 5, &dump($root) eq $dumped; 
+
+unlink 't/store';
+

Modified: trunk/orca/packages/Storable-1.0.11/t/store.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/store.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/store.t	Sat Jul 13 21:27:04 2002
@@ -1,20 +1,20 @@
 #!./perl
 
-# $Id: store.t,v 0.6 1998/06/04 16:08:35 ram Exp $
+# $Id: store.t,v 1.0 2000/09/01 19:40:42 ram Exp $
 #
-#  Copyright (c) 1995-1998, Raphael Manfredi
+#  Copyright (c) 1995-2000, Raphael Manfredi
 #  
-#  You may redistribute only under the terms of the Artistic License,
-#  as specified in the README file that comes with the distribution.
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
 #
 # $Log: store.t,v $
-# Revision 0.6  1998/06/04 16:08:35  ram
-# Baseline for first beta release.
+# Revision 1.0  2000/09/01 19:40:42  ram
+# Baseline for first official release.
 #
 
 require 't/dump.pl';
 
-use Storable qw(store retrieve store_fd nstore_fd retrieve_fd);
+use Storable qw(store retrieve store_fd nstore_fd fd_retrieve);
 
 print "1..20\n";
 
@@ -75,31 +75,31 @@
 print "not " unless open(OUT, 't/store');
 binmode OUT;
 
-$r = retrieve_fd(::OUT);
+$r = fd_retrieve(::OUT);
 print "not " unless defined $r;
 print "ok 12\n";
 print "not " unless &dump($foo) eq &dump($r);
 print "ok 13\n";
 
-$r = retrieve_fd(::OUT);
+$r = fd_retrieve(::OUT);
 print "not " unless defined $r;
 print "ok 14\n";
 print "not " unless &dump(\@a) eq &dump($r);
 print "ok 15\n";
 
-$r = retrieve_fd(main::OUT);
+$r = fd_retrieve(main::OUT);
 print "not " unless defined $r;
 print "ok 16\n";
 print "not " unless &dump($foo) eq &dump($r);
 print "ok 17\n";
 
-$r = retrieve_fd(::OUT);
+$r = fd_retrieve(::OUT);
 print "not " unless defined $r;
 print "ok 18\n";
 print "not " unless &dump(\%a) eq &dump($r);
 print "ok 19\n";
 
-eval { $r = retrieve_fd(::OUT); };
+eval { $r = fd_retrieve(::OUT); };
 print "not " unless $@;
 print "ok 20\n";
 

Modified: trunk/orca/packages/Storable-1.0.11/t/forgive.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/forgive.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/forgive.t	Sat Jul 13 21:27:05 2002
@@ -1,18 +1,21 @@
 #!./perl
 
-# $Id: forgive.t,v 0.6 1998/06/04 16:08:38 ram Exp $
+# $Id: forgive.t,v 1.0.1.1 2000/09/01 19:40:42 ram Exp $
 #
-#  Copyright (c) 1995-1998, Raphael Manfredi
+#  Copyright (c) 1995-2000, Raphael Manfredi
 #  
-#  You may redistribute only under the terms of the Artistic License,
-#  as specified in the README file that comes with the distribution.
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
 #
 # Original Author: Ulrich Pfeifer
 # (C) Copyright 1997, Universitat Dortmund, all rights reserved.
 #
 # $Log: forgive.t,v $
-# Revision 0.6  1998/06/04 16:08:38  ram
-# Baseline for first beta release.
+# Revision 1.0.1.1  2000/09/01 19:40:42  ram
+# Baseline for first official release.
+#
+# Revision 1.0  2000/09/01 19:40:41  ram
+# Baseline for first official release.
 #
 
 use Storable qw(store retrieve);

Modified: trunk/orca/packages/Storable-1.0.11/t/dclone.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/dclone.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/dclone.t	Sat Jul 13 21:27:05 2002
@@ -1,18 +1,15 @@
 #!./perl
 
-# $Id: dclone.t,v 0.6.1.1 2000/03/02 22:21:05 ram Exp $
+# $Id: dclone.t,v 1.0 2000/09/01 19:40:41 ram Exp $
 #
-#  Copyright (c) 1995-1998, Raphael Manfredi
+#  Copyright (c) 1995-2000, Raphael Manfredi
 #  
-#  You may redistribute only under the terms of the Artistic License,
-#  as specified in the README file that comes with the distribution.
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
 #
 # $Log: dclone.t,v $
-# Revision 0.6.1.1  2000/03/02 22:21:05  ram
-# patch9: added test case for "undef" bug in hashes
-#
-# Revision 0.6  1998/06/04  16:08:25  ram
-# Baseline for first beta release.
+# Revision 1.0  2000/09/01 19:40:41  ram
+# Baseline for first official release.
 #
 
 require 't/dump.pl';

Added: trunk/orca/packages/Storable-1.0.11/t/tied_hook.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/tied_hook.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/tied_hook.t	Sat Jul 13 21:27:06 2002
@@ -0,0 +1,243 @@
+#!./perl
+
+# $Id: tied_hook.t,v 1.0.1.1 2001/02/17 12:29:01 ram Exp $
+#
+#  Copyright (c) 1995-2000, Raphael Manfredi
+#  
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
+#
+# $Log: tied_hook.t,v $
+# Revision 1.0.1.1  2001/02/17 12:29:01  ram
+# patch8: added test for blessed ref to tied hash
+#
+# Revision 1.0  2000/09/01 19:40:42  ram
+# Baseline for first official release.
+#
+
+require 't/dump.pl';
+sub ok;
+
+use Storable qw(freeze thaw);
+
+print "1..25\n";
+
+($scalar_fetch, $array_fetch, $hash_fetch) = (0, 0, 0);
+
+package TIED_HASH;
+
+sub TIEHASH {
+	my $self = bless {}, shift;
+	return $self;
+}
+
+sub FETCH {
+	my $self = shift;
+	my ($key) = @_;
+	$main::hash_fetch++;
+	return $self->{$key};
+}
+
+sub STORE {
+	my $self = shift;
+	my ($key, $value) = @_;
+	$self->{$key} = $value;
+}
+
+sub FIRSTKEY {
+	my $self = shift;
+	scalar keys %{$self};
+	return each %{$self};
+}
+
+sub NEXTKEY {
+	my $self = shift;
+	return each %{$self};
+}
+
+sub STORABLE_freeze {
+	my $self = shift;
+	$main::hash_hook1++;
+	return join(":", keys %$self) . ";" . join(":", values %$self);
+}
+
+sub STORABLE_thaw {
+	my ($self, $cloning, $frozen) = @_;
+	my ($keys, $values) = split(/;/, $frozen);
+	my @keys = split(/:/, $keys);
+	my @values = split(/:/, $values);
+	for (my $i = 0; $i < @keys; $i++) {
+		$self->{$keys[$i]} = $values[$i];
+	}
+	$main::hash_hook2++;
+}
+
+package TIED_ARRAY;
+
+sub TIEARRAY {
+	my $self = bless [], shift;
+	return $self;
+}
+
+sub FETCH {
+	my $self = shift;
+	my ($idx) = @_;
+	$main::array_fetch++;
+	return $self->[$idx];
+}
+
+sub STORE {
+	my $self = shift;
+	my ($idx, $value) = @_;
+	$self->[$idx] = $value;
+}
+
+sub FETCHSIZE {
+	my $self = shift;
+	return @{$self};
+}
+
+sub STORABLE_freeze {
+	my $self = shift;
+	$main::array_hook1++;
+	return join(":", @$self);
+}
+
+sub STORABLE_thaw {
+	my ($self, $cloning, $frozen) = @_;
+	@$self = split(/:/, $frozen);
+	$main::array_hook2++;
+}
+
+package TIED_SCALAR;
+
+sub TIESCALAR {
+	my $scalar;
+	my $self = bless \$scalar, shift;
+	return $self;
+}
+
+sub FETCH {
+	my $self = shift;
+	$main::scalar_fetch++;
+	return $$self;
+}
+
+sub STORE {
+	my $self = shift;
+	my ($value) = @_;
+	$$self = $value;
+}
+
+sub STORABLE_freeze {
+	my $self = shift;
+	$main::scalar_hook1++;
+	return $$self;
+}
+
+sub STORABLE_thaw {
+	my ($self, $cloning, $frozen) = @_;
+	$$self = $frozen;
+	$main::scalar_hook2++;
+}
+
+package main;
+
+$a = 'toto';
+$b = \$a;
+
+$c = tie %hash, TIED_HASH;
+$d = tie @array, TIED_ARRAY;
+tie $scalar, TIED_SCALAR;
+
+$scalar = 'foo';
+$hash{'attribute'} = 'plain value';
+$array[0] = \$scalar;
+$array[1] = $c;
+$array[2] = \@array;
+$array[3] = "plaine scalaire";
+
+ at tied = (\$scalar, \@array, \%hash);
+%a = ('key', 'value', 1, 0, $a, $b, 'cvar', \$a, 'scalarref', \$scalar);
+ at a = ('first', 3, -4, -3.14159, 456, 4.5, $d, \$d,
+	$b, \$a, $a, $c, \$c, \%a, \@array, \%hash, \@tied);
+
+ok 1, defined($f = freeze(\@a));
+
+$dumped = &dump(\@a);
+ok 2, 1;
+
+$root = thaw($f);
+ok 3, defined $root;
+
+$got = &dump($root);
+ok 4, 1;
+
+ok 5, $got ne $dumped;		# our hooks did not handle refs in array
+
+$g = freeze($root);
+ok 6, length($f) == length($g);
+
+# Ensure the tied items in the retrieved image work
+ at old = ($scalar_fetch, $array_fetch, $hash_fetch);
+ at tied = ($tscalar, $tarray, $thash) = @{$root->[$#{$root}]};
+ at type = qw(SCALAR  ARRAY  HASH);
+
+ok 7, tied $$tscalar;
+ok 8, tied @{$tarray};
+ok 9, tied %{$thash};
+
+ at new = ($$tscalar, $tarray->[0], $thash->{'attribute'});
+ at new = ($scalar_fetch, $array_fetch, $hash_fetch);
+
+# Tests 10..15
+for ($i = 0; $i < @new; $i++) {
+	ok 10 + 2*$i, $new[$i] == $old[$i] + 1;		# Tests 10,12,14
+	ok 11 + 2*$i, ref $tied[$i] eq $type[$i];	# Tests 11,13,15
+}
+
+ok 16, $$tscalar eq 'foo';
+ok 17, $tarray->[3] eq 'plaine scalaire';
+ok 18, $thash->{'attribute'} eq 'plain value';
+
+# Ensure hooks were called
+ok 19, ($scalar_hook1 && $scalar_hook2);
+ok 20, ($array_hook1 && $array_hook2);
+ok 21, ($hash_hook1 && $hash_hook2);
+
+#
+# And now for the "blessed ref to tied hash" with "store hook" test...
+#
+
+my $bc = bless \%hash, 'FOO';		# FOO does not exist -> no hook
+my $bx = thaw freeze $bc;
+
+ok 22, ref $bx eq 'FOO';
+my $old_hash_fetch = $hash_fetch;
+my $v = $bx->{attribute};
+ok 23, $hash_fetch == $old_hash_fetch + 1;	# Still tied
+
+package TIED_HASH_REF;
+
+
+sub STORABLE_freeze {
+        my ($self, $cloning) = @_;
+        return if $cloning;
+        return('ref lost');
+}
+
+sub STORABLE_thaw {
+        my ($self, $cloning, $data) = @_;
+        return if $cloning;
+}
+
+package main;
+
+$bc = bless \%hash, 'TIED_HASH_REF';
+$bx = thaw freeze $bc;
+
+ok 24, ref $bx eq 'TIED_HASH_REF';
+$old_hash_fetch = $hash_fetch;
+$v = $bx->{attribute};
+ok 25, $hash_fetch == $old_hash_fetch + 1;	# Still tied
+

Added: trunk/orca/packages/Storable-1.0.11/t/recurse.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/recurse.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/recurse.t	Sat Jul 13 21:27:06 2002
@@ -0,0 +1,287 @@
+#!./perl
+
+# $Id: recurse.t,v 1.0.1.3 2001/02/17 12:28:33 ram Exp $
+#
+#  Copyright (c) 1995-2000, Raphael Manfredi
+#  
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
+#  
+# $Log: recurse.t,v $
+# Revision 1.0.1.3  2001/02/17 12:28:33  ram
+# patch8: ensure blessing occurs ASAP, specially designed for hooks
+#
+# Revision 1.0.1.2  2000/11/05 17:22:05  ram
+# patch6: stress hook a little more with refs to lexicals
+#
+# Revision 1.0.1.1  2000/09/17 16:48:05  ram
+# patch1: added test case for store hook bug
+#
+# Revision 1.0  2000/09/01 19:40:42  ram
+# Baseline for first official release.
+#
+
+require 't/dump.pl';
+sub ok;
+
+use Storable qw(freeze thaw dclone);
+
+print "1..32\n";
+
+package OBJ_REAL;
+
+use Storable qw(freeze thaw);
+
+ at x = ('a', 1);
+
+sub make { bless [], shift }
+
+sub STORABLE_freeze {
+	my $self = shift;
+	my $cloning = shift;
+	die "STORABLE_freeze" unless Storable::is_storing;
+	return (freeze(\@x), $self);
+}
+
+sub STORABLE_thaw {
+	my $self = shift;
+	my $cloning = shift;
+	my ($x, $obj) = @_;
+	die "STORABLE_thaw #1" unless $obj eq $self;
+	my $len = length $x;
+	my $a = thaw $x;
+	die "STORABLE_thaw #2" unless ref $a eq 'ARRAY';
+	die "STORABLE_thaw #3" unless @$a == 2 && $a->[0] eq 'a' && $a->[1] == 1;
+	@$self = @$a;
+	die "STORABLE_thaw #4" unless Storable::is_retrieving;
+}
+
+package OBJ_SYNC;
+
+ at x = ('a', 1);
+
+sub make { bless {}, shift }
+
+sub STORABLE_freeze {
+	my $self = shift;
+	my ($cloning) = @_;
+	return if $cloning;
+	return ("", \@x, $self);
+}
+
+sub STORABLE_thaw {
+	my $self = shift;
+	my ($cloning, $undef, $a, $obj) = @_;
+	die "STORABLE_thaw #1" unless $obj eq $self;
+	die "STORABLE_thaw #2" unless ref $a eq 'ARRAY' || @$a != 2;
+	$self->{ok} = $self;
+}
+
+package OBJ_SYNC2;
+
+use Storable qw(dclone);
+
+sub make {
+	my $self = bless {}, shift;
+	my ($ext) = @_;
+	$self->{sync} = OBJ_SYNC->make;
+	$self->{ext} = $ext;
+	return $self;
+}
+
+sub STORABLE_freeze {
+	my $self = shift;
+	my %copy = %$self;
+	my $r = \%copy;
+	my $t = dclone($r->{sync});
+	return ("", [$t, $self->{ext}], $r, $self, $r->{ext});
+}
+
+sub STORABLE_thaw {
+	my $self = shift;
+	my ($cloning, $undef, $a, $r, $obj, $ext) = @_;
+	die "STORABLE_thaw #1" unless $obj eq $self;
+	die "STORABLE_thaw #2" unless ref $a eq 'ARRAY';
+	die "STORABLE_thaw #3" unless ref $r eq 'HASH';
+	die "STORABLE_thaw #4" unless $a->[1] == $r->{ext};
+	$self->{ok} = $self;
+	($self->{sync}, $self->{ext}) = @$a;
+}
+
+package OBJ_REAL2;
+
+use Storable qw(freeze thaw);
+
+$MAX = 20;
+$recursed = 0;
+$hook_called = 0;
+
+sub make { bless [], shift }
+
+sub STORABLE_freeze {
+	my $self = shift;
+	$hook_called++;
+	return (freeze($self), $self) if ++$recursed < $MAX;
+	return ("no", $self);
+}
+
+sub STORABLE_thaw {
+	my $self = shift;
+	my $cloning = shift;
+	my ($x, $obj) = @_;
+	die "STORABLE_thaw #1" unless $obj eq $self;
+	$self->[0] = thaw($x) if $x ne "no";
+	$recursed--;
+}
+
+package main;
+
+my $real = OBJ_REAL->make;
+my $x = freeze $real;
+ok 1, 1;
+
+my $y = thaw $x;
+ok 2, 1;
+ok 3, $y->[0] eq 'a';
+ok 4, $y->[1] == 1;
+
+my $sync = OBJ_SYNC->make;
+$x = freeze $sync;
+ok 5, 1;
+
+$y = thaw $x;
+ok 6, 1;
+ok 7, $y->{ok} == $y;
+
+my $ext = [1, 2];
+$sync = OBJ_SYNC2->make($ext);
+$x = freeze [$sync, $ext];
+ok 8, 1;
+
+my $z = thaw $x;
+$y = $z->[0];
+ok 9, 1;
+ok 10, $y->{ok} == $y;
+ok 11, ref $y->{sync} eq 'OBJ_SYNC';
+ok 12, $y->{ext} == $z->[1];
+
+$real = OBJ_REAL2->make;
+$x = freeze $real;
+ok 13, 1;
+ok 14, $OBJ_REAL2::recursed == $OBJ_REAL2::MAX;
+ok 15, $OBJ_REAL2::hook_called == $OBJ_REAL2::MAX;
+
+$y = thaw $x;
+ok 16, 1;
+ok 17, $OBJ_REAL2::recursed == 0;
+
+$x = dclone $real;
+ok 18, 1;
+ok 19, ref $x eq 'OBJ_REAL2';
+ok 20, $OBJ_REAL2::recursed == 0;
+ok 21, $OBJ_REAL2::hook_called == 2 * $OBJ_REAL2::MAX;
+
+ok 22, !Storable::is_storing;
+ok 23, !Storable::is_retrieving;
+
+#
+# The following was a test-case that Salvador Ortiz Garcia <sog at msg.com.mx>
+# sent me, along with a proposed fix.
+#
+
+package Foo;
+
+sub new {
+	my $class = shift;
+	my $dat = shift;
+	return bless {dat => $dat}, $class;
+}
+
+package Bar;
+sub new {
+	my $class = shift;
+	return bless {
+		a => 'dummy',
+		b => [ 
+			Foo->new(1),
+			Foo->new(2), # Second instance of a Foo 
+		]
+	}, $class;
+}
+
+sub STORABLE_freeze {
+	my($self,$clonning) = @_;
+	return "$self->{a}", $self->{b};
+}
+
+sub STORABLE_thaw {
+	my($self,$clonning,$dummy,$o) = @_;
+	$self->{a} = $dummy;
+	$self->{b} = $o;
+}
+
+package main;
+
+my $bar = new Bar;
+my $bar2 = thaw freeze $bar;
+
+ok 24, ref($bar2) eq 'Bar';
+ok 25, ref($bar->{b}[0]) eq 'Foo';
+ok 26, ref($bar->{b}[1]) eq 'Foo';
+ok 27, ref($bar2->{b}[0]) eq 'Foo';
+ok 28, ref($bar2->{b}[1]) eq 'Foo';
+
+#
+# The following attempts to make sure blessed objects are blessed ASAP
+# at retrieve time.
+#
+
+package CLASS_1;
+
+sub make {
+	my $self = bless {}, shift;
+	return $self;
+}
+
+package CLASS_2;
+
+sub make {
+	my $self = bless {}, shift;
+	my ($o) = @_;
+	$self->{c1} = CLASS_1->make();
+	$self->{o} = $o;
+	$self->{c3} = bless CLASS_1->make(), "CLASS_3";
+	$o->set_c2($self);
+	return $self;
+}
+
+sub STORABLE_freeze {
+	my($self, $clonning) = @_;
+	return "", $self->{c1}, $self->{c3}, $self->{o};
+}
+
+sub STORABLE_thaw {
+	my($self, $clonning, $frozen, $c1, $c3, $o) = @_;
+	main::ok 29, ref $self eq "CLASS_2";
+	main::ok 30, ref $c1 eq "CLASS_1";
+	main::ok 31, ref $c3 eq "CLASS_3";
+	main::ok 32, ref $o eq "CLASS_OTHER";
+	$self->{c1} = $c1;
+	$self->{c3} = $c3;
+}
+
+package CLASS_OTHER;
+
+sub make {
+	my $self = bless {}, shift;
+	return $self;
+}
+
+sub set_c2 { $_[0]->{c2} = $_[1] }
+
+package main;
+
+my $o = CLASS_OTHER->make();
+my $c2 = CLASS_2->make($o);
+my $so = thaw freeze $o;
+

Added: trunk/orca/packages/Storable-1.0.11/t/overload.t
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/t/overload.t	(original)
+++ trunk/orca/packages/Storable-1.0.11/t/overload.t	Sat Jul 13 21:27:07 2002
@@ -0,0 +1,86 @@
+#!./perl
+
+# $Id: overload.t,v 1.0.1.1 2001/02/17 12:27:22 ram Exp $
+#
+#  Copyright (c) 1995-2000, Raphael Manfredi
+#  
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
+#  
+# $Log: overload.t,v $
+# Revision 1.0.1.1  2001/02/17 12:27:22  ram
+# patch8: added test for structures with indirect ref to overloaded
+#
+# Revision 1.0  2000/09/01 19:40:42  ram
+# Baseline for first official release.
+#
+
+require 't/dump.pl';
+sub ok;
+
+use Storable qw(freeze thaw);
+
+print "1..12\n";
+
+package OVERLOADED;
+
+use overload
+	'""' => sub { $_[0][0] };
+
+package main;
+
+$a = bless [77], OVERLOADED;
+
+$b = thaw freeze $a;
+ok 1, ref $b eq 'OVERLOADED';
+ok 2, "$b" eq "77";
+
+$c = thaw freeze \$a;
+ok 3, ref $c eq 'REF';
+ok 4, ref $$c eq 'OVERLOADED';
+ok 5, "$$c" eq "77";
+
+$d = thaw freeze [$a, $a];
+ok 6, "$d->[0]" eq "77";
+$d->[0][0]++;
+ok 7, "$d->[1]" eq "78";
+
+package REF_TO_OVER;
+
+sub make {
+	my $self = bless {}, shift;
+	my ($over) = @_;
+	$self->{over} = $over;
+	return $self;
+}
+
+package OVER;
+
+use overload
+	'+'		=> \&plus,
+	'""'	=> sub { ref $_[0] };
+
+sub plus {
+	return 314;
+}
+
+sub make {
+	my $self = bless {}, shift;
+	my $ref = REF_TO_OVER->make($self);
+	$self->{ref} = $ref;
+	return $self;
+}
+
+package main;
+
+$a = OVER->make();
+$b = thaw freeze $a;
+
+ok 8, ref $b eq 'OVER';
+ok 9, $a + $a == 314;
+ok 10, ref $b->{ref} eq 'REF_TO_OVER';
+ok 11, "$b->{ref}->{over}" eq "$b";
+ok 12, $b + $b == 314;
+
+1;
+

Modified: trunk/orca/packages/Storable-1.0.11/Storable.xs
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/Storable.xs	(original)
+++ trunk/orca/packages/Storable-1.0.11/Storable.xs	Sat Jul 13 21:27:07 2002
@@ -3,56 +3,57 @@
  */
 
 /*
- * $Id: Storable.xs,v 0.6.1.8 2000/03/02 22:20:35 ram Exp $
+ * $Id: Storable.xs,v 1.0.1.8 2001/03/15 00:20:55 ram Exp $
  *
- *  Copyright (c) 1995-1998, Raphael Manfredi
+ *  Copyright (c) 1995-2000, Raphael Manfredi
  *  
- *  You may redistribute only under the terms of the Artistic License,
- *  as specified in the README file that comes with the distribution.
+ *  You may redistribute only under the same terms as Perl 5, as specified
+ *  in the README file that comes with the distribution.
  *
  * $Log: Storable.xs,v $
- * Revision 0.6.1.8  2000/03/02 22:20:35  ram
- * patch9: include "patchlevel.h" for new perl 5.6
- * patch9: fixed "undef" bug in hash keys, reported by Albert N. Micheev
+ * Revision 1.0.1.8  2001/03/15 00:20:55  ram
+ * patch11: last version was wrongly compiling with assertions on
  *
- * Revision 0.6.1.7  2000/02/10 18:47:22  ram
- * patch8: added last_op_in_netorder() predicate
+ * Revision 1.0.1.7  2001/02/17 12:25:26  ram
+ * patch8: now bless objects ASAP at retrieve time
+ * patch8: added support for blessed ref to tied structures
  *
- * Revision 0.6.1.6  1999/10/19 19:23:34  ram
- * patch6: Fixed typo in macro that made threaded code not compilable
- * patch6: Changed detection of older perls (pre-5.005) by testing PATCHLEVEL
+ * Revision 1.0.1.6  2001/01/03 09:40:40  ram
+ * patch7: prototype and casting cleanup
+ * patch7: trace offending package when overloading cannot be restored
+ * patch7: made context cleanup safer to avoid dup freeing
  *
- * Revision 0.6.1.5  1999/09/14 20:12:29  ram
- * patch5: integrated "thread-safe" patch from Murray Nesbitt
- * patch5: try to avoid compilation warning on 64-bit CPUs
+ * Revision 1.0.1.5  2000/11/05 17:21:24  ram
+ * patch6: fixed severe "object lost" bug for STORABLE_freeze returns
  *
- * Revision 0.6.1.4  1999/07/12  12:37:01  ram
- * patch4: uses new internal PL_* naming convention.
+ * Revision 1.0.1.4  2000/10/26 17:11:04  ram
+ * patch5: auto requires module of blessed ref when STORABLE_thaw misses
  *
- * Revision 0.6.1.3  1998/07/03  11:36:09  ram
- * patch3: fixed compatibility (wrt 0.5 at 9) for retrieval of blessed refs
- * patch3: increased store() throughput significantly
+ * Revision 1.0.1.3  2000/09/29 19:49:57  ram
+ * patch3: avoid using "tainted" and "dirty" since Perl remaps them via cpp
  *
- * Revision 0.6.1.2  1998/06/22  09:00:04  ram
- * patch2: adjust refcnt of tied objects after calling sv_magic()
+ * Revision 1.0.1.2  2000/09/28 21:43:10  ram
+ * patch2: perls before 5.004_04 lack newSVpvn
  *
- * Revision 0.6.1.1  1998/06/12  09:46:48  ram
- * patch1: added workaround for persistent LVALUE-ness in perl5.004
- * patch1: now handles Perl immortal scalars explicitely
- * patch1: retrieval of non-immortal undef cannot be shared
+ * Revision 1.0.1.1  2000/09/17 16:47:49  ram
+ * patch1: now only taint retrieved data when source was tainted
+ * patch1: added support for UTF-8 strings
+ * patch1: fixed store hook bug: was allocating class id too soon
  *
- * Revision 0.6  1998/06/04  16:08:22  ram
- * Baseline for first beta release.
+ * Revision 1.0  2000/09/01 19:40:41  ram
+ * Baseline for first official release.
  *
  */
 
-#include "EXTERN.h"
-#include "perl.h"
-#include "patchlevel.h"		/* Perl's one, needed since 5.6 */
-#include "XSUB.h"
+#include <EXTERN.h>
+#include <perl.h>
+#include <patchlevel.h>		/* Perl's one, needed since 5.6 */
+#include <XSUB.h>
 
-/*#define DEBUGME /* Debug mode, turns assertions on as well */
-/*#define DASSERT /* Assertion mode */
+#if 0
+#define DEBUGME /* Debug mode, turns assertions on as well */
+#define DASSERT /* Assertion mode */
+#endif
 
 /*
  * Pre PerlIO time when none of USE_PERLIO and PERLIO_IS_STDIO is defined
@@ -72,6 +73,9 @@
 /*
  * Earlier versions of perl might be used, we can't assume they have the latest!
  */
+
+#ifndef PERL_VERSION		/* For perls < 5.6 */
+#define PERL_VERSION PATCHLEVEL
 #ifndef newRV_noinc
 #define newRV_noinc(sv)		((Sv = newRV(sv)), --SvREFCNT(SvRV(Sv)), Sv)
 #endif
@@ -79,23 +83,64 @@
 #define PL_sv_yes	sv_yes
 #define PL_sv_no	sv_no
 #define PL_sv_undef	sv_undef
+#if (SUBVERSION <= 4)		/* 5.004_04 has been reported to lack newSVpvn */
+#define newSVpvn newSVpv
 #endif
+#endif						/* PATCHLEVEL <= 4 */
 #ifndef HvSHAREKEYS_off
 #define HvSHAREKEYS_off(hv)	/* Ignore */
 #endif
+#ifndef AvFILLp				/* Older perls (<=5.003) lack AvFILLp */
+#define AvFILLp AvFILL
+#endif
+typedef double NV;			/* Older perls lack the NV type */
+#define	IVdf		"ld"	/* Various printf formats for Perl types */
+#define	UVuf		"lu"
+#define	UVof		"lo"
+#define	UVxf		"lx"
+#define INT2PTR(t,v) (t)(IV)(v)
+#define PTR2UV(v)    (unsigned long)(v)
+#endif						/* PERL_VERSION -- perls < 5.6 */
+
+#ifndef NVef				/* The following were not part of perl 5.6 */
+#if defined(USE_LONG_DOUBLE) && \
+	defined(HAS_LONG_DOUBLE) && defined(PERL_PRIfldbl)
+#define NVef		PERL_PRIeldbl
+#define NVff		PERL_PRIfldbl
+#define NVgf		PERL_PRIgldbl
+#else
+#define	NVef		"e"
+#define	NVff		"f"
+#define	NVgf		"g"
+#endif
+#endif
 
 #ifdef DEBUGME
+
 #ifndef DASSERT
 #define DASSERT
 #endif
-#define TRACEME(x)	do { PerlIO_stdoutf x; PerlIO_stdoutf("\n"); } while (0)
+
+/*
+ * TRACEME() will only output things when the $Storable::DEBUGME is true.
+ */
+
+#define TRACEME(x)	do {									\
+	if (SvTRUE(perl_get_sv("Storable::DEBUGME", TRUE)))	\
+		{ PerlIO_stdoutf x; PerlIO_stdoutf("\n"); }			\
+} while (0)
 #else
 #define TRACEME(x)
-#endif
+#endif	/* DEBUGME */
 
 #ifdef DASSERT
-#define ASSERT(x,y)	do { \
-	if (!x) { PerlIO_stdoutf y; PerlIO_stdoutf("\n"); }} while (0)
+#define ASSERT(x,y)	do {									\
+	if (!(x)) {												\
+		PerlIO_stdoutf("ASSERT FAILED (\"%s\", line %d): ",	\
+			__FILE__, __LINE__);							\
+		PerlIO_stdoutf y; PerlIO_stdoutf("\n");				\
+	}														\
+} while (0)
 #else
 #define ASSERT(x,y)
 #endif
@@ -107,7 +152,7 @@
 #define C(x) ((char) (x))	/* For markers with dynamic retrieval handling */
 
 #define SX_OBJECT	C(0)	/* Already stored object */
-#define SX_LSCALAR	C(1)	/* Scalar (string) forthcoming (length, data) */
+#define SX_LSCALAR	C(1)	/* Scalar (large binary) follows (length, data) */
 #define SX_ARRAY	C(2)	/* Array forthcominng (size, item list) */
 #define SX_HASH		C(3)	/* Hash forthcoming (size, key/value pair list) */
 #define SX_REF		C(4)	/* Reference to object forthcoming */
@@ -116,14 +161,22 @@
 #define SX_DOUBLE	C(7)	/* Double forthcoming */
 #define SX_BYTE		C(8)	/* (signed) byte forthcoming */
 #define SX_NETINT	C(9)	/* Integer in network order forthcoming */
-#define SX_SCALAR	C(10)	/* Scalar (small) forthcoming (length, data) */
+#define SX_SCALAR	C(10)	/* Scalar (binary, small) follows (length, data) */
 #define SX_TIED_ARRAY  C(11)  /* Tied array forthcoming */
 #define SX_TIED_HASH   C(12)  /* Tied hash forthcoming */
 #define SX_TIED_SCALAR C(13)  /* Tied scalar forthcoming */
 #define SX_SV_UNDEF	C(14)	/* Perl's immortal PL_sv_undef */
 #define SX_SV_YES	C(15)	/* Perl's immortal PL_sv_yes */
 #define SX_SV_NO	C(16)	/* Perl's immortal PL_sv_no */
-#define SX_ERROR	C(17)	/* Error */
+#define SX_BLESS	C(17)	/* Object is blessed */
+#define SX_IX_BLESS	C(18)	/* Object is blessed, classname given by index */
+#define SX_HOOK		C(19)	/* Stored via hook, user-defined */
+#define SX_OVERLOAD	C(20)	/* Overloaded reference */
+#define SX_TIED_KEY C(21)   /* Tied magic key forthcoming */
+#define SX_TIED_IDX C(22)   /* Tied magic index forthcoming */
+#define SX_UTF8STR	C(23)   /* UTF-8 string forthcoming (small) */
+#define SX_LUTF8STR	C(24)   /* UTF-8 string forthcoming (large) */
+#define SX_ERROR	C(25)	/* Error */
 
 /*
  * Those are only used to retrieve "old" pre-0.6 binary images.
@@ -135,15 +188,27 @@
 #define SX_VL_UNDEF	'V'		/* Undefined hash value */
 
 /*
- * Notification markers.
+ * Those are only used to retrieve "old" pre-0.7 binary images
  */
 
-#define SX_BLESS	'b'		/* Object is blessed, class name length <255 */
-#define SX_LG_BLESS	'B'		/* Object is blessed, class name length >255 */
+#define SX_CLASS	'b'		/* Object is blessed, class name length <255 */
+#define SX_LG_CLASS 'B'		/* Object is blessed, class name length >255 */
 #define SX_STORED	'X'		/* End of object */
 
-#define LG_BLESS	255		/* Large blessing classname length limit */
+/*
+ * Limits between short/long length representation.
+ */
+
 #define LG_SCALAR	255		/* Large scalar length limit */
+#define LG_BLESS	127		/* Large classname bless limit */
+
+/*
+ * Operation types
+ */
+
+#define ST_STORE	0x1		/* Store operation */
+#define ST_RETRIEVE	0x2		/* Retrieval operation */
+#define ST_CLONE	0x4		/* Deep cloning operation */
 
 /*
  * The following structure is used for hash table key retrieval. Since, when
@@ -165,15 +230,18 @@
 
 /*
  * At store time:
- * This hash table records the objects which have already been stored.
+ * An hash table records the objects which have already been stored.
  * Those are referred to as SX_OBJECT in the file, and their "tag" (i.e.
  * an arbitrary sequence number) is used to identify them.
  *
  * At retrieve time:
- * This array table records the objects which have already been retrieved,
+ * An array table records the objects which have already been retrieved,
  * as seen by the tag determind by counting the objects themselves. The
  * reference to that retrieved object is kept in the table, and is returned
  * when an SX_OBJECT is found bearing that same tag.
+ *
+ * The same processing is used to record "classname" for blessed objects:
+ * indexing by a hash at store time, and via an array at retrieve time.
  */
 
 typedef unsigned long stag_t;	/* Used by pre-0.6 binary format */
@@ -182,83 +250,147 @@
  * The following "thread-safe" related defines were contributed by
  * Murray Nesbitt <murray at activestate.com> and integrated by RAM, who
  * only renamed things a little bit to ensure consistency with surrounding
- * code.
- *
- * The patch itself is fairly inefficient since it performs a lookup in
- * some hash table at the start of every routine. It has to do that in order
- * to determine the proper context.
- *
- * The right solution, naturally, is to change all the signatures to propagate
- * the context down the call chain and only fetch the per-thread context only
- * once at the entry point before recursion begins. That's planned for some
- * day, when Perl's threading model will be stabilized.
+ * code.	-- RAM, 14/09/1999
  *
- *		-- RAM, 14/09/1999
+ * The original patch suffered from the fact that the stcxt_t structure
+ * was global.  Murray tried to minimize the impact on the code as much as
+ * possible.
+ *
+ * Starting with 0.7, Storable can be re-entrant, via the STORABLE_xxx hooks
+ * on objects.  Therefore, the notion of context needs to be generalized,
+ * threading or not.
  */
 
 #define MY_VERSION "Storable(" XS_VERSION ")"
 
-typedef struct {
+/*
+ * Fields s_tainted and s_dirty are prefixed with s_ because Perl's include
+ * files remap tainted and dirty when threading is enabled.  That's bad for
+ * perl to remap such common words.	-- RAM, 29/09/00
+ */
+
+typedef struct stcxt {
+	int entry;			/* flags recursion */
+	int optype;			/* type of traversal operation */
     HV *hseen;			/* which objects have been seen, store time */
+    AV *hook_seen;		/* which SVs were returned by STORABLE_freeze() */
     AV *aseen;			/* which objects have been seen, retrieve time */
+    HV *hclass;			/* which classnames have been seen, store time */
+    AV *aclass;			/* which classnames have been seen, retrieve time */
+    HV *hook;			/* cache for hook methods per class name */
     I32 tagnum;			/* incremented at store time for each seen object */
+    I32 classnum;		/* incremented at store time for each seen classname */
     int netorder;		/* true if network order used */
+    int s_tainted;		/* true if input source is tainted, at retrieve time */
     int forgive_me;		/* whether to be forgiving... */
     int canonical;		/* whether to store hashes sorted by key */
+	int s_dirty;		/* context is dirty due to CROAK() -- can be cleaned */
     struct extendable keybuf;	/* for hash key retrieval */
     struct extendable membuf;	/* for memory store/retrieve operations */
-} storable_cxt_t;
+	PerlIO *fio;		/* where I/O are performed, NULL for memory */
+	int ver_major;		/* major of version for retrieved object */
+	int ver_minor;		/* minor of version for retrieved object */
+	SV *(**retrieve_vtbl)();	/* retrieve dispatch table */
+	struct stcxt *prev;	/* contexts chained backwards in real recursion */
+} stcxt_t;
 
 #if defined(MULTIPLICITY) || defined(PERL_OBJECT) || defined(PERL_CAPI)
 
 #if (PATCHLEVEL <= 4) && (SUBVERSION < 68)
-#define dPERINTERP_SV 									\
+#define dSTCXT_SV 									\
 	SV *perinterp_sv = perl_get_sv(MY_VERSION, FALSE)
 #else	/* >= perl5.004_68 */
-#define dPERINTERP_SV									\
-	SV *perinterp_sv = *hv_fetch(PL_modglobal,			\
+#define dSTCXT_SV									\
+	SV *perinterp_sv = *hv_fetch(PL_modglobal,		\
 		MY_VERSION, sizeof(MY_VERSION)-1, TRUE)
 #endif	/* < perl5.004_68 */
 
-#define dPERINTERP_PTR(T,name)							\
-	T name = (T)(perinterp_sv && SvIOK(perinterp_sv)	\
-				? SvIVX(perinterp_sv) : NULL)
-#define dPERINTERP										\
-	dPERINTERP_SV;										\
-	dPERINTERP_PTR(storable_cxt_t *, PERINTERP)
-
-#define INIT_PERINTERP									\
-      dPERINTERP;										\
-      Newz(0,PERINTERP,1, storable_cxt_t);				\
-      sv_setiv(perinterp_sv, (IV)PERINTERP)
+#define dSTCXT_PTR(T,name)							\
+	T name = (perinterp_sv && SvIOK(perinterp_sv)	\
+				? INT2PTR(T, SvIVX(perinterp_sv)) : (T) 0)
+#define dSTCXT										\
+	dSTCXT_SV;										\
+	dSTCXT_PTR(stcxt_t *, cxt)
+
+#define INIT_STCXT									\
+      dSTCXT;										\
+      Newz(0, cxt, 1, stcxt_t);						\
+      sv_setiv(perinterp_sv, PTR2IV(cxt))
+
+#define SET_STCXT(x) do {							\
+	dSTCXT_SV;										\
+	sv_setiv(perinterp_sv, PTR2IV(x));				\
+} while (0)
 
 #else /* !MULTIPLICITY && !PERL_OBJECT && !PERL_CAPI */
 
-static storable_cxt_t Context;
-#define dPERINTERP typedef int _interp_DBI_dummy
-#define PERINTERP (&Context)
-#define INIT_PERINTERP
+static stcxt_t Context;
+static stcxt_t *Context_ptr = &Context;
+#define dSTCXT			stcxt_t *cxt = Context_ptr
+#define INIT_STCXT		dSTCXT
+#define SET_STCXT(x)	Context_ptr = x
 
 #endif /* MULTIPLICITY || PERL_OBJECT || PERL_CAPI */
 
-#define hseen           (PERINTERP->hseen)
-#define aseen           (PERINTERP->aseen)
-#define tagnum          (PERINTERP->tagnum)
-#define netorder        (PERINTERP->netorder)
-#define forgive_me      (PERINTERP->forgive_me)
-#define canonical       (PERINTERP->canonical)
-#define keybuf          (PERINTERP->keybuf)
-#define membuf          (PERINTERP->membuf)
+/*
+ * KNOWN BUG:
+ *   Croaking implies a memory leak, since we don't use setjmp/longjmp
+ *   to catch the exit and free memory used during store or retrieve
+ *   operations.  This is not too difficult to fix, but I need to understand
+ *   how Perl does it, and croaking is exceptional anyway, so I lack the
+ *   motivation to do it.
+ *
+ * The current workaround is to mark the context as dirty when croaking,
+ * so that data structures can be freed whenever we renter Storable code
+ * (but only *then*: it's a workaround, not a fix).
+ *
+ * This is also imperfect, because we don't really know how far they trapped
+ * the croak(), and when we were recursing, we won't be able to clean anything
+ * but the topmost context stacked.
+ */
+
+#define CROAK(x)	do { cxt->s_dirty = 1; croak x; } while (0)
 
 /*
  * End of "thread-safe" related definitions.
  */
 
 /*
+ * LOW_32BITS
+ *
+ * Keep only the low 32 bits of a pointer (used for tags, which are not
+ * really pointers).
+ */
+
+#if PTRSIZE <= 4
+#define LOW_32BITS(x)	((I32) (x))
+#else
+#define LOW_32BITS(x)	((I32) ((unsigned long) (x) & 0xffffffffUL))
+#endif
+
+/*
+ * oI, oS, oC
+ *
+ * Hack for Crays, where sizeof(I32) == 8, and which are big-endians.
+ * Used in the WLEN and RLEN macros.
+ */
+
+#if INTSIZE > 4
+#define oI(x)	((I32 *) ((char *) (x) + 4))
+#define oS(x)	((x) - 4)
+#define oC(x)	(x = 0)
+#define CRAY_HACK
+#else
+#define oI(x)	(x)
+#define oS(x)	(x)
+#define oC(x)
+#endif
+
+/*
  * key buffer handling
  */
-#define kbuf	keybuf.arena
-#define ksiz	keybuf.asiz
+#define kbuf	(cxt->keybuf).arena
+#define ksiz	(cxt->keybuf).asiz
 #define KBUFINIT() do {					\
 	if (!kbuf) {						\
 		TRACEME(("** allocating kbuf of 128 bytes")); \
@@ -277,10 +409,11 @@
 /*
  * memory buffer handling
  */
-#define mbase	membuf.arena
-#define msiz	membuf.asiz
-#define mptr	membuf.aptr
-#define mend	membuf.aend
+#define mbase	(cxt->membuf).arena
+#define msiz	(cxt->membuf).asiz
+#define mptr	(cxt->membuf).aptr
+#define mend	(cxt->membuf).aend
+
 #define MGROW	(1 << 13)
 #define MMASK	(MGROW - 1)
 
@@ -304,7 +437,8 @@
 		mend = mbase + msiz;			\
 } while (0)
 
-#define MBUF_SIZE()	(mptr - mbase)
+#define MBUF_TRUNC(x)	mptr = mbase + x
+#define MBUF_SIZE()		(mptr - mbase)
 
 /*
  * Use SvPOKp(), because SvPOK() fails on tainted scalars.
@@ -312,7 +446,7 @@
  */
 #define MBUF_LOAD(v) do {				\
 	if (!SvPOKp(v))						\
-		croak("Not a scalar string");	\
+		CROAK(("Not a scalar string"));	\
 	mptr = mbase = SvPV(v, msiz);		\
 	mend = mbase + msiz;				\
 } while (0)
@@ -339,6 +473,16 @@
 		return (SV *) 0;			\
 } while (0)
 
+#ifdef CRAY_HACK
+#define MBUF_GETINT(x) do {				\
+	oC(x);								\
+	if ((mptr + 4) <= mend) {			\
+		memcpy(oI(&x), mptr, 4);		\
+		mptr += 4;						\
+	} else								\
+		return (SV *) 0;				\
+} while (0)
+#else
 #define MBUF_GETINT(x) do {				\
 	if ((mptr + sizeof(int)) <= mend) {	\
 		if (int_aligned(mptr))			\
@@ -349,6 +493,7 @@
 	} else								\
 		return (SV *) 0;				\
 } while (0)
+#endif
 
 #define MBUF_READ(x,s) do {			\
 	if ((mptr + (s)) <= mend) {		\
@@ -377,6 +522,13 @@
 	}								\
 } while (0)
 
+#ifdef CRAY_HACK
+#define MBUF_PUTINT(i) do {			\
+	MBUF_CHK(4);					\
+	memcpy(mptr, oI(&i), 4);		\
+	mptr += 4;						\
+} while (0)
+#else
 #define MBUF_PUTINT(i) do {			\
 	MBUF_CHK(sizeof(int));			\
 	if (int_aligned(mptr))			\
@@ -385,6 +537,7 @@
 		memcpy(mptr, &i, sizeof(int));	\
 	mptr += sizeof(int);			\
 } while (0)
+#endif
 
 #define MBUF_WRITE(x,s) do {		\
 	MBUF_CHK(s);					\
@@ -392,16 +545,46 @@
 	mptr += s;						\
 } while (0)
 
+/*
+ * Possible return values for sv_type().
+ */
+
+#define svis_REF		0
+#define svis_SCALAR		1
+#define svis_ARRAY		2
+#define svis_HASH		3
+#define svis_TIED		4
+#define svis_TIED_ITEM	5
+#define svis_OTHER		6
+
+/*
+ * Flags for SX_HOOK.
+ */
+
+#define SHF_TYPE_MASK		0x03
+#define SHF_LARGE_CLASSLEN	0x04
+#define SHF_LARGE_STRLEN	0x08
+#define SHF_LARGE_LISTLEN	0x10
+#define SHF_IDX_CLASSNAME	0x20
+#define SHF_NEED_RECURSE	0x40
+#define SHF_HAS_LIST		0x80
 
-#define mbuf	membuf.arena
-#define msiz	membuf.asiz
+/*
+ * Types for SX_HOOK (last 2 bits in flags).
+ */
+
+#define SHT_SCALAR			0
+#define SHT_ARRAY			1
+#define SHT_HASH			2
+#define SHT_EXTRA			3		/* Read extra byte for type */
+
+/*
+ * The following are held in the "extra byte"...
+ */
 
-#define svis_REF	0
-#define svis_SCALAR	1
-#define svis_ARRAY	2
-#define svis_HASH	3
-#define svis_TIED	4
-#define svis_OTHER	5
+#define SHT_TSCALAR			4		/* 4 + 0 -- tied scalar */
+#define SHT_TARRAY			5		/* 4 + 1 -- tied array */
+#define SHT_THASH			6		/* 4 + 2 -- tied hash */
 
 /*
  * Before 0.6, the magic string was "perl-store" (binary version number 0).
@@ -410,74 +593,101 @@
  * been changed to "pst0" to allow an old image to be properly retrieved by
  * a newer Storable, but ensure a newer image cannot be retrieved with an
  * older version.
+ *
+ * At 0.7, objects are given the ability to serialize themselves, and the
+ * set of markers is extended, backward compatibility is not jeopardized,
+ * so the binary version number could have remained unchanged.  To correctly
+ * spot errors if a file making use of 0.7-specific extensions is given to
+ * 0.6 for retrieval, the binary version was moved to "2".  And I'm introducing
+ * a "minor" version, to better track this kind of evolution from now on.
+ * 
  */
 static char old_magicstr[] = "perl-store";	/* Magic number before 0.6 */
 static char magicstr[] = "pst0";			/* Used as a magic number */
 
-#define STORABLE_BINARY		1				/* Binary "version" number */
+#define STORABLE_BIN_MAJOR	2				/* Binary major "version" */
+#define STORABLE_BIN_MINOR	4				/* Binary minor "version" */
 
 /*
  * Useful store shortcuts...
  */
-#define PUTMARK(x) do {					\
-	if (!f)								\
-		MBUF_PUTC(x);					\
-	else if (PerlIO_putc(f, x) == EOF)	\
-		return -1;						\
+
+#define PUTMARK(x) do {						\
+	if (!cxt->fio)							\
+		MBUF_PUTC(x);						\
+	else if (PerlIO_putc(cxt->fio, x) == EOF)	\
+		return -1;							\
+} while (0)
+
+#define WRITE_I32(x)	do {			\
+	ASSERT(sizeof(x) == sizeof(I32), ("writing an I32"));	\
+	if (!cxt->fio)						\
+		MBUF_PUTINT(x);					\
+	else if (PerlIO_write(cxt->fio, oI(&x), oS(sizeof(x))) != oS(sizeof(x))) \
+		return -1;					\
 	} while (0)
 
 #ifdef HAS_HTONL
 #define WLEN(x)	do {				\
-	if (netorder) {					\
+	if (cxt->netorder) {			\
 		int y = (int) htonl(x);		\
-		if (!f)						\
+		if (!cxt->fio)				\
 			MBUF_PUTINT(y);			\
-		else if (PerlIO_write(f, &y, sizeof(y)) != sizeof(y))	\
+		else if (PerlIO_write(cxt->fio,oI(&y),oS(sizeof(y))) != oS(sizeof(y))) \
 			return -1;				\
 	} else {						\
-		if (!f)						\
+		if (!cxt->fio)				\
 			MBUF_PUTINT(x);			\
-		else if (PerlIO_write(f, &x, sizeof(x)) != sizeof(x))	\
+		else if (PerlIO_write(cxt->fio,oI(&x),oS(sizeof(x))) != oS(sizeof(x))) \
 			return -1;				\
 	}								\
 } while (0)
 #else
-#define WLEN(x)	do {				\
-	if (!f)							\
-		MBUF_PUTINT(x);				\
-	else if (PerlIO_write(f, &x, sizeof(x)) != sizeof(x))	\
-		return -1;					\
-	} while (0)
+#define WLEN(x)	WRITE_I32(x)
 #endif
 
 #define WRITE(x,y) do {						\
-	if (!f)									\
+	if (!cxt->fio)							\
 		MBUF_WRITE(x,y);					\
-	else if (PerlIO_write(f, x, y) != y)	\
+	else if (PerlIO_write(cxt->fio, x, y) != y)	\
 		return -1;							\
 	} while (0)
 
-#define STORE_SCALAR(pv, len) do {		\
+#define STORE_PV_LEN(pv, len, small, large) do {	\
 	if (len <= LG_SCALAR) {				\
 		unsigned char clen = (unsigned char) len;	\
-		PUTMARK(SX_SCALAR);				\
+		PUTMARK(small);					\
 		PUTMARK(clen);					\
 		if (len)						\
 			WRITE(pv, len);				\
 	} else {							\
-		PUTMARK(SX_LSCALAR);			\
+		PUTMARK(large);					\
 		WLEN(len);						\
 		WRITE(pv, len);					\
 	}									\
 } while (0)
 
+#define STORE_SCALAR(pv, len)	STORE_PV_LEN(pv, len, SX_SCALAR, SX_LSCALAR)
+
 /*
- * Store undef in arrays and hashes without recusrsing through store().
+ * Conditional UTF8 support.
+ * On non-UTF8 perls, UTF8 strings are returned as normal strings.
+ *
+ */
+#ifdef SvUTF8_on
+#define STORE_UTF8STR(pv, len)	STORE_PV_LEN(pv, len, SX_UTF8STR, SX_LUTF8STR)
+#else
+#define SvUTF8(sv) 0
+#define STORE_UTF8STR(pv, len) CROAK(("panic: storing UTF8 in non-UTF8 perl"))
+#define SvUTF8_on(sv) CROAK(("Cannot retrieve UTF8 data in non-UTF8 perl"))
+#endif
+
+/*
+ * Store undef in arrays and hashes without recursing through store().
  */
 #define STORE_UNDEF() do {				\
-	tagnum++;							\
+	cxt->tagnum++;						\
 	PUTMARK(SX_UNDEF);					\
-	PUTMARK(SX_STORED);					\
 } while (0)
 
 /*
@@ -485,47 +695,52 @@
  */
 
 #define GETCHAR() \
-	(f ? PerlIO_getc(f) : (mptr >= mend ? EOF : (int) *mptr++))
+	(cxt->fio ? PerlIO_getc(cxt->fio) : (mptr >= mend ? EOF : (int) *mptr++))
 
-#define GETMARK(x) do {						\
-	if (!f)									\
-		MBUF_GETC(x);						\
-	else if ((x = PerlIO_getc(f)) == EOF)	\
-		return (SV *) 0;					\
+#define GETMARK(x) do {							\
+	if (!cxt->fio)								\
+		MBUF_GETC(x);							\
+	else if ((int) (x = PerlIO_getc(cxt->fio)) == EOF)	\
+		return (SV *) 0;						\
 } while (0)
 
-#ifdef HAS_NTOHL
-#define RLEN(x)	do {					\
-	if (!f)								\
+#define READ_I32(x)	do {				\
+	ASSERT(sizeof(x) == sizeof(I32), ("reading an I32"));	\
+	oC(x);								\
+	if (!cxt->fio)						\
 		MBUF_GETINT(x);					\
-	else if (PerlIO_read(f, &x, sizeof(x)) != sizeof(x))	\
+	else if (PerlIO_read(cxt->fio, oI(&x), oS(sizeof(x))) != oS(sizeof(x)))	\
 		return (SV *) 0;				\
-	if (netorder)						\
-		x = (int) ntohl(x);				\
 } while (0)
-#else
+
+#ifdef HAS_NTOHL
 #define RLEN(x)	do {					\
-	if (!f)								\
+	oC(x);								\
+	if (!cxt->fio)						\
 		MBUF_GETINT(x);					\
-	else if (PerlIO_read(f, &x, sizeof(x)) != sizeof(x))	\
+	else if (PerlIO_read(cxt->fio, oI(&x), oS(sizeof(x))) != oS(sizeof(x)))	\
 		return (SV *) 0;				\
+	if (cxt->netorder)					\
+		x = (int) ntohl(x);				\
 } while (0)
+#else
+#define RLEN(x) READ_I32(x)
 #endif
 
-#define READ(x,y) do {					\
-	if (!f)								\
-		MBUF_READ(x, y);				\
-	else if (PerlIO_read(f, x, y) != y)	\
-		return (SV *) 0;				\
+#define READ(x,y) do {						\
+	if (!cxt->fio)							\
+		MBUF_READ(x, y);					\
+	else if (PerlIO_read(cxt->fio, x, y) != y)	\
+		return (SV *) 0;					\
 } while (0)
 
-#define SAFEREAD(x,y,z) do { 				\
-	if (!f)									\
-		MBUF_SAFEREAD(x,y,z);				\
-	else if (PerlIO_read(f, x, y) != y)	 {	\
-		sv_free(z);							\
-		return (SV *) 0;					\
-	}										\
+#define SAFEREAD(x,y,z) do { 					\
+	if (!cxt->fio)								\
+		MBUF_SAFEREAD(x,y,z);					\
+	else if (PerlIO_read(cxt->fio, x, y) != y)	 {	\
+		sv_free(z);								\
+		return (SV *) 0;						\
+	}											\
 } while (0)
 
 /*
@@ -533,154 +748,943 @@
  * given tag 'tagnum', has been retrieved. Next time we see an SX_OBJECT marker,
  * we'll therefore know where it has been retrieved and will be able to
  * share the same reference, as in the original stored memory image.
+ *
+ * We also need to bless objects ASAP for hooks (which may compute "ref $x"
+ * on the objects given to STORABLE_thaw and expect that to be defined), and
+ * also for overloaded objects (for which we might not find the stash if the
+ * object is not blessed yet--this might occur for overloaded objects that
+ * refer to themselves indirectly: if we blessed upon return from a sub
+ * retrieve(), the SX_OBJECT marker we'd found could not have overloading
+ * restored on it because the underlying object would not be blessed yet!).
+ *
+ * To achieve that, the class name of the last retrieved object is passed down
+ * recursively, and the first SEEN() call for which the class name is not NULL
+ * will bless the object.
  */
-#define SEEN(y) do {						\
+#define SEEN(y,c) do {						\
 	if (!y)									\
 		return (SV *) 0;					\
-	if (av_store(aseen, tagnum++, SvREFCNT_inc(y)) == 0) \
+	if (av_store(cxt->aseen, cxt->tagnum++, SvREFCNT_inc(y)) == 0) \
 		return (SV *) 0;					\
-	TRACEME(("aseen(#%d) = 0x%lx (refcnt=%d)", tagnum-1, \
-		(unsigned long) y, SvREFCNT(y)-1)); \
-	} while (0)
+	TRACEME(("aseen(#%d) = 0x%"UVxf" (refcnt=%d)", cxt->tagnum-1, \
+		 PTR2UV(y), SvREFCNT(y)-1));		\
+	if (c)									\
+		BLESS((SV *) (y), c);				\
+} while (0)
+
+/*
+ * Bless `s' in `p', via a temporary reference, required by sv_bless().
+ */
+#define BLESS(s,p) do {					\
+	SV *ref;								\
+	HV *stash;								\
+	TRACEME(("blessing 0x%"UVxf" in %s", PTR2UV(s), (p))); \
+	stash = gv_stashpv((p), TRUE);			\
+	ref = newRV_noinc(s);					\
+	(void) sv_bless(ref, stash);			\
+	SvRV(ref) = 0;							\
+	SvREFCNT_dec(ref);						\
+} while (0)
 
 static int store();
-static SV *retrieve();
+static SV *retrieve(stcxt_t *cxt, char *cname);
 
 /*
- * store_ref
+ * Dynamic dispatching table for SV store.
+ */
+
+static int store_ref(stcxt_t *cxt, SV *sv);
+static int store_scalar(stcxt_t *cxt, SV *sv);
+static int store_array(stcxt_t *cxt, AV *av);
+static int store_hash(stcxt_t *cxt, HV *hv);
+static int store_tied(stcxt_t *cxt, SV *sv);
+static int store_tied_item(stcxt_t *cxt, SV *sv);
+static int store_other(stcxt_t *cxt, SV *sv);
+static int store_blessed(stcxt_t *cxt, SV *sv, int type, HV *pkg);
+
+static int (*sv_store[])(stcxt_t *cxt, SV *sv) = {
+	store_ref,										/* svis_REF */
+	store_scalar,									/* svis_SCALAR */
+	(int (*)(stcxt_t *cxt, SV *sv)) store_array,	/* svis_ARRAY */
+	(int (*)(stcxt_t *cxt, SV *sv)) store_hash,		/* svis_HASH */
+	store_tied,										/* svis_TIED */
+	store_tied_item,								/* svis_TIED_ITEM */
+	store_other,									/* svis_OTHER */
+};
+
+#define SV_STORE(x)	(*sv_store[x])
+
+/*
+ * Dynamic dispatching tables for SV retrieval.
+ */
+
+static SV *retrieve_lscalar(stcxt_t *cxt, char *cname);
+static SV *retrieve_lutf8str(stcxt_t *cxt, char *cname);
+static SV *old_retrieve_array(stcxt_t *cxt, char *cname);
+static SV *old_retrieve_hash(stcxt_t *cxt, char *cname);
+static SV *retrieve_ref(stcxt_t *cxt, char *cname);
+static SV *retrieve_undef(stcxt_t *cxt, char *cname);
+static SV *retrieve_integer(stcxt_t *cxt, char *cname);
+static SV *retrieve_double(stcxt_t *cxt, char *cname);
+static SV *retrieve_byte(stcxt_t *cxt, char *cname);
+static SV *retrieve_netint(stcxt_t *cxt, char *cname);
+static SV *retrieve_scalar(stcxt_t *cxt, char *cname);
+static SV *retrieve_utf8str(stcxt_t *cxt, char *cname);
+static SV *retrieve_tied_array(stcxt_t *cxt, char *cname);
+static SV *retrieve_tied_hash(stcxt_t *cxt, char *cname);
+static SV *retrieve_tied_scalar(stcxt_t *cxt, char *cname);
+static SV *retrieve_other(stcxt_t *cxt, char *cname);
+
+static SV *(*sv_old_retrieve[])(stcxt_t *cxt, char *cname) = {
+	0,			/* SX_OBJECT -- entry unused dynamically */
+	retrieve_lscalar,		/* SX_LSCALAR */
+	old_retrieve_array,		/* SX_ARRAY -- for pre-0.6 binaries */
+	old_retrieve_hash,		/* SX_HASH -- for pre-0.6 binaries */
+	retrieve_ref,			/* SX_REF */
+	retrieve_undef,			/* SX_UNDEF */
+	retrieve_integer,		/* SX_INTEGER */
+	retrieve_double,		/* SX_DOUBLE */
+	retrieve_byte,			/* SX_BYTE */
+	retrieve_netint,		/* SX_NETINT */
+	retrieve_scalar,		/* SX_SCALAR */
+	retrieve_tied_array,	/* SX_ARRAY */
+	retrieve_tied_hash,		/* SX_HASH */
+	retrieve_tied_scalar,	/* SX_SCALAR */
+	retrieve_other,			/* SX_SV_UNDEF not supported */
+	retrieve_other,			/* SX_SV_YES not supported */
+	retrieve_other,			/* SX_SV_NO not supported */
+	retrieve_other,			/* SX_BLESS not supported */
+	retrieve_other,			/* SX_IX_BLESS not supported */
+	retrieve_other,			/* SX_HOOK not supported */
+	retrieve_other,			/* SX_OVERLOADED not supported */
+	retrieve_other,			/* SX_TIED_KEY not supported */
+	retrieve_other,			/* SX_TIED_IDX not supported */
+	retrieve_other,			/* SX_UTF8STR not supported */
+	retrieve_other,			/* SX_LUTF8STR not supported */
+	retrieve_other,			/* SX_ERROR */
+};
+
+static SV *retrieve_array(stcxt_t *cxt, char *cname);
+static SV *retrieve_hash(stcxt_t *cxt, char *cname);
+static SV *retrieve_sv_undef(stcxt_t *cxt, char *cname);
+static SV *retrieve_sv_yes(stcxt_t *cxt, char *cname);
+static SV *retrieve_sv_no(stcxt_t *cxt, char *cname);
+static SV *retrieve_blessed(stcxt_t *cxt, char *cname);
+static SV *retrieve_idx_blessed(stcxt_t *cxt, char *cname);
+static SV *retrieve_hook(stcxt_t *cxt, char *cname);
+static SV *retrieve_overloaded(stcxt_t *cxt, char *cname);
+static SV *retrieve_tied_key(stcxt_t *cxt, char *cname);
+static SV *retrieve_tied_idx(stcxt_t *cxt, char *cname);
+
+static SV *(*sv_retrieve[])(stcxt_t *cxt, char *cname) = {
+	0,			/* SX_OBJECT -- entry unused dynamically */
+	retrieve_lscalar,		/* SX_LSCALAR */
+	retrieve_array,			/* SX_ARRAY */
+	retrieve_hash,			/* SX_HASH */
+	retrieve_ref,			/* SX_REF */
+	retrieve_undef,			/* SX_UNDEF */
+	retrieve_integer,		/* SX_INTEGER */
+	retrieve_double,		/* SX_DOUBLE */
+	retrieve_byte,			/* SX_BYTE */
+	retrieve_netint,		/* SX_NETINT */
+	retrieve_scalar,		/* SX_SCALAR */
+	retrieve_tied_array,	/* SX_ARRAY */
+	retrieve_tied_hash,		/* SX_HASH */
+	retrieve_tied_scalar,	/* SX_SCALAR */
+	retrieve_sv_undef,		/* SX_SV_UNDEF */
+	retrieve_sv_yes,		/* SX_SV_YES */
+	retrieve_sv_no,			/* SX_SV_NO */
+	retrieve_blessed,		/* SX_BLESS */
+	retrieve_idx_blessed,	/* SX_IX_BLESS */
+	retrieve_hook,			/* SX_HOOK */
+	retrieve_overloaded,	/* SX_OVERLOAD */
+	retrieve_tied_key,		/* SX_TIED_KEY */
+	retrieve_tied_idx,		/* SX_TIED_IDX */
+	retrieve_utf8str,		/* SX_UTF8STR  */
+	retrieve_lutf8str,		/* SX_LUTF8STR */
+	retrieve_other,			/* SX_ERROR */
+};
+
+#define RETRIEVE(c,x) (*(c)->retrieve_vtbl[(x) >= SX_ERROR ? SX_ERROR : (x)])
+
+static SV *mbuf2sv(void);
+
+/***
+ *** Context management.
+ ***/
+
+/*
+ * init_perinterp
  *
- * Store a reference.
- * Layout is SX_REF <object>.
+ * Called once per "thread" (interpreter) to initialize some global context.
  */
-static int store_ref(f, sv)
-PerlIO *f;
-SV *sv;
+static void init_perinterp(void)
 {
-	dPERINTERP;
-	TRACEME(("store_ref (0x%lx)", (unsigned long) sv));
+    INIT_STCXT;
 
-	PUTMARK(SX_REF);
-	sv = SvRV(sv);
-	return store(f, sv);
+    cxt->netorder = 0;		/* true if network order used */
+    cxt->forgive_me = -1;	/* whether to be forgiving... */
 }
 
 /*
- * store_scalar
- *
- * Store a scalar.
+ * init_store_context
  *
- * Layout is SX_LSCALAR <length> <data>, SX_SCALAR <lenght> <data> or SX_UNDEF.
- * The <data> section is omitted if <length> is 0.
- *
- * If integer or double, the layout is SX_INTEGER <data> or SX_DOUBLE <data>.
- * Small integers (within [-127, +127]) are stored as SX_BYTE <byte>.
+ * Initialize a new store context for real recursion.
  */
-static int store_scalar(f, sv)
-PerlIO *f;
-SV *sv;
+static void init_store_context(
+	stcxt_t *cxt,
+	PerlIO *f,
+	int optype,
+	int network_order)
 {
-	dPERINTERP;
-	IV iv;
-	char *pv;
-	STRLEN len;
-	U32 flags = SvFLAGS(sv);			/* "cc -O" may put it in register */
+	TRACEME(("init_store_context"));
 
-	TRACEME(("store_scalar (0x%lx)", (unsigned long) sv));
+	cxt->netorder = network_order;
+	cxt->forgive_me = -1;			/* Fetched from perl if needed */
+	cxt->canonical = -1;			/* Idem */
+	cxt->tagnum = -1;				/* Reset tag numbers */
+	cxt->classnum = -1;				/* Reset class numbers */
+	cxt->fio = f;					/* Where I/O are performed */
+	cxt->optype = optype;			/* A store, or a deep clone */
+	cxt->entry = 1;					/* No recursion yet */
 
 	/*
-	 * For efficiency, break the SV encapsulation by peaking at the flags
-	 * directly without using the Perl macros to avoid dereferencing
-	 * sv->sv_flags each time we wish to check the flags.
+	 * The `hseen' table is used to keep track of each SV stored and their
+	 * associated tag numbers is special. It is "abused" because the
+	 * values stored are not real SV, just integers cast to (SV *),
+	 * which explains the freeing below.
+	 *
+	 * It is also one possible bottlneck to achieve good storing speed,
+	 * so the "shared keys" optimization is turned off (unlikely to be
+	 * of any use here), and the hash table is "pre-extended". Together,
+	 * those optimizations increase the throughput by 12%.
 	 */
 
-	if (!(flags & SVf_OK)) {			/* !SvOK(sv) */
-		if (sv == &PL_sv_undef) {
-			TRACEME(("immortal undef"));
-			PUTMARK(SX_SV_UNDEF);
-		} else {
-			TRACEME(("undef at 0x%x", sv));
-			PUTMARK(SX_UNDEF);
-		}
-		return 0;
-	}
+	cxt->hseen = newHV();			/* Table where seen objects are stored */
+	HvSHAREKEYS_off(cxt->hseen);
 
 	/*
-	 * Always store the string representation of a scalar if it exists.
-	 * Gisle Aas provided me with this test case, better than a long speach:
+	 * The following does not work well with perl5.004_04, and causes
+	 * a core dump later on, in a completely unrelated spot, which
+	 * makes me think there is a memory corruption going on.
 	 *
-	 *  perl -MDevel::Peek -le '$a="abc"; $a+0; Dump($a)'
-	 *  SV = PVNV(0x80c8520)
-	 *       REFCNT = 1
-	 *       FLAGS = (NOK,POK,pNOK,pPOK)
-	 *       IV = 0
-	 *       NV = 0
-	 *       PV = 0x80c83d0 "abc"\0
-	 *       CUR = 3
-	 *       LEN = 4
+	 * Calling hv_ksplit(hseen, HBUCKETS) instead of manually hacking
+	 * it below does not make any difference. It seems to work fine
+	 * with perl5.004_68 but given the probable nature of the bug,
+	 * that does not prove anything.
 	 *
-	 * Write SX_SCALAR, length, followed by the actual data.
+	 * It's a shame because increasing the amount of buckets raises
+	 * store() throughput by 5%, but until I figure this out, I can't
+	 * allow for this to go into production.
 	 *
-	 * Otherwise, write an SX_BYTE, SX_INTEGER or an SX_DOUBLE as
-	 * appropriate, followed by the actual (binary) data. A double
-	 * is written as a string if network order, for portability.
+	 * It is reported fixed in 5.005, hence the #if.
+	 */
+#if PERL_VERSION >= 5
+#define HBUCKETS	4096				/* Buckets for %hseen */
+	HvMAX(cxt->hseen) = HBUCKETS - 1;	/* keys %hseen = $HBUCKETS; */
+#endif
+
+	/*
+	 * The `hclass' hash uses the same settings as `hseen' above, but it is
+	 * used to assign sequential tags (numbers) to class names for blessed
+	 * objects.
 	 *
-	 * NOTE: instead of using SvNOK(sv), we test for SvNOKp(sv).
-	 * The reason is that when the scalar value is tainted, the SvNOK(sv)
-	 * value is false.
+	 * We turn the shared key optimization on.
+	 */
+
+	cxt->hclass = newHV();			/* Where seen classnames are stored */
+
+#if PERL_VERSION >= 5
+	HvMAX(cxt->hclass) = HBUCKETS - 1;	/* keys %hclass = $HBUCKETS; */
+#endif
+
+	/*
+	 * The `hook' hash table is used to keep track of the references on
+	 * the STORABLE_freeze hook routines, when found in some class name.
 	 *
-	 * The test for a read-only scalar with both POK and NOK set is meant
-	 * to quickly detect &PL_sv_yes and &PL_sv_no without having to pay the
-	 * address comparison for each scalar we store.
+	 * It is assumed that the inheritance tree will not be changed during
+	 * storing, and that no new method will be dynamically created by the
+	 * hooks.
 	 */
 
-#define SV_MAYBE_IMMORTAL (SVf_READONLY|SVf_POK|SVf_NOK)
+	cxt->hook = newHV();			/* Table where hooks are cached */
 
-	if ((flags & SV_MAYBE_IMMORTAL) == SV_MAYBE_IMMORTAL) {
-		if (sv == &PL_sv_yes) {
-			TRACEME(("immortal yes"));
-			PUTMARK(SX_SV_YES);
-		} else if (sv == &PL_sv_no) {
-			TRACEME(("immortal no"));
-			PUTMARK(SX_SV_NO);
-		} else {
-			pv = SvPV(sv, len);			/* We know it's SvPOK */
-			goto string;				/* Share code below */
-		}
-	} else if (flags & SVp_POK) {		/* SvPOKp(sv) => string */
-		pv = SvPV(sv, len);
+	/*
+	 * The `hook_seen' array keeps track of all the SVs returned by
+	 * STORABLE_freeze hooks for us to serialize, so that they are not
+	 * reclaimed until the end of the serialization process.  Each SV is
+	 * only stored once, the first time it is seen.
+	 */
 
-		/*
-		 * Will come here from below with pv and len set if double & netorder,
+	cxt->hook_seen = newAV();		/* Lists SVs returned by STORABLE_freeze */
+}
+
+/*
+ * clean_store_context
+ *
+ * Clean store context by
+ */
+static void clean_store_context(stcxt_t *cxt)
+{
+	HE *he;
+
+	TRACEME(("clean_store_context"));
+
+	ASSERT(cxt->optype & ST_STORE, ("was performing a store()"));
+
+	/*
+	 * Insert real values into hashes where we stored faked pointers.
+	 */
+
+	hv_iterinit(cxt->hseen);
+	while (he = hv_iternext(cxt->hseen))
+		HeVAL(he) = &PL_sv_undef;
+
+	hv_iterinit(cxt->hclass);
+	while (he = hv_iternext(cxt->hclass))
+		HeVAL(he) = &PL_sv_undef;
+
+	/*
+	 * And now dispose of them...
+	 *
+	 * The surrounding if() protection has been added because there might be
+	 * some cases where this routine is called more than once, during
+	 * exceptionnal events.  This was reported by Marc Lehmann when Storable
+	 * is executed from mod_perl, and the fix was suggested by him.
+	 * 		-- RAM, 20/12/2000
+	 */
+
+	if (cxt->hseen) {
+		HV *hseen = cxt->hseen;
+		cxt->hseen = 0;
+		hv_undef(hseen);
+		sv_free((SV *) hseen);
+	}
+
+	if (cxt->hclass) {
+		HV *hclass = cxt->hclass;
+		cxt->hclass = 0;
+		hv_undef(hclass);
+		sv_free((SV *) hclass);
+	}
+
+	if (cxt->hook) {
+		HV *hook = cxt->hook;
+		cxt->hook = 0;
+		hv_undef(hook);
+		sv_free((SV *) hook);
+	}
+
+	if (cxt->hook_seen) {
+		AV *hook_seen = cxt->hook_seen;
+		cxt->hook_seen = 0;
+		av_undef(hook_seen);
+		sv_free((SV *) hook_seen);
+	}
+
+	cxt->entry = 0;
+	cxt->s_dirty = 0;
+}
+
+/*
+ * init_retrieve_context
+ *
+ * Initialize a new retrieve context for real recursion.
+ */
+static void init_retrieve_context(stcxt_t *cxt, int optype, int is_tainted)
+{
+	TRACEME(("init_retrieve_context"));
+
+	/*
+	 * The hook hash table is used to keep track of the references on
+	 * the STORABLE_thaw hook routines, when found in some class name.
+	 *
+	 * It is assumed that the inheritance tree will not be changed during
+	 * storing, and that no new method will be dynamically created by the
+	 * hooks.
+	 */
+
+	cxt->hook  = newHV();			/* Caches STORABLE_thaw */
+
+	/*
+	 * If retrieving an old binary version, the cxt->retrieve_vtbl variable
+	 * was set to sv_old_retrieve. We'll need a hash table to keep track of
+	 * the correspondance between the tags and the tag number used by the
+	 * new retrieve routines.
+	 */
+
+	cxt->hseen = (cxt->retrieve_vtbl == sv_old_retrieve) ? newHV() : 0;
+
+	cxt->aseen = newAV();			/* Where retrieved objects are kept */
+	cxt->aclass = newAV();			/* Where seen classnames are kept */
+	cxt->tagnum = 0;				/* Have to count objects... */
+	cxt->classnum = 0;				/* ...and class names as well */
+	cxt->optype = optype;
+	cxt->s_tainted = is_tainted;
+	cxt->entry = 1;					/* No recursion yet */
+}
+
+/*
+ * clean_retrieve_context
+ *
+ * Clean retrieve context by
+ */
+static void clean_retrieve_context(stcxt_t *cxt)
+{
+	TRACEME(("clean_retrieve_context"));
+
+	ASSERT(cxt->optype & ST_RETRIEVE, ("was performing a retrieve()"));
+
+	if (cxt->aseen) {
+		AV *aseen = cxt->aseen;
+		cxt->aseen = 0;
+		av_undef(aseen);
+		sv_free((SV *) aseen);
+	}
+
+	if (cxt->aclass) {
+		AV *aclass = cxt->aclass;
+		cxt->aclass = 0;
+		av_undef(aclass);
+		sv_free((SV *) aclass);
+	}
+
+	if (cxt->hook) {
+		HV *hook = cxt->hook;
+		cxt->hook = 0;
+		hv_undef(hook);
+		sv_free((SV *) hook);
+	}
+
+	if (cxt->hseen) {
+		HV *hseen = cxt->hseen;
+		cxt->hseen = 0;
+		hv_undef(hseen);
+		sv_free((SV *) hseen);		/* optional HV, for backward compat. */
+	}
+
+	cxt->entry = 0;
+	cxt->s_dirty = 0;
+}
+
+/*
+ * clean_context
+ *
+ * A workaround for the CROAK bug: cleanup the last context.
+ */
+static void clean_context(cxt)
+stcxt_t *cxt;
+{
+	TRACEME(("clean_context"));
+
+	ASSERT(cxt->s_dirty, ("dirty context"));
+
+	if (cxt->optype & ST_RETRIEVE)
+		clean_retrieve_context(cxt);
+	else
+		clean_store_context(cxt);
+
+	ASSERT(!cxt->s_dirty, ("context is clean"));
+}
+
+/*
+ * allocate_context
+ *
+ * Allocate a new context and push it on top of the parent one.
+ * This new context is made globally visible via SET_STCXT().
+ */
+static stcxt_t *allocate_context(parent_cxt)
+stcxt_t *parent_cxt;
+{
+	stcxt_t *cxt;
+
+	TRACEME(("allocate_context"));
+
+	ASSERT(!parent_cxt->s_dirty, ("parent context clean"));
+
+	Newz(0, cxt, 1, stcxt_t);
+	cxt->prev = parent_cxt;
+	SET_STCXT(cxt);
+
+	return cxt;
+}
+
+/*
+ * free_context
+ *
+ * Free current context, which cannot be the "root" one.
+ * Make the context underneath globally visible via SET_STCXT().
+ */
+static void free_context(cxt)
+stcxt_t *cxt;
+{
+	stcxt_t *prev = cxt->prev;
+
+	TRACEME(("free_context"));
+
+	ASSERT(!cxt->s_dirty, ("clean context"));
+	ASSERT(prev, ("not freeing root context"));
+
+	if (kbuf)
+		Safefree(kbuf);
+	if (mbase)
+		Safefree(mbase);
+
+	Safefree(cxt);
+	SET_STCXT(prev);
+}
+
+/***
+ *** Predicates.
+ ***/
+
+/*
+ * is_storing
+ *
+ * Tells whether we're in the middle of a store operation.
+ */
+int is_storing(void)
+{
+	dSTCXT;
+
+	return cxt->entry && (cxt->optype & ST_STORE);
+}
+
+/*
+ * is_retrieving
+ *
+ * Tells whether we're in the middle of a retrieve operation.
+ */
+int is_retrieving(void)
+{
+	dSTCXT;
+
+	return cxt->entry && (cxt->optype & ST_RETRIEVE);
+}
+
+/*
+ * last_op_in_netorder
+ *
+ * Returns whether last operation was made using network order.
+ *
+ * This is typically out-of-band information that might prove useful
+ * to people wishing to convert native to network order data when used.
+ */
+int last_op_in_netorder(void)
+{
+	dSTCXT;
+
+	return cxt->netorder;
+}
+
+/***
+ *** Hook lookup and calling routines.
+ ***/
+
+/*
+ * pkg_fetchmeth
+ *
+ * A wrapper on gv_fetchmethod_autoload() which caches results.
+ *
+ * Returns the routine reference as an SV*, or null if neither the package
+ * nor its ancestors know about the method.
+ */
+static SV *pkg_fetchmeth(
+	HV *cache,
+	HV *pkg,
+	char *method)
+{
+	GV *gv;
+	SV *sv;
+	SV **svh;
+
+	/*
+	 * The following code is the same as the one performed by UNIVERSAL::can
+	 * in the Perl core.
+	 */
+
+	gv = gv_fetchmethod_autoload(pkg, method, FALSE);
+	if (gv && isGV(gv)) {
+		sv = newRV((SV*) GvCV(gv));
+		TRACEME(("%s->%s: 0x%"UVxf, HvNAME(pkg), method, PTR2UV(sv)));
+	} else {
+		sv = newSVsv(&PL_sv_undef);
+		TRACEME(("%s->%s: not found", HvNAME(pkg), method));
+	}
+
+	/*
+	 * Cache the result, ignoring failure: if we can't store the value,
+	 * it just won't be cached.
+	 */
+
+	(void) hv_store(cache, HvNAME(pkg), strlen(HvNAME(pkg)), sv, 0);
+
+	return SvOK(sv) ? sv : (SV *) 0;
+}
+
+/*
+ * pkg_hide
+ *
+ * Force cached value to be undef: hook ignored even if present.
+ */
+static void pkg_hide(
+	HV *cache,
+	HV *pkg,
+	char *method)
+{
+	(void) hv_store(cache,
+		HvNAME(pkg), strlen(HvNAME(pkg)), newSVsv(&PL_sv_undef), 0);
+}
+
+/*
+ * pkg_uncache
+ *
+ * Discard cached value: a whole fetch loop will be retried at next lookup.
+ */
+static void pkg_uncache(
+	HV *cache,
+	HV *pkg,
+	char *method)
+{
+	(void) hv_delete(cache, HvNAME(pkg), strlen(HvNAME(pkg)), G_DISCARD);
+}
+
+/*
+ * pkg_can
+ *
+ * Our own "UNIVERSAL::can", which caches results.
+ *
+ * Returns the routine reference as an SV*, or null if the object does not
+ * know about the method.
+ */
+static SV *pkg_can(
+	HV *cache,
+	HV *pkg,
+	char *method)
+{
+	SV **svh;
+	SV *sv;
+
+	TRACEME(("pkg_can for %s->%s", HvNAME(pkg), method));
+
+	/*
+	 * Look into the cache to see whether we already have determined
+	 * where the routine was, if any.
+	 *
+	 * NOTA BENE: we don't use `method' at all in our lookup, since we know
+	 * that only one hook (i.e. always the same) is cached in a given cache.
+	 */
+
+	svh = hv_fetch(cache, HvNAME(pkg), strlen(HvNAME(pkg)), FALSE);
+	if (svh) {
+		sv = *svh;
+		if (!SvOK(sv)) {
+			TRACEME(("cached %s->%s: not found", HvNAME(pkg), method));
+			return (SV *) 0;
+		} else {
+			TRACEME(("cached %s->%s: 0x%"UVxf,
+				HvNAME(pkg), method, PTR2UV(sv)));
+			return sv;
+		}
+	}
+
+	TRACEME(("not cached yet"));
+	return pkg_fetchmeth(cache, pkg, method);		/* Fetch and cache */
+}
+
+/*
+ * scalar_call
+ *
+ * Call routine as obj->hook(av) in scalar context.
+ * Propagates the single returned value if not called in void context.
+ */
+static SV *scalar_call(
+	SV *obj,
+	SV *hook,
+	int cloning,
+	AV *av,
+	I32 flags)
+{
+	dSP;
+	int count;
+	SV *sv = 0;
+
+	TRACEME(("scalar_call (cloning=%d)", cloning));
+
+	ENTER;
+	SAVETMPS;
+
+	PUSHMARK(sp);
+	XPUSHs(obj);
+	XPUSHs(sv_2mortal(newSViv(cloning)));		/* Cloning flag */
+	if (av) {
+		SV **ary = AvARRAY(av);
+		int cnt = AvFILLp(av) + 1;
+		int i;
+		XPUSHs(ary[0]);							/* Frozen string */
+		for (i = 1; i < cnt; i++) {
+			TRACEME(("pushing arg #%d (0x%"UVxf")...",
+				 i, PTR2UV(ary[i])));
+			XPUSHs(sv_2mortal(newRV(ary[i])));
+		}
+	}
+	PUTBACK;
+
+	TRACEME(("calling..."));
+	count = perl_call_sv(hook, flags);		/* Go back to Perl code */
+	TRACEME(("count = %d", count));
+
+	SPAGAIN;
+
+	if (count) {
+		sv = POPs;
+		SvREFCNT_inc(sv);		/* We're returning it, must stay alive! */
+	}
+
+	PUTBACK;
+	FREETMPS;
+	LEAVE;
+
+	return sv;
+}
+
+/*
+ * array_call
+ *
+ * Call routine obj->hook(cloning) in list context.
+ * Returns the list of returned values in an array.
+ */
+static AV *array_call(
+	SV *obj,
+	SV *hook,
+	int cloning)
+{
+	dSP;
+	int count;
+	AV *av;
+	int i;
+
+	TRACEME(("array_call (cloning=%d)", cloning));
+
+	ENTER;
+	SAVETMPS;
+
+	PUSHMARK(sp);
+	XPUSHs(obj);								/* Target object */
+	XPUSHs(sv_2mortal(newSViv(cloning)));		/* Cloning flag */
+	PUTBACK;
+
+	count = perl_call_sv(hook, G_ARRAY);		/* Go back to Perl code */
+
+	SPAGAIN;
+
+	av = newAV();
+	for (i = count - 1; i >= 0; i--) {
+		SV *sv = POPs;
+		av_store(av, i, SvREFCNT_inc(sv));
+	}
+
+	PUTBACK;
+	FREETMPS;
+	LEAVE;
+
+	return av;
+}
+
+/*
+ * known_class
+ *
+ * Lookup the class name in the `hclass' table and either assign it a new ID
+ * or return the existing one, by filling in `classnum'.
+ *
+ * Return true if the class was known, false if the ID was just generated.
+ */
+static int known_class(
+	stcxt_t *cxt,
+	char *name,		/* Class name */
+	int len,		/* Name length */
+	I32 *classnum)
+{
+	SV **svh;
+	HV *hclass = cxt->hclass;
+
+	TRACEME(("known_class (%s)", name));
+
+	/*
+	 * Recall that we don't store pointers in this hash table, but tags.
+	 * Therefore, we need LOW_32BITS() to extract the relevant parts.
+	 */
+
+	svh = hv_fetch(hclass, name, len, FALSE);
+	if (svh) {
+		*classnum = LOW_32BITS(*svh);
+		return TRUE;
+	}
+
+	/*
+	 * Unknown classname, we need to record it.
+	 */
+
+	cxt->classnum++;
+	if (!hv_store(hclass, name, len, INT2PTR(SV*, cxt->classnum), 0))
+		CROAK(("Unable to record new classname"));
+
+	*classnum = cxt->classnum;
+	return FALSE;
+}
+
+/***
+ *** Sepcific store routines.
+ ***/
+
+/*
+ * store_ref
+ *
+ * Store a reference.
+ * Layout is SX_REF <object> or SX_OVERLOAD <object>.
+ */
+static int store_ref(stcxt_t *cxt, SV *sv)
+{
+	TRACEME(("store_ref (0x%"UVxf")", PTR2UV(sv)));
+
+	/*
+	 * Follow reference, and check if target is overloaded.
+	 */
+
+	sv = SvRV(sv);
+
+	if (SvOBJECT(sv)) {
+		HV *stash = (HV *) SvSTASH(sv);
+		if (stash && Gv_AMG(stash)) {
+			TRACEME(("ref (0x%"UVxf") is overloaded", PTR2UV(sv)));
+			PUTMARK(SX_OVERLOAD);
+		} else
+			PUTMARK(SX_REF);
+	} else
+		PUTMARK(SX_REF);
+
+	return store(cxt, sv);
+}
+
+/*
+ * store_scalar
+ *
+ * Store a scalar.
+ *
+ * Layout is SX_LSCALAR <length> <data>, SX_SCALAR <lenght> <data> or SX_UNDEF.
+ * The <data> section is omitted if <length> is 0.
+ *
+ * If integer or double, the layout is SX_INTEGER <data> or SX_DOUBLE <data>.
+ * Small integers (within [-127, +127]) are stored as SX_BYTE <byte>.
+ */
+static int store_scalar(stcxt_t *cxt, SV *sv)
+{
+	IV iv;
+	char *pv;
+	STRLEN len;
+	U32 flags = SvFLAGS(sv);			/* "cc -O" may put it in register */
+
+	TRACEME(("store_scalar (0x%"UVxf")", PTR2UV(sv)));
+
+	/*
+	 * For efficiency, break the SV encapsulation by peaking at the flags
+	 * directly without using the Perl macros to avoid dereferencing
+	 * sv->sv_flags each time we wish to check the flags.
+	 */
+
+	if (!(flags & SVf_OK)) {			/* !SvOK(sv) */
+		if (sv == &PL_sv_undef) {
+			TRACEME(("immortal undef"));
+			PUTMARK(SX_SV_UNDEF);
+		} else {
+			TRACEME(("undef at 0x%"UVxf, PTR2UV(sv)));
+			PUTMARK(SX_UNDEF);
+		}
+		return 0;
+	}
+
+	/*
+	 * Always store the string representation of a scalar if it exists.
+	 * Gisle Aas provided me with this test case, better than a long speach:
+	 *
+	 *  perl -MDevel::Peek -le '$a="abc"; $a+0; Dump($a)'
+	 *  SV = PVNV(0x80c8520)
+	 *       REFCNT = 1
+	 *       FLAGS = (NOK,POK,pNOK,pPOK)
+	 *       IV = 0
+	 *       NV = 0
+	 *       PV = 0x80c83d0 "abc"\0
+	 *       CUR = 3
+	 *       LEN = 4
+	 *
+	 * Write SX_SCALAR, length, followed by the actual data.
+	 *
+	 * Otherwise, write an SX_BYTE, SX_INTEGER or an SX_DOUBLE as
+	 * appropriate, followed by the actual (binary) data. A double
+	 * is written as a string if network order, for portability.
+	 *
+	 * NOTE: instead of using SvNOK(sv), we test for SvNOKp(sv).
+	 * The reason is that when the scalar value is tainted, the SvNOK(sv)
+	 * value is false.
+	 *
+	 * The test for a read-only scalar with both POK and NOK set is meant
+	 * to quickly detect &PL_sv_yes and &PL_sv_no without having to pay the
+	 * address comparison for each scalar we store.
+	 */
+
+#define SV_MAYBE_IMMORTAL (SVf_READONLY|SVf_POK|SVf_NOK)
+
+	if ((flags & SV_MAYBE_IMMORTAL) == SV_MAYBE_IMMORTAL) {
+		if (sv == &PL_sv_yes) {
+			TRACEME(("immortal yes"));
+			PUTMARK(SX_SV_YES);
+		} else if (sv == &PL_sv_no) {
+			TRACEME(("immortal no"));
+			PUTMARK(SX_SV_NO);
+		} else {
+			pv = SvPV(sv, len);			/* We know it's SvPOK */
+			goto string;				/* Share code below */
+		}
+	} else if (flags & SVp_POK) {		/* SvPOKp(sv) => string */
+		I32 wlen;						/* For 64-bit machines */
+		pv = SvPV(sv, len);
+
+		/*
+		 * Will come here from below with pv and len set if double & netorder,
 		 * or from above if it was readonly, POK and NOK but neither &PL_sv_yes
 		 * nor &PL_sv_no.
 		 */
 	string:
 
-		STORE_SCALAR(pv, len);
-		TRACEME(("ok (scalar 0x%lx '%s', length = %d)",
-			(unsigned long) sv, SvPVX(sv), len));
+		wlen = (I32) len;				/* WLEN via STORE_SCALAR expects I32 */
+		if (SvUTF8 (sv))
+			STORE_UTF8STR(pv, wlen);
+		else
+			STORE_SCALAR(pv, wlen);
+		TRACEME(("ok (scalar 0x%"UVxf" '%s', length = %"IVdf")",
+			 PTR2UV(sv), SvPVX(sv), (IV)len));
 
 	} else if (flags & SVp_NOK) {		/* SvNOKp(sv) => double */
-		double nv = SvNV(sv);
+		NV nv = SvNV(sv);
 
 		/*
 		 * Watch for number being an integer in disguise.
 		 */
-		if (nv == (double) (iv = I_V(nv))) {
-			TRACEME(("double %lf is actually integer %ld", nv, iv));
+		if (nv == (NV) (iv = I_V(nv))) {
+			TRACEME(("double %"NVff" is actually integer %"IVdf, nv, iv));
 			goto integer;		/* Share code below */
 		}
 
-		if (netorder) {
-			TRACEME(("double %lf stored as string", nv));
+		if (cxt->netorder) {
+			TRACEME(("double %"NVff" stored as string", nv));
 			pv = SvPV(sv, len);
-			goto string;		/* Share code below */
+			goto string;		/* Share code above */
 		}
 
 		PUTMARK(SX_DOUBLE);
 		WRITE(&nv, sizeof(nv));
 
-		TRACEME(("ok (double 0x%lx, value = %lf)", (unsigned long) sv, nv));
+		TRACEME(("ok (double 0x%"UVxf", value = %"NVff")", PTR2UV(sv), nv));
 
 	} else if (flags & SVp_IOK) {		/* SvIOKp(sv) => integer */
 		iv = SvIV(sv);
@@ -700,27 +1704,28 @@
 			PUTMARK(SX_BYTE);
 			PUTMARK(siv);
 			TRACEME(("small integer stored as %d", siv));
-		} else if (netorder) {
-			int niv;
+		} else if (cxt->netorder) {
+			I32 niv;
 #ifdef HAS_HTONL
-			niv = (int) htonl(iv);
+			niv = (I32) htonl(iv);
 			TRACEME(("using network order"));
 #else
-			niv = (int) iv;
+			niv = (I32) iv;
 			TRACEME(("as-is for network order"));
 #endif
 			PUTMARK(SX_NETINT);
-			WRITE(&niv, sizeof(niv));
+			WRITE_I32(niv);
 		} else {
 			PUTMARK(SX_INTEGER);
 			WRITE(&iv, sizeof(iv));
 		}
 
-		TRACEME(("ok (integer 0x%lx, value = %d)", (unsigned long) sv, iv));
+		TRACEME(("ok (integer 0x%"UVxf", value = %"IVdf")", PTR2UV(sv), iv));
 
 	} else
-		croak("Can't determine type of %s(0x%lx)", sv_reftype(sv, FALSE),
-			(unsigned long) sv);
+		CROAK(("Can't determine type of %s(0x%"UVxf")",
+		       sv_reftype(sv, FALSE),
+		       PTR2UV(sv)));
 
 	return 0;		/* Ok, no recursion on scalars */
 }
@@ -733,17 +1738,14 @@
  * Layout is SX_ARRAY <size> followed by each item, in increading index order.
  * Each item is stored as <object>.
  */
-static int store_array(f, av)
-PerlIO *f;
-AV *av;
+static int store_array(stcxt_t *cxt, AV *av)
 {
-	dPERINTERP;
 	SV **sav;
 	I32 len = av_len(av) + 1;
 	I32 i;
 	int ret;
 
-	TRACEME(("store_array (0x%lx)", (unsigned long) av));
+	TRACEME(("store_array (0x%"UVxf")", PTR2UV(av)));
 
 	/* 
 	 * Signal array by emitting SX_ARRAY, followed by the array length.
@@ -765,7 +1767,7 @@
 			continue;
 		}
 		TRACEME(("(#%d) item", i));
-		if (ret = store(f, *sav))
+		if (ret = store(cxt, *sav))
 			return ret;
 	}
 
@@ -781,9 +1783,7 @@
  * Borrowed from perl source file pp_ctl.c, where it is used by pp_sort.
  */
 static int
-sortcmp(a, b)
-const void *a;
-const void *b;
+sortcmp(const void *a, const void *b)
 {
 	return sv_cmp(*(SV * const *) a, *(SV * const *) b);
 }
@@ -799,18 +1799,15 @@
  * Keys are stored as <length> <data>, the <data> section being omitted
  * if length is 0.
  */
-static int store_hash(f, hv)
-PerlIO *f;
-HV *hv;
+static int store_hash(stcxt_t *cxt, HV *hv)
 {
-	dPERINTERP;
 	I32 len = HvKEYS(hv);
 	I32 i;
 	int ret = 0;
 	I32 riter;
 	HE *eiter;
 
-	TRACEME(("store_hash (0x%lx)", (unsigned long) hv));
+	TRACEME(("store_hash (0x%"UVxf")", PTR2UV(hv)));
 
 	/* 
 	 * Signal hash by emitting SX_HASH, followed by the table length.
@@ -833,15 +1830,16 @@
 	 *
      * If canonical is defined to some true value then store each
      * key/value pair in sorted order otherwise the order is random.
+	 * Canonical order is irrelevant when a deep clone operation is performed.
 	 *
 	 * Fetch the value from perl only once per store() operation, and only
 	 * when needed.
 	 */
 
 	if (
-		canonical == 1 ||
-		(canonical < 0 && (canonical =
-			SvTRUE(perl_get_sv("Storable::canonical", TRUE)) ? 1 : 0))
+		!(cxt->optype & ST_CLONE) && (cxt->canonical == 1 ||
+		(cxt->canonical < 0 && (cxt->canonical =
+			SvTRUE(perl_get_sv("Storable::canonical", TRUE)) ? 1 : 0)))
 	) {
 		/*
 		 * Storing in order, sorted by key.
@@ -857,7 +1855,7 @@
 		for (i = 0; i < len; i++) {
 			HE *he = hv_iternext(hv);
 			SV *key = hv_iterkeysv(he);
-			av_push(av, key);
+			av_store(av, AvFILLp(av)+1, key);	/* av_push(), really */
 		}
 			
 		qsort((char *) AvARRAY(av), len, sizeof(SV *), sortcmp);
@@ -872,30 +1870,13 @@
 				return 1;		/* Internal error, not I/O error */
 			
 			/*
-			 * Store value first, if defined.
+			 * Store value first.
 			 */
 			
-			if (!SvOK(val)) {
-				/*
-				 * If the "undef" has a refcnt greater than one, other parts
-				 * of the structure might reference this, so we cannot call
-				 * STORE_UNDEF(): at retrieval time, we would break the
-				 * relationship.  Thanks to Albert Micheev for exhibiting
-				 * a structure where this bug manifested -- RAM, 02/03/2000.
-				 */
-				if (SvREFCNT(val) == 1) {
-					TRACEME(("undef value"));
-					STORE_UNDEF();
-				} else {
-					TRACEME(("undef value with refcnt=%d", SvREFCNT(val)));
-					if (ret = store(f, val))
-						goto out;
-				}
-			} else {
-				TRACEME(("(#%d) value 0x%lx", i, (unsigned long) val));
-				if (ret = store(f, val))
-					goto out;
-			}
+			TRACEME(("(#%d) value 0x%"UVxf, i, PTR2UV(val)));
+
+			if (ret = store(cxt, val))
+				goto out;
 
 			/*
 			 * Write key string.
@@ -935,26 +1916,13 @@
 				return 1;		/* Internal error, not I/O error */
 
 			/*
-			 * Store value first, if defined.
+			 * Store value first.
 			 */
 
-			if (!SvOK(val)) {
-				/*
-				 * See comment above in the "canonical" section.
-				 */
-				if (SvREFCNT(val) == 1) {
-					TRACEME(("undef value"));
-					STORE_UNDEF();
-				} else {
-					TRACEME(("undef value with refcnt=%d", SvREFCNT(val)));
-					if (ret = store(f, val))
-						goto out;
-				}
-			} else {
-				TRACEME(("(#%d) value 0x%lx", i, (unsigned long) val));
-				if (ret = store(f, val))
-					goto out;
-			}
+			TRACEME(("(#%d) value 0x%"UVxf, i, PTR2UV(val)));
+
+			if (ret = store(cxt, val))
+				goto out;
 
 			/*
 			 * Write key string.
@@ -971,7 +1939,7 @@
 		}
     }
 
-	TRACEME(("ok (hash 0x%lx)", (unsigned long) hv));
+	TRACEME(("ok (hash 0x%"UVxf")", PTR2UV(hv)));
 
 out:
 	HvRITER(hv) = riter;		/* Restore hash iterator state */
@@ -988,17 +1956,14 @@
  * dealing with a tied hash, we store SX_TIED_HASH <hash object>, where
  * <hash object> stands for the serialization of the tied hash.
  */
-static int store_tied(f, sv)
-PerlIO *f;
-SV *sv;
+static int store_tied(stcxt_t *cxt, SV *sv)
 {
-	dPERINTERP;
 	MAGIC *mg;
 	int ret = 0;
 	int svt = SvTYPE(sv);
 	char mtype = 'P';
 
-	TRACEME(("store_tied (0x%lx)", (unsigned long) sv));
+	TRACEME(("store_tied (0x%"UVxf")", PTR2UV(sv)));
 
 	/*
 	 * We have a small run-time penalty here because we chose to factorise
@@ -1010,41 +1975,612 @@
 	 * tied hashes first, as they are the most likely beasts.
 	 */
 
-	if (svt == SVt_PVHV) {
-		TRACEME(("tied hash"));
-		PUTMARK(SX_TIED_HASH);			/* Introduces tied hash */
-	} else if (svt == SVt_PVAV) {
-		TRACEME(("tied array"));
-		PUTMARK(SX_TIED_ARRAY);			/* Introduces tied array */
+	if (svt == SVt_PVHV) {
+		TRACEME(("tied hash"));
+		PUTMARK(SX_TIED_HASH);			/* Introduces tied hash */
+	} else if (svt == SVt_PVAV) {
+		TRACEME(("tied array"));
+		PUTMARK(SX_TIED_ARRAY);			/* Introduces tied array */
+	} else {
+		TRACEME(("tied scalar"));
+		PUTMARK(SX_TIED_SCALAR);		/* Introduces tied scalar */
+		mtype = 'q';
+	}
+
+	if (!(mg = mg_find(sv, mtype)))
+		CROAK(("No magic '%c' found while storing tied %s", mtype,
+			(svt == SVt_PVHV) ? "hash" :
+				(svt == SVt_PVAV) ? "array" : "scalar"));
+
+	/*
+	 * The mg->mg_obj found by mg_find() above actually points to the
+	 * underlying tied Perl object implementation. For instance, if the
+	 * original SV was that of a tied array, then mg->mg_obj is an AV.
+	 *
+	 * Note that we store the Perl object as-is. We don't call its FETCH
+	 * method along the way. At retrieval time, we won't call its STORE
+	 * method either, but the tieing magic will be re-installed. In itself,
+	 * that ensures that the tieing semantics are preserved since futher
+	 * accesses on the retrieved object will indeed call the magic methods...
+	 */
+
+	if (ret = store(cxt, mg->mg_obj))
+		return ret;
+
+	TRACEME(("ok (tied)"));
+
+	return 0;
+}
+
+/*
+ * store_tied_item
+ *
+ * Stores a reference to an item within a tied structure:
+ *
+ *  . \$h{key}, stores both the (tied %h) object and 'key'.
+ *  . \$a[idx], stores both the (tied @a) object and 'idx'.
+ *
+ * Layout is therefore either:
+ *     SX_TIED_KEY <object> <key>
+ *     SX_TIED_IDX <object> <index>
+ */
+static int store_tied_item(stcxt_t *cxt, SV *sv)
+{
+	MAGIC *mg;
+	int ret;
+
+	TRACEME(("store_tied_item (0x%"UVxf")", PTR2UV(sv)));
+
+	if (!(mg = mg_find(sv, 'p')))
+		CROAK(("No magic 'p' found while storing reference to tied item"));
+
+	/*
+	 * We discriminate between \$h{key} and \$a[idx] via mg_ptr.
+	 */
+
+	if (mg->mg_ptr) {
+		TRACEME(("store_tied_item: storing a ref to a tied hash item"));
+		PUTMARK(SX_TIED_KEY);
+		TRACEME(("store_tied_item: storing OBJ 0x%"UVxf, PTR2UV(mg->mg_obj)));
+
+		if (ret = store(cxt, mg->mg_obj))
+			return ret;
+
+		TRACEME(("store_tied_item: storing PTR 0x%"UVxf, PTR2UV(mg->mg_ptr)));
+
+		if (ret = store(cxt, (SV *) mg->mg_ptr))
+			return ret;
+	} else {
+		I32 idx = mg->mg_len;
+
+		TRACEME(("store_tied_item: storing a ref to a tied array item "));
+		PUTMARK(SX_TIED_IDX);
+		TRACEME(("store_tied_item: storing OBJ 0x%"UVxf, PTR2UV(mg->mg_obj)));
+
+		if (ret = store(cxt, mg->mg_obj))
+			return ret;
+
+		TRACEME(("store_tied_item: storing IDX %d", idx));
+
+		WLEN(idx);
+	}
+
+	TRACEME(("ok (tied item)"));
+
+	return 0;
+}
+
+/*
+ * store_hook		-- dispatched manually, not via sv_store[]
+ *
+ * The blessed SV is serialized by a hook.
+ *
+ * Simple Layout is:
+ *
+ *     SX_HOOK <flags> <len> <classname> <len2> <str> [<len3> <object-IDs>]
+ *
+ * where <flags> indicates how long <len>, <len2> and <len3> are, whether
+ * the trailing part [] is present, the type of object (scalar, array or hash).
+ * There is also a bit which says how the classname is stored between:
+ *
+ *     <len> <classname>
+ *     <index>
+ *
+ * and when the <index> form is used (classname already seen), the "large
+ * classname" bit in <flags> indicates how large the <index> is.
+ * 
+ * The serialized string returned by the hook is of length <len2> and comes
+ * next.  It is an opaque string for us.
+ *
+ * Those <len3> object IDs which are listed last represent the extra references
+ * not directly serialized by the hook, but which are linked to the object.
+ *
+ * When recursion is mandated to resolve object-IDs not yet seen, we have
+ * instead, with <header> being flags with bits set to indicate the object type
+ * and that recursion was indeed needed:
+ *
+ *     SX_HOOK <header> <object> <header> <object> <flags>
+ *
+ * that same header being repeated between serialized objects obtained through
+ * recursion, until we reach flags indicating no recursion, at which point
+ * we know we've resynchronized with a single layout, after <flags>.
+ *
+ * When storing a blessed ref to a tied variable, the following format is
+ * used:
+ *
+ *     SX_HOOK <flags> <extra> ... [<len3> <object-IDs>] <magic object>
+ *
+ * The first <flags> indication carries an object of type SHT_EXTRA, and the
+ * real object type is held in the <extra> flag.  At the very end of the
+ * serialization stream, the underlying magic object is serialized, just like
+ * any other tied variable.
+ */
+static int store_hook(
+	stcxt_t *cxt,
+	SV *sv,
+	int type,
+	HV *pkg,
+	SV *hook)
+{
+	I32 len;
+	char *class;
+	STRLEN len2;
+	SV *ref;
+	AV *av;
+	SV **ary;
+	int count;				/* really len3 + 1 */
+	unsigned char flags;
+	char *pv;
+	int i;
+	int recursed = 0;		/* counts recursion */
+	int obj_type;			/* object type, on 2 bits */
+	I32 classnum;
+	int ret;
+	int clone = cxt->optype & ST_CLONE;
+	char mtype;				/* for blessed ref to tied structures */
+	unsigned char eflags;	/* used when object type is SHT_EXTRA */
+
+	TRACEME(("store_hook, class \"%s\", tagged #%d", HvNAME(pkg), cxt->tagnum));
+
+	/*
+	 * Determine object type on 2 bits.
+	 */
+
+	switch (type) {
+	case svis_SCALAR:
+		obj_type = SHT_SCALAR;
+		break;
+	case svis_ARRAY:
+		obj_type = SHT_ARRAY;
+		break;
+	case svis_HASH:
+		obj_type = SHT_HASH;
+		break;
+	case svis_TIED:
+		/*
+		 * Produced by a blessed ref to a tied data structure, $o in the
+		 * following Perl code.
+		 *
+		 * 	my %h;
+		 *  tie %h, 'FOO';
+		 *	my $o = bless \%h, 'BAR';
+		 *
+		 * Signal the tie-ing magic by setting the object type as SHT_EXTRA
+		 * (since we have only 2 bits in <flags> to store the type), and an
+		 * <extra> byte flag will be emitted after the FIRST <flags> in the
+		 * stream, carrying what we put in `eflags'.
+		 */
+		obj_type = SHT_EXTRA;
+		switch (SvTYPE(sv)) {
+		case SVt_PVHV:
+			eflags = (unsigned char) SHT_THASH;
+			mtype = 'P';
+			break;
+		case SVt_PVAV:
+			eflags = (unsigned char) SHT_TARRAY;
+			mtype = 'P';
+			break;
+		default:
+			eflags = (unsigned char) SHT_TSCALAR;
+			mtype = 'q';
+			break;
+		}
+		break;
+	default:
+		CROAK(("Unexpected object type (%d) in store_hook()", type));
+	}
+	flags = SHF_NEED_RECURSE | obj_type;
+
+	class = HvNAME(pkg);
+	len = strlen(class);
+
+	/*
+	 * To call the hook, we need to fake a call like:
+	 *
+	 *    $object->STORABLE_freeze($cloning);
+	 *
+	 * but we don't have the $object here.  For instance, if $object is
+	 * a blessed array, what we have in `sv' is the array, and we can't
+	 * call a method on those.
+	 *
+	 * Therefore, we need to create a temporary reference to the object and
+	 * make the call on that reference.
+	 */
+
+	TRACEME(("about to call STORABLE_freeze on class %s", class));
+
+	ref = newRV_noinc(sv);				/* Temporary reference */
+	av = array_call(ref, hook, clone);	/* @a = $object->STORABLE_freeze($c) */
+	SvRV(ref) = 0;
+	SvREFCNT_dec(ref);					/* Reclaim temporary reference */
+
+	count = AvFILLp(av) + 1;
+	TRACEME(("store_hook, array holds %d items", count));
+
+	/*
+	 * If they return an empty list, it means they wish to ignore the
+	 * hook for this class (and not just this instance -- that's for them
+	 * to handle if they so wish).
+	 *
+	 * Simply disable the cached entry for the hook (it won't be recomputed
+	 * since it's present in the cache) and recurse to store_blessed().
+	 */
+
+	if (!count) {
+		/*
+		 * They must not change their mind in the middle of a serialization.
+		 */
+
+		if (hv_fetch(cxt->hclass, class, len, FALSE))
+			CROAK(("Too late to ignore hooks for %s class \"%s\"",
+				(cxt->optype & ST_CLONE) ? "cloning" : "storing", class));
+	
+		pkg_hide(cxt->hook, pkg, "STORABLE_freeze");
+
+		ASSERT(!pkg_can(cxt->hook, pkg, "STORABLE_freeze"), ("hook invisible"));
+		TRACEME(("ignoring STORABLE_freeze in class \"%s\"", class));
+
+		return store_blessed(cxt, sv, type, pkg);
+	}
+
+	/*
+	 * Get frozen string.
+	 */
+
+	ary = AvARRAY(av);
+	pv = SvPV(ary[0], len2);
+
+	/*
+	 * If they returned more than one item, we need to serialize some
+	 * extra references if not already done.
+	 *
+	 * Loop over the array, starting at postion #1, and for each item,
+	 * ensure it is a reference, serialize it if not already done, and
+	 * replace the entry with the tag ID of the corresponding serialized
+	 * object.
+	 *
+	 * We CHEAT by not calling av_fetch() and read directly within the
+	 * array, for speed.
+	 */
+
+	for (i = 1; i < count; i++) {
+		SV **svh;
+		SV *rsv = ary[i];
+		SV *xsv;
+		AV *av_hook = cxt->hook_seen;
+
+		if (!SvROK(rsv))
+			CROAK(("Item #%d returned by STORABLE_freeze "
+				"for %s is not a reference", i, class));
+		xsv = SvRV(rsv);		/* Follow ref to know what to look for */
+
+		/*
+		 * Look in hseen and see if we have a tag already.
+		 * Serialize entry if not done already, and get its tag.
+		 */
+
+		if (svh = hv_fetch(cxt->hseen, (char *) &xsv, sizeof(xsv), FALSE))
+			goto sv_seen;		/* Avoid moving code too far to the right */
+
+		TRACEME(("listed object %d at 0x%"UVxf" is unknown", i-1, PTR2UV(xsv)));
+
+		/*
+		 * We need to recurse to store that object and get it to be known
+		 * so that we can resolve the list of object-IDs at retrieve time.
+		 *
+		 * The first time we do this, we need to emit the proper header
+		 * indicating that we recursed, and what the type of object is (the
+		 * object we're storing via a user-hook).  Indeed, during retrieval,
+		 * we'll have to create the object before recursing to retrieve the
+		 * others, in case those would point back at that object.
+		 */
+
+		/* [SX_HOOK] <flags> [<extra>] <object>*/
+		if (!recursed++) {
+			PUTMARK(SX_HOOK);
+			PUTMARK(flags);
+			if (obj_type == SHT_EXTRA)
+				PUTMARK(eflags);
+		} else
+			PUTMARK(flags);
+
+		if (ret = store(cxt, xsv))		/* Given by hook for us to store */
+			return ret;
+
+		svh = hv_fetch(cxt->hseen, (char *) &xsv, sizeof(xsv), FALSE);
+		if (!svh)
+			CROAK(("Could not serialize item #%d from hook in %s", i, class));
+
+		/*
+		 * It was the first time we serialized `xsv'.
+		 *
+		 * Keep this SV alive until the end of the serialization: if we
+		 * disposed of it right now by decrementing its refcount, and it was
+		 * a temporary value, some next temporary value allocated during
+		 * another STORABLE_freeze might take its place, and we'd wrongly
+		 * assume that new SV was already serialized, based on its presence
+		 * in cxt->hseen.
+		 *
+		 * Therefore, push it away in cxt->hook_seen.
+		 */
+
+		av_store(av_hook, AvFILLp(av_hook)+1, SvREFCNT_inc(xsv));
+
+	sv_seen:
+		/*
+		 * Dispose of the REF they returned.  If we saved the `xsv' away
+		 * in the array of returned SVs, that will not cause the underlying
+		 * referenced SV to be reclaimed.
+		 */
+
+		ASSERT(SvREFCNT(xsv) > 1, ("SV will survive disposal of its REF"));
+		SvREFCNT_dec(rsv);			/* Dispose of reference */
+
+		/*
+		 * Replace entry with its tag (not a real SV, so no refcnt increment)
+		 */
+
+		ary[i] = *svh;
+		TRACEME(("listed object %d at 0x%"UVxf" is tag #%"UVuf,
+			 i-1, PTR2UV(xsv), PTR2UV(*svh)));
+	}
+
+	/*
+	 * Allocate a class ID if not already done.
+	 *
+	 * This needs to be done after the recursion above, since at retrieval
+	 * time, we'll see the inner objects first.  Many thanks to
+	 * Salvador Ortiz Garcia <sog at msg.com.mx> who spot that bug and
+	 * proposed the right fix.  -- RAM, 15/09/2000
+	 */
+
+	if (!known_class(cxt, class, len, &classnum)) {
+		TRACEME(("first time we see class %s, ID = %d", class, classnum));
+		classnum = -1;				/* Mark: we must store classname */
+	} else {
+		TRACEME(("already seen class %s, ID = %d", class, classnum));
+	}
+
+	/*
+	 * Compute leading flags.
+	 */
+
+	flags = obj_type;
+	if (((classnum == -1) ? len : classnum) > LG_SCALAR)
+		flags |= SHF_LARGE_CLASSLEN;
+	if (classnum != -1)
+		flags |= SHF_IDX_CLASSNAME;
+	if (len2 > LG_SCALAR)
+		flags |= SHF_LARGE_STRLEN;
+	if (count > 1)
+		flags |= SHF_HAS_LIST;
+	if (count > (LG_SCALAR + 1))
+		flags |= SHF_LARGE_LISTLEN;
+
+	/* 
+	 * We're ready to emit either serialized form:
+	 *
+	 *   SX_HOOK <flags> <len> <classname> <len2> <str> [<len3> <object-IDs>]
+	 *   SX_HOOK <flags> <index>           <len2> <str> [<len3> <object-IDs>]
+	 *
+	 * If we recursed, the SX_HOOK has already been emitted.
+	 */
+
+	TRACEME(("SX_HOOK (recursed=%d) flags=0x%x "
+			"class=%"IVdf" len=%"IVdf" len2=%"IVdf" len3=%d",
+		 recursed, flags, (IV)classnum, (IV)len, (IV)len2, count-1));
+
+	/* SX_HOOK <flags> [<extra>] */
+	if (!recursed) {
+		PUTMARK(SX_HOOK);
+		PUTMARK(flags);
+		if (obj_type == SHT_EXTRA)
+			PUTMARK(eflags);
+	} else
+		PUTMARK(flags);
+
+	/* <len> <classname> or <index> */
+	if (flags & SHF_IDX_CLASSNAME) {
+		if (flags & SHF_LARGE_CLASSLEN)
+			WLEN(classnum);
+		else {
+			unsigned char cnum = (unsigned char) classnum;
+			PUTMARK(cnum);
+		}
+	} else {
+		if (flags & SHF_LARGE_CLASSLEN)
+			WLEN(len);
+		else {
+			unsigned char clen = (unsigned char) len;
+			PUTMARK(clen);
+		}
+		WRITE(class, len);		/* Final \0 is omitted */
+	}
+
+	/* <len2> <frozen-str> */
+	if (flags & SHF_LARGE_STRLEN) {
+		I32 wlen2 = len2;		/* STRLEN might be 8 bytes */
+		WLEN(wlen2);			/* Must write an I32 for 64-bit machines */
+	} else {
+		unsigned char clen = (unsigned char) len2;
+		PUTMARK(clen);
+	}
+	if (len2)
+		WRITE(pv, len2);	/* Final \0 is omitted */
+
+	/* [<len3> <object-IDs>] */
+	if (flags & SHF_HAS_LIST) {
+		int len3 = count - 1;
+		if (flags & SHF_LARGE_LISTLEN)
+			WLEN(len3);
+		else {
+			unsigned char clen = (unsigned char) len3;
+			PUTMARK(clen);
+		}
+
+		/*
+		 * NOTA BENE, for 64-bit machines: the ary[i] below does not yield a
+		 * real pointer, rather a tag number, well under the 32-bit limit.
+		 */
+
+		for (i = 1; i < count; i++) {
+			I32 tagval = htonl(LOW_32BITS(ary[i]));
+			WRITE_I32(tagval);
+			TRACEME(("object %d, tag #%d", i-1, ntohl(tagval)));
+		}
+	}
+
+	/*
+	 * Free the array.  We need extra care for indices after 0, since they
+	 * don't hold real SVs but integers cast.
+	 */
+
+	if (count > 1)
+		AvFILLp(av) = 0;	/* Cheat, nothing after 0 interests us */
+	av_undef(av);
+	sv_free((SV *) av);
+
+	/*
+	 * If object was tied, need to insert serialization of the magic object.
+	 */
+
+	if (obj_type == SHT_EXTRA) {
+		MAGIC *mg;
+
+		if (!(mg = mg_find(sv, mtype))) {
+			int svt = SvTYPE(sv);
+			CROAK(("No magic '%c' found while storing ref to tied %s with hook",
+				mtype, (svt == SVt_PVHV) ? "hash" :
+					(svt == SVt_PVAV) ? "array" : "scalar"));
+		}
+
+		TRACEME(("handling the magic object 0x%"UVxf" part of 0x%"UVxf,
+			PTR2UV(mg->mg_obj), PTR2UV(sv)));
+
+		/*
+		 * [<magic object>]
+		 */
+
+		if (ret = store(cxt, mg->mg_obj))
+			return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * store_blessed	-- dispatched manually, not via sv_store[]
+ *
+ * Check whether there is a STORABLE_xxx hook defined in the class or in one
+ * of its ancestors.  If there is, then redispatch to store_hook();
+ *
+ * Otherwise, the blessed SV is stored using the following layout:
+ *
+ *    SX_BLESS <flag> <len> <classname> <object>
+ *
+ * where <flag> indicates whether <len> is stored on 0 or 4 bytes, depending
+ * on the high-order bit in flag: if 1, then length follows on 4 bytes.
+ * Otherwise, the low order bits give the length, thereby giving a compact
+ * representation for class names less than 127 chars long.
+ *
+ * Each <classname> seen is remembered and indexed, so that the next time
+ * an object in the blessed in the same <classname> is stored, the following
+ * will be emitted:
+ *
+ *    SX_IX_BLESS <flag> <index> <object>
+ *
+ * where <index> is the classname index, stored on 0 or 4 bytes depending
+ * on the high-order bit in flag (same encoding as above for <len>).
+ */
+static int store_blessed(
+	stcxt_t *cxt,
+	SV *sv,
+	int type,
+	HV *pkg)
+{
+	SV *hook;
+	I32 len;
+	char *class;
+	I32 classnum;
+
+	TRACEME(("store_blessed, type %d, class \"%s\"", type, HvNAME(pkg)));
+
+	/*
+	 * Look for a hook for this blessed SV and redirect to store_hook()
+	 * if needed.
+	 */
+
+	hook = pkg_can(cxt->hook, pkg, "STORABLE_freeze");
+	if (hook)
+		return store_hook(cxt, sv, type, pkg, hook);
+
+	/*
+	 * This is a blessed SV without any serialization hook.
+	 */
+
+	class = HvNAME(pkg);
+	len = strlen(class);
+
+	TRACEME(("blessed 0x%"UVxf" in %s, no hook: tagged #%d",
+		 PTR2UV(sv), class, cxt->tagnum));
+
+	/*
+	 * Determine whether it is the first time we see that class name (in which
+	 * case it will be stored in the SX_BLESS form), or whether we already
+	 * saw that class name before (in which case the SX_IX_BLESS form will be
+	 * used).
+	 */
+
+	if (known_class(cxt, class, len, &classnum)) {
+		TRACEME(("already seen class %s, ID = %d", class, classnum));
+		PUTMARK(SX_IX_BLESS);
+		if (classnum <= LG_BLESS) {
+			unsigned char cnum = (unsigned char) classnum;
+			PUTMARK(cnum);
+		} else {
+			unsigned char flag = (unsigned char) 0x80;
+			PUTMARK(flag);
+			WLEN(classnum);
+		}
 	} else {
-		TRACEME(("tied scalar"));
-		PUTMARK(SX_TIED_SCALAR);		/* Introduces tied scalar */
-		mtype = 'q';
+		TRACEME(("first time we see class %s, ID = %d", class, classnum));
+		PUTMARK(SX_BLESS);
+		if (len <= LG_BLESS) {
+			unsigned char clen = (unsigned char) len;
+			PUTMARK(clen);
+		} else {
+			unsigned char flag = (unsigned char) 0x80;
+			PUTMARK(flag);
+			WLEN(len);					/* Don't BER-encode, this should be rare */
+		}
+		WRITE(class, len);				/* Final \0 is omitted */
 	}
 
-	if (!(mg = mg_find(sv, mtype)))
-		croak("No magic '%c' found while storing tied %s", mtype,
-			(svt == SVt_PVHV) ? "hash" :
-				(svt == SVt_PVAV) ? "array" : "scalar");
-
 	/*
-	 * The mg->mg_obj found by mg_find() above actually points to the
-	 * underlying tied Perl object implementation. For instance, if the
-	 * original SV was that of a tied array, then mg->mg_obj is an AV.
-	 *
-	 * Note that we store the Perl object as-is. We don't call its FETCH
-	 * method along the way. At retrieval time, we won't call its STORE
-	 * method either, but the tieing magic will be re-installed. In itself,
-	 * that ensures that the tieing semantics are preserved since futher
-	 * accesses on the retrieved object will indeed call the magic methods...
+	 * Now emit the <object> part.
 	 */
 
-	if (ret = store(f, mg->mg_obj))
-		return ret;
-
-	TRACEME(("ok (tied)"));
-
-	return 0;
+	return SV_STORE(type)(cxt, sv);
 }
 
 /*
@@ -1057,12 +2593,9 @@
  * true value, then don't croak, just warn, and store a placeholder string
  * instead.
  */
-static int store_other(f, sv)
-PerlIO *f;
-SV *sv;
+static int store_other(stcxt_t *cxt, SV *sv)
 {
-	dPERINTERP;
-	STRLEN len;
+	I32 len;
 	static char buf[80];
 
 	TRACEME(("store_other"));
@@ -1072,41 +2605,32 @@
 	 */
 
 	if (
-		forgive_me == 0 ||
-		(forgive_me < 0 && !(forgive_me =
+		cxt->forgive_me == 0 ||
+		(cxt->forgive_me < 0 && !(cxt->forgive_me =
 			SvTRUE(perl_get_sv("Storable::forgive_me", TRUE)) ? 1 : 0))
 	)
-		croak("Can't store %s items", sv_reftype(sv, FALSE));
+		CROAK(("Can't store %s items", sv_reftype(sv, FALSE)));
 
-	warn("Can't store %s items", sv_reftype(sv, FALSE));
+	warn("Can't store item %s(0x%"UVxf")",
+		sv_reftype(sv, FALSE), PTR2UV(sv));
 
 	/*
 	 * Store placeholder string as a scalar instead...
 	 */
 
-	(void) sprintf(buf, "You lost %s(0x%lx)\0", sv_reftype(sv, FALSE),
-		(unsigned long) sv);
+	(void) sprintf(buf, "You lost %s(0x%"UVxf")\0", sv_reftype(sv, FALSE),
+		       PTR2UV(sv));
 
 	len = strlen(buf);
 	STORE_SCALAR(buf, len);
-	TRACEME(("ok (dummy \"%s\", length = %d)", buf, len));
+	TRACEME(("ok (dummy \"%s\", length = %"IVdf")", buf, len));
 
 	return 0;
 }
 
-/*
- * Dynamic dispatching table for SV store.
- */
-static int (*sv_store[])() = {
-	store_ref,		/* svis_REF */
-	store_scalar,	/* svis_SCALAR */
-	store_array,	/* svis_ARRAY */
-	store_hash,		/* svis_HASH */
-	store_tied,		/* svis_TIED */
-	store_other,	/* svis_OTHER */
-};
-
-#define SV_STORE(x)	(*sv_store[x])
+/***
+ *** Store driving routines
+ ***/
 
 /*
  * sv_type
@@ -1116,8 +2640,7 @@
  * Returns the type of the SV, identified by an integer. That integer
  * may then be used to index the dynamic routine dispatch table.
  */
-static int sv_type(sv)
-SV *sv;
+static int sv_type(SV *sv)
 {
 	switch (SvTYPE(sv)) {
 	case SVt_NULL:
@@ -1144,6 +2667,9 @@
 		return SvROK(sv) ? svis_REF : svis_SCALAR;
 	case SVt_PVMG:
 	case SVt_PVLV:		/* Workaround for perl5.004_04 "LVALUE" bug */
+		if (SvRMAGICAL(sv) && (mg_find(sv, 'p')))
+			return svis_TIED_ITEM;
+		/* FALL THROUGH */
 	case SVt_PVBM:
 		if (SvRMAGICAL(sv) && (mg_find(sv, 'q')))
 			return svis_TIED;
@@ -1168,22 +2694,19 @@
  *
  * Recursively store objects pointed to by the sv to the specified file.
  *
- * Layout is <content> SX_STORED or SX_OBJECT <tagnum> SX_STORED if we
- * reach an already stored object (one for which storage has started--
- * it may not be over if we have a self-referenced structure). This data set
- * forms a stored <object>.
- */
-static int store(f, sv)
-PerlIO *f;
-SV *sv;
+ * Layout is <content> or SX_OBJECT <tagnum> if we reach an already stored
+ * object (one for which storage has started -- it may not be over if we have
+ * a self-referenced structure). This data set forms a stored <object>.
+ */
+static int store(stcxt_t *cxt, SV *sv)
 {
-	dPERINTERP;
 	SV **svh;
 	int ret;
-	int type;
 	SV *tag;
+	int type;
+	HV *hseen = cxt->hseen;
 
-	TRACEME(("store (0x%lx)", (unsigned long) sv));
+	TRACEME(("store (0x%"UVxf")", PTR2UV(sv)));
 
 	/*
 	 * If object has already been stored, do not duplicate data.
@@ -1199,14 +2722,12 @@
 
 	svh = hv_fetch(hseen, (char *) &sv, sizeof(sv), FALSE);
 	if (svh) {
-#if PTRSIZE <= 4
-		I32 tagval = htonl((I32) (*svh));
-#else
-		I32 tagval = htonl((I32) ((unsigned long) (*svh) & 0xffffffff));
-#endif
-		TRACEME(("object 0x%lx seen as #%d.", (unsigned long) sv, tagval));
+		I32 tagval = htonl(LOW_32BITS(*svh));
+
+		TRACEME(("object 0x%"UVxf" seen as #%d", PTR2UV(sv), ntohl(tagval)));
+
 		PUTMARK(SX_OBJECT);
-		WRITE(&tagval, sizeof(I32));
+		WRITE_I32(tagval);
 		return 0;
 	}
 
@@ -1219,275 +2740,793 @@
 	 * means that we must clean up the hash manually afterwards, but gives
 	 * us a 15% throughput increase.
 	 *
-	 * The (IV) cast below is for 64-bit machines, to avoid warnings from
-	 * the compiler. Please, let me know if it does not work.
-	 *		-- RAM, 14/09/1999
 	 */
 
-	if (!hv_store(hseen, (char *) &sv, sizeof(sv), (SV*) (IV) (tagnum++), 0))
-		return -1;
-	TRACEME(("recorded 0x%lx as object #%d", (unsigned long) sv, tagnum));
+	cxt->tagnum++;
+	if (!hv_store(hseen,
+			(char *) &sv, sizeof(sv), INT2PTR(SV*, cxt->tagnum), 0))
+		return -1;
+
+	/*
+	 * Store `sv' and everything beneath it, using appropriate routine.
+	 * Abort immediately if we get a non-zero status back.
+	 */
+
+	type = sv_type(sv);
+
+	TRACEME(("storing 0x%"UVxf" tag #%d, type %d...",
+		 PTR2UV(sv), cxt->tagnum, type));
+
+	if (SvOBJECT(sv)) {
+		HV *pkg = SvSTASH(sv);
+		ret = store_blessed(cxt, sv, type, pkg);
+	} else
+		ret = SV_STORE(type)(cxt, sv);
+
+	TRACEME(("%s (stored 0x%"UVxf", refcnt=%d, %s)",
+		ret ? "FAILED" : "ok", PTR2UV(sv),
+		SvREFCNT(sv), sv_reftype(sv, FALSE)));
+
+	return ret;
+}
+
+/*
+ * magic_write
+ *
+ * Write magic number and system information into the file.
+ * Layout is <magic> <network> [<len> <byteorder> <sizeof int> <sizeof long>
+ * <sizeof ptr>] where <len> is the length of the byteorder hexa string.
+ * All size and lenghts are written as single characters here.
+ *
+ * Note that no byte ordering info is emitted when <network> is true, since
+ * integers will be emitted in network order in that case.
+ */
+static int magic_write(stcxt_t *cxt)
+{
+	char buf[256];	/* Enough room for 256 hexa digits */
+	unsigned char c;
+	int use_network_order = cxt->netorder;
+
+	TRACEME(("magic_write on fd=%d", cxt->fio ? fileno(cxt->fio) : -1));
+
+	if (cxt->fio)
+		WRITE(magicstr, strlen(magicstr));	/* Don't write final \0 */
+
+	/*
+	 * Starting with 0.6, the "use_network_order" byte flag is also used to
+	 * indicate the version number of the binary image, encoded in the upper
+	 * bits. The bit 0 is always used to indicate network order.
+	 */
+
+	c = (unsigned char)
+		((use_network_order ? 0x1 : 0x0) | (STORABLE_BIN_MAJOR << 1));
+	PUTMARK(c);
+
+	/*
+	 * Starting with 0.7, a full byte is dedicated to the minor version of
+	 * the binary format, which is incremented only when new markers are
+	 * introduced, for instance, but when backward compatibility is preserved.
+	 */
+
+	PUTMARK((unsigned char) STORABLE_BIN_MINOR);
+
+	if (use_network_order)
+		return 0;						/* Don't bother with byte ordering */
+
+	sprintf(buf, "%lx", (unsigned long) BYTEORDER);
+	c = (unsigned char) strlen(buf);
+	PUTMARK(c);
+	WRITE(buf, (unsigned int) c);		/* Don't write final \0 */
+	PUTMARK((unsigned char) sizeof(int));
+	PUTMARK((unsigned char) sizeof(long));
+	PUTMARK((unsigned char) sizeof(char *));
+	PUTMARK((unsigned char) sizeof(NV));
+
+	TRACEME(("ok (magic_write byteorder = 0x%lx [%d], I%d L%d P%d D%d)",
+		 (unsigned long) BYTEORDER, (int) c,
+		 (int) sizeof(int), (int) sizeof(long),
+		 (int) sizeof(char *), (int) sizeof(NV)));
+
+	return 0;
+}
+
+/*
+ * do_store
+ *
+ * Common code for store operations.
+ *
+ * When memory store is requested (f = NULL) and a non null SV* is given in
+ * `res', it is filled with a new SV created out of the memory buffer.
+ *
+ * It is required to provide a non-null `res' when the operation type is not
+ * dclone() and store() is performed to memory.
+ */
+static int do_store(
+	PerlIO *f,
+	SV *sv,
+	int optype,
+	int network_order,
+	SV **res)
+{
+	dSTCXT;
+	int status;
+
+	ASSERT(!(f == 0 && !(optype & ST_CLONE)) || res,
+		("must supply result SV pointer for real recursion to memory"));
+
+	TRACEME(("do_store (optype=%d, netorder=%d)",
+		optype, network_order));
+
+	optype |= ST_STORE;
+
+	/*
+	 * Workaround for CROAK leak: if they enter with a "dirty" context,
+	 * free up memory for them now.
+	 */
+
+	if (cxt->s_dirty)
+		clean_context(cxt);
+
+	/*
+	 * Now that STORABLE_xxx hooks exist, it is possible that they try to
+	 * re-enter store() via the hooks.  We need to stack contexts.
+	 */
+
+	if (cxt->entry)
+		cxt = allocate_context(cxt);
+
+	cxt->entry++;
+
+	ASSERT(cxt->entry == 1, ("starting new recursion"));
+	ASSERT(!cxt->s_dirty, ("clean context"));
+
+	/*
+	 * Ensure sv is actually a reference. From perl, we called something
+	 * like:
+	 *       pstore(FILE, \@array);
+	 * so we must get the scalar value behing that reference.
+	 */
+
+	if (!SvROK(sv))
+		CROAK(("Not a reference"));
+	sv = SvRV(sv);			/* So follow it to know what to store */
+
+	/* 
+	 * If we're going to store to memory, reset the buffer.
+	 */
+
+	if (!f)
+		MBUF_INIT(0);
+
+	/*
+	 * Prepare context and emit headers.
+	 */
+
+	init_store_context(cxt, f, optype, network_order);
+
+	if (-1 == magic_write(cxt))		/* Emit magic and ILP info */
+		return 0;					/* Error */
+
+	/*
+	 * Recursively store object...
+	 */
+
+	ASSERT(is_storing(), ("within store operation"));
+
+	status = store(cxt, sv);		/* Just do it! */
+
+	/*
+	 * If they asked for a memory store and they provided an SV pointer,
+	 * make an SV string out of the buffer and fill their pointer.
+	 *
+	 * When asking for ST_REAL, it's MANDATORY for the caller to provide
+	 * an SV, since context cleanup might free the buffer if we did recurse.
+	 * (unless caller is dclone(), which is aware of that).
+	 */
+
+	if (!cxt->fio && res)
+		*res = mbuf2sv();
+
+	/*
+	 * Final cleanup.
+	 *
+	 * The "root" context is never freed, since it is meant to be always
+	 * handy for the common case where no recursion occurs at all (i.e.
+	 * we enter store() outside of any Storable code and leave it, period).
+	 * We know it's the "root" context because there's nothing stacked
+	 * underneath it.
+	 *
+	 * OPTIMIZATION:
+	 *
+	 * When deep cloning, we don't free the context: doing so would force
+	 * us to copy the data in the memory buffer.  Sicne we know we're
+	 * about to enter do_retrieve...
+	 */
+
+	clean_store_context(cxt);
+	if (cxt->prev && !(cxt->optype & ST_CLONE))
+		free_context(cxt);
+
+	TRACEME(("do_store returns %d", status));
+
+	return status == 0;
+}
+
+/*
+ * pstore
+ *
+ * Store the transitive data closure of given object to disk.
+ * Returns 0 on error, a true value otherwise.
+ */
+int pstore(PerlIO *f, SV *sv)
+{
+	TRACEME(("pstore"));
+	return do_store(f, sv, 0, FALSE, (SV**) 0);
+
+}
+
+/*
+ * net_pstore
+ *
+ * Same as pstore(), but network order is used for integers and doubles are
+ * emitted as strings.
+ */
+int net_pstore(PerlIO *f, SV *sv)
+{
+	TRACEME(("net_pstore"));
+	return do_store(f, sv, 0, TRUE, (SV**) 0);
+}
+
+/***
+ *** Memory stores.
+ ***/
+
+/*
+ * mbuf2sv
+ *
+ * Build a new SV out of the content of the internal memory buffer.
+ */
+static SV *mbuf2sv(void)
+{
+	dSTCXT;
+
+	return newSVpv(mbase, MBUF_SIZE());
+}
+
+/*
+ * mstore
+ *
+ * Store the transitive data closure of given object to memory.
+ * Returns undef on error, a scalar value containing the data otherwise.
+ */
+SV *mstore(SV *sv)
+{
+	dSTCXT;
+	SV *out;
+
+	TRACEME(("mstore"));
+
+	if (!do_store((PerlIO*) 0, sv, 0, FALSE, &out))
+		return &PL_sv_undef;
+
+	return out;
+}
+
+/*
+ * net_mstore
+ *
+ * Same as mstore(), but network order is used for integers and doubles are
+ * emitted as strings.
+ */
+SV *net_mstore(SV *sv)
+{
+	dSTCXT;
+	SV *out;
+
+	TRACEME(("net_mstore"));
+
+	if (!do_store((PerlIO*) 0, sv, 0, TRUE, &out))
+		return &PL_sv_undef;
+
+	return out;
+}
+
+/***
+ *** Specific retrieve callbacks.
+ ***/
+
+/*
+ * retrieve_other
+ *
+ * Return an error via croak, since it is not possible that we get here
+ * under normal conditions, when facing a file produced via pstore().
+ */
+static SV *retrieve_other(stcxt_t *cxt, char *cname)
+{
+	if (
+		cxt->ver_major != STORABLE_BIN_MAJOR &&
+		cxt->ver_minor != STORABLE_BIN_MINOR
+	) {
+		CROAK(("Corrupted storable %s (binary v%d.%d), current is v%d.%d",
+			cxt->fio ? "file" : "string",
+			cxt->ver_major, cxt->ver_minor,
+			STORABLE_BIN_MAJOR, STORABLE_BIN_MINOR));
+	} else {
+		CROAK(("Corrupted storable %s (binary v%d.%d)",
+			cxt->fio ? "file" : "string",
+			cxt->ver_major, cxt->ver_minor));
+	}
+
+	return (SV *) 0;		/* Just in case */
+}
+
+/*
+ * retrieve_idx_blessed
+ *
+ * Layout is SX_IX_BLESS <index> <object> with SX_IX_BLESS already read.
+ * <index> can be coded on either 1 or 5 bytes.
+ */
+static SV *retrieve_idx_blessed(stcxt_t *cxt, char *cname)
+{
+	I32 idx;
+	char *class;
+	SV **sva;
+	SV *sv;
+
+	TRACEME(("retrieve_idx_blessed (#%d)", cxt->tagnum));
+	ASSERT(!cname, ("no bless-into class given here, got %s", cname));
+
+	GETMARK(idx);			/* Index coded on a single char? */
+	if (idx & 0x80)
+		RLEN(idx);
 
 	/*
-	 * Call the proper routine to store this SV.
-	 * Abort immediately if we get a non-zero status back.
+	 * Fetch classname in `aclass'
 	 */
 
-	type = sv_type(sv);
-	TRACEME(("storing 0x%lx #%d type=%d...", (unsigned long) sv, tagnum, type));
-	if (ret = SV_STORE(type)(f, sv))
-		return ret;
+	sva = av_fetch(cxt->aclass, idx, FALSE);
+	if (!sva)
+		CROAK(("Class name #%d should have been seen already", idx));
+
+	class = SvPVX(*sva);	/* We know it's a PV, by construction */
+
+	TRACEME(("class ID %d => %s", idx, class));
 
 	/*
-	 * If object is blessed, notify the blessing now.
-	 *
-	 * Since the storable mechanism is going to make usage of lots
-	 * of blessed objects (!), we're trying to optimize the cost
-	 * by having two separate blessing notifications:
-	 *    SX_BLESS <char-len> <class> for short classnames (<255 chars)
-	 *    SX_LG_BLESS <int-len> <class> for larger classnames.
+	 * Retrieve object and bless it.
 	 */
 
-	if (SvOBJECT(sv)) {
-		char *class = HvNAME(SvSTASH(sv));
-		I32 len = strlen(class);
-		unsigned char clen;
-		TRACEME(("blessing 0x%lx in %s", (unsigned long) sv, class));
-		if (len <= LG_BLESS) {
-			PUTMARK(SX_BLESS);
-			clen = (unsigned char) len;
-			PUTMARK(clen);
-		} else {
-			PUTMARK(SX_LG_BLESS);
-			WLEN(len);
-		}
-		WRITE(class, len);		/* Final \0 is omitted */
-	}
-
-	PUTMARK(SX_STORED);
-	TRACEME(("ok (store 0x%lx)", (unsigned long) sv));
+	sv = retrieve(cxt, class);	/* First SV which is SEEN will be blessed */
 
-	return 0;	/* Done, with success */
+	return sv;
 }
 
 /*
- * magic_write
- *
- * Write magic number and system information into the file.
- * Layout is <magic> <network> [<len> <byteorder> <sizeof int> <sizeof long>
- * <sizeof ptr>] where <len> is the length of the byteorder hexa string.
- * All size and lenghts are written as single characters here.
+ * retrieve_blessed
  *
- * Note that no byte ordering info is emitted when <network> is true, since
- * integers will be emitted in network order in that case.
+ * Layout is SX_BLESS <len> <classname> <object> with SX_BLESS already read.
+ * <len> can be coded on either 1 or 5 bytes.
  */
-static int magic_write(f, use_network_order)
-PerlIO *f;
-int use_network_order;
+static SV *retrieve_blessed(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
-	char buf[256];	/* Enough room for 256 hexa digits */
-	unsigned char c;
+	I32 len;
+	SV *sv;
+	char buf[LG_BLESS + 1];		/* Avoid malloc() if possible */
+	char *class = buf;
 
-	TRACEME(("magic_write on fd=%d", fileno(f)));
+	TRACEME(("retrieve_blessed (#%d)", cxt->tagnum));
+	ASSERT(!cname, ("no bless-into class given here, got %s", cname));
 
-	if (f)
-		WRITE(magicstr, strlen(magicstr));	/* Don't write final \0 */
+	/*
+	 * Decode class name length and read that name.
+	 *
+	 * Short classnames have two advantages: their length is stored on one
+	 * single byte, and the string can be read on the stack.
+	 */
+
+	GETMARK(len);			/* Length coded on a single char? */
+	if (len & 0x80) {
+		RLEN(len);
+		TRACEME(("** allocating %d bytes for class name", len+1));
+		New(10003, class, len+1, char);
+	}
+	READ(class, len);
+	class[len] = '\0';		/* Mark string end */
 
 	/*
-	 * Starting with 0.6, the "use_network_order" byte flag is also used to
-	 * indicate the version number of the binary image, encoded in the upper
-	 * bits. The bit 0 is always used to indicate network order.
+	 * It's a new classname, otherwise it would have been an SX_IX_BLESS.
 	 */
 
-	c = (unsigned char)
-		((use_network_order ? 0x1 : 0x0) | (STORABLE_BINARY << 1));
-	PUTMARK(c);
+	TRACEME(("new class name \"%s\" will bear ID = %d", class, cxt->classnum));
 
-	if (use_network_order)
-		return 0;						/* Don't bother with byte ordering */
+	if (!av_store(cxt->aclass, cxt->classnum++, newSVpvn(class, len)))
+		return (SV *) 0;
 
-	sprintf(buf, "%lx", (unsigned long) BYTEORDER);
-	c = (unsigned char) strlen(buf);
-	PUTMARK(c);
-	WRITE(buf, (unsigned int) c);		/* Don't write final \0 */
-	PUTMARK((unsigned char) sizeof(int));
-	PUTMARK((unsigned char) sizeof(long));
-	PUTMARK((unsigned char) sizeof(char *));
+	/*
+	 * Retrieve object and bless it.
+	 */
 
-	TRACEME(("ok (magic_write byteorder = 0x%lx [%d], I%d L%d P%d)",
-		(unsigned long) BYTEORDER, (int) c,
-		sizeof(int), sizeof(long), sizeof(char *)));
+	sv = retrieve(cxt, class);	/* First SV which is SEEN will be blessed */
+	if (class != buf)
+		Safefree(class);
 
-	return 0;
+	return sv;
 }
 
 /*
- * do_store
+ * retrieve_hook
  *
- * Common code for pstore() and net_pstore().
+ * Layout: SX_HOOK <flags> <len> <classname> <len2> <str> [<len3> <object-IDs>]
+ * with leading mark already read, as usual.
+ *
+ * When recursion was involved during serialization of the object, there
+ * is an unknown amount of serialized objects after the SX_HOOK mark.  Until
+ * we reach a <flags> marker with the recursion bit cleared.
+ *
+ * If the first <flags> byte contains a type of SHT_EXTRA, then the real type
+ * is held in the <extra> byte, and if the object is tied, the serialized
+ * magic object comes at the very end:
+ *
+ *     SX_HOOK <flags> <extra> ... [<len3> <object-IDs>] <magic object>
+ *
+ * This means the STORABLE_thaw hook will NOT get a tied variable during its
+ * processing (since we won't have seen the magic object by the time the hook
+ * is called).  See comments below for why it was done that way.
  */
-static int do_store(f, sv, use_network_order)
-PerlIO *f;
-SV *sv;
-int use_network_order;
+static SV *retrieve_hook(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
-	int status;
-
-	netorder = use_network_order;	/* Global, not suited for multi-thread */
-	forgive_me = -1;				/* Unknown, fetched from perl if needed */
-	canonical = -1;					/* Idem */
-	tagnum = 0;						/* Reset tag numbers */
+	I32 len;
+	char buf[LG_BLESS + 1];		/* Avoid malloc() if possible */
+	char *class = buf;
+	unsigned int flags;
+	I32 len2;
+	SV *frozen;
+	I32 len3 = 0;
+	AV *av = 0;
+	SV *hook;
+	SV *sv;
+	SV *rv;
+	int obj_type;
+	I32 classname;
+	int clone = cxt->optype & ST_CLONE;
+	char mtype = '\0';
+	unsigned int extra_type = 0;
 
-	if (-1 == magic_write(f, netorder))	/* Emit magic number and system info */
-		return 0;						/* Error */
+	TRACEME(("retrieve_hook (#%d)", cxt->tagnum));
+	ASSERT(!cname, ("no bless-into class given here, got %s", cname));
 
 	/*
-	 * Ensure sv is actually a reference. From perl, we called something
-	 * like:
-	 *       pstore(FILE, \@array);
-	 * so we must get the scalar value behing that reference.
+	 * Read flags, which tell us about the type, and whether we need to recurse.
 	 */
 
-	if (!SvROK(sv))
-		croak("Not a reference");
-	sv = SvRV(sv);			/* So follow it to know what to store */
+	GETMARK(flags);
 
 	/*
-	 * The hash table used to keep track of each SV stored and their
-	 * associated tag numbers is special. It is "abused" because the
-	 * values stored are not real SV, just integers cast to (SV *),
-	 * which explains the freeing below.
+	 * Create the (empty) object, and mark it as seen.
 	 *
-	 * It is also one possible bottlneck to achieve good storing speed,
-	 * so the "shared keys" optimization is turned off (unlikely to be
-	 * of any use here), and the hash table is "pre-extended". Together,
-	 * those optimizations increase the throughput by 12%.
+	 * This must be done now, because tags are incremented, and during
+	 * serialization, the object tag was affected before recursion could
+	 * take place.
 	 */
 
-	hseen = newHV();			/* Table where seen objects are stored */
-	HvSHAREKEYS_off(hseen);
+	obj_type = flags & SHF_TYPE_MASK;
+	switch (obj_type) {
+	case SHT_SCALAR:
+		sv = newSV(0);
+		break;
+	case SHT_ARRAY:
+		sv = (SV *) newAV();
+		break;
+	case SHT_HASH:
+		sv = (SV *) newHV();
+		break;
+	case SHT_EXTRA:
+		/*
+		 * Read <extra> flag to know the type of the object.
+		 * Record associated magic type for later.
+		 */
+		GETMARK(extra_type);
+		switch (extra_type) {
+		case SHT_TSCALAR:
+			sv = newSV(0);
+			mtype = 'q';
+			break;
+		case SHT_TARRAY:
+			sv = (SV *) newAV();
+			mtype = 'P';
+			break;
+		case SHT_THASH:
+			sv = (SV *) newHV();
+			mtype = 'P';
+			break;
+		default:
+			return retrieve_other(cxt, 0);	/* Let it croak */
+		}
+		break;
+	default:
+		return retrieve_other(cxt, 0);		/* Let it croak */
+	}
+	SEEN(sv, 0);							/* Don't bless yet */
 
 	/*
-	 * The following does not work well with perl5.004_04, and causes
-	 * a core dump later on, in a completely unrelated spot, which
-	 * makes me think there is a memory corruption going on.
+	 * Whilst flags tell us to recurse, do so.
 	 *
-	 * Calling hv_ksplit(hseen, HBUCKETS) instead of manually hacking
-	 * it below does not make any difference. It seems to work fine
-	 * with perl5.004_68 but given the probable nature of the bug,
-	 * that does not prove anything.
+	 * We don't need to remember the addresses returned by retrieval, because
+	 * all the references will be obtained through indirection via the object
+	 * tags in the object-ID list.
+	 */
+
+	while (flags & SHF_NEED_RECURSE) {
+		TRACEME(("retrieve_hook recursing..."));
+		rv = retrieve(cxt, 0);
+		if (!rv)
+			return (SV *) 0;
+		TRACEME(("retrieve_hook back with rv=0x%"UVxf,
+			 PTR2UV(rv)));
+		GETMARK(flags);
+	}
+
+	if (flags & SHF_IDX_CLASSNAME) {
+		SV **sva;
+		I32 idx;
+
+		/*
+		 * Fetch index from `aclass'
+		 */
+
+		if (flags & SHF_LARGE_CLASSLEN)
+			RLEN(idx);
+		else
+			GETMARK(idx);
+
+		sva = av_fetch(cxt->aclass, idx, FALSE);
+		if (!sva)
+			CROAK(("Class name #%d should have been seen already", idx));
+
+		class = SvPVX(*sva);	/* We know it's a PV, by construction */
+		TRACEME(("class ID %d => %s", idx, class));
+
+	} else {
+		/*
+		 * Decode class name length and read that name.
+		 *
+		 * NOTA BENE: even if the length is stored on one byte, we don't read
+		 * on the stack.  Just like retrieve_blessed(), we limit the name to
+		 * LG_BLESS bytes.  This is an arbitrary decision.
+		 */
+
+		if (flags & SHF_LARGE_CLASSLEN)
+			RLEN(len);
+		else
+			GETMARK(len);
+
+		if (len > LG_BLESS) {
+			TRACEME(("** allocating %d bytes for class name", len+1));
+			New(10003, class, len+1, char);
+		}
+
+		READ(class, len);
+		class[len] = '\0';		/* Mark string end */
+
+		/*
+		 * Record new classname.
+		 */
+
+		if (!av_store(cxt->aclass, cxt->classnum++, newSVpvn(class, len)))
+			return (SV *) 0;
+	}
+
+	TRACEME(("class name: %s", class));
+
+	/*
+	 * Decode user-frozen string length and read it in a SV.
 	 *
-	 * It's a shame because increasing the amount of buckets raises
-	 * store() throughput by 5%, but until I figure this out, I can't
-	 * allow for this to go into production.
+	 * For efficiency reasons, we read data directly into the SV buffer.
+	 * To understand that code, read retrieve_scalar()
 	 */
-#if 0
-#define HBUCKETS	4096			/* Buckets for %hseen */
-	HvMAX(hseen) = HBUCKETS - 1;	/* keys %hseen = $HBUCKETS; */
-#endif
+
+	if (flags & SHF_LARGE_STRLEN)
+		RLEN(len2);
+	else
+		GETMARK(len2);
+
+	frozen = NEWSV(10002, len2);
+	if (len2) {
+		SAFEREAD(SvPVX(frozen), len2, frozen);
+		SvCUR_set(frozen, len2);
+		*SvEND(frozen) = '\0';
+	}
+	(void) SvPOK_only(frozen);		/* Validates string pointer */
+	if (cxt->s_tainted)				/* Is input source tainted? */
+		SvTAINT(frozen);
+
+	TRACEME(("frozen string: %d bytes", len2));
 
 	/*
-	 * Recursively store object...
+	 * Decode object-ID list length, if present.
 	 */
 
-	status = store(f, sv);		/* Just do it! */
+	if (flags & SHF_HAS_LIST) {
+		if (flags & SHF_LARGE_LISTLEN)
+			RLEN(len3);
+		else
+			GETMARK(len3);
+		if (len3) {
+			av = newAV();
+			av_extend(av, len3 + 1);	/* Leave room for [0] */
+			AvFILLp(av) = len3;			/* About to be filled anyway */
+		}
+	}
+
+	TRACEME(("has %d object IDs to link", len3));
+
+	/*
+	 * Read object-ID list into array.
+	 * Because we pre-extended it, we can cheat and fill it manually.
+	 *
+	 * We read object tags and we can convert them into SV* on the fly
+	 * because we know all the references listed in there (as tags)
+	 * have been already serialized, hence we have a valid correspondance
+	 * between each of those tags and the recreated SV.
+	 */
+
+	if (av) {
+		SV **ary = AvARRAY(av);
+		int i;
+		for (i = 1; i <= len3; i++) {	/* We leave [0] alone */
+			I32 tag;
+			SV **svh;
+			SV *xsv;
+
+			READ_I32(tag);
+			tag = ntohl(tag);
+			svh = av_fetch(cxt->aseen, tag, FALSE);
+			if (!svh)
+				CROAK(("Object #%d should have been retrieved already", tag));
+			xsv = *svh;
+			ary[i] = SvREFCNT_inc(xsv);
+		}
+	}
 
 	/*
-	 * Need to free the hseen table, but since we have stored fake
-	 * value pointers in it, we need to make them real first.
+	 * Bless the object and look up the STORABLE_thaw hook.
 	 */
 
-	{
-		HE * he;
+	BLESS(sv, class);
+	hook = pkg_can(cxt->hook, SvSTASH(sv), "STORABLE_thaw");
+	if (!hook) {
+		/*
+		 * Hook not found.  Maybe they did not require the module where this
+		 * hook is defined yet?
+		 *
+		 * If the require below succeeds, we'll be able to find the hook.
+		 * Still, it only works reliably when each class is defined in a
+		 * file of its own.
+		 */
+
+		SV *psv = newSVpvn("require ", 8);
+		sv_catpv(psv, class);
+
+		TRACEME(("No STORABLE_thaw defined for objects of class %s", class));
+		TRACEME(("Going to require module '%s' with '%s'", class, SvPVX(psv)));
 
-		hv_iterinit(hseen);
-		while (he = hv_iternext(hseen))
-			HeVAL(he) = &PL_sv_undef;
+		perl_eval_sv(psv, G_DISCARD);
+		sv_free(psv);
+
+		/*
+		 * We cache results of pkg_can, so we need to uncache before attempting
+		 * the lookup again.
+		 */
+
+		pkg_uncache(cxt->hook, SvSTASH(sv), "STORABLE_thaw");
+		hook = pkg_can(cxt->hook, SvSTASH(sv), "STORABLE_thaw");
+
+		if (!hook)
+			CROAK(("No STORABLE_thaw defined for objects of class %s "
+					"(even after a \"require %s;\")", class, class));
 	}
-	hv_undef(hseen);		/* Free seen object table */
-	sv_free((SV *) hseen);	/* Free HV */
 
-	TRACEME(("do_store returns %d", status));
+	/*
+	 * If we don't have an `av' yet, prepare one.
+	 * Then insert the frozen string as item [0].
+	 */
 
-	return status == 0;
-}
+	if (!av) {
+		av = newAV();
+		av_extend(av, 1);
+		AvFILLp(av) = 0;
+	}
+	AvARRAY(av)[0] = SvREFCNT_inc(frozen);
 
-/*
- * mbuf2sv
- *
- * Build a new SV out of the content of the internal memory buffer.
- */
-static SV *mbuf2sv()
-{
-	dPERINTERP;
-	return newSVpv(mbase, MBUF_SIZE());
-}
+	/*
+	 * Call the hook as:
+	 *
+	 *   $object->STORABLE_thaw($cloning, $frozen, @refs);
+	 * 
+	 * where $object is our blessed (empty) object, $cloning is a boolean
+	 * telling whether we're running a deep clone, $frozen is the frozen
+	 * string the user gave us in his serializing hook, and @refs, which may
+	 * be empty, is the list of extra references he returned along for us
+	 * to serialize.
+	 *
+	 * In effect, the hook is an alternate creation routine for the class,
+	 * the object itself being already created by the runtime.
+	 */
 
-/*
- * mstore
- *
- * Store the transitive data closure of given object to memory.
- * Returns undef on error, a scalar value containing the data otherwise.
- */
-SV *mstore(sv)
-SV *sv;
-{
-	dPERINTERP;
-	TRACEME(("mstore"));
-	MBUF_INIT(0);
-	if (!do_store(0, sv, FALSE))		/* Not in network order */
-		return &PL_sv_undef;
+	TRACEME(("calling STORABLE_thaw on %s at 0x%"UVxf" (%"IVdf" args)",
+		 class, PTR2UV(sv), AvFILLp(av) + 1));
 
-	return mbuf2sv();
-}
+	rv = newRV(sv);
+	(void) scalar_call(rv, hook, clone, av, G_SCALAR|G_DISCARD);
+	SvREFCNT_dec(rv);
 
-/*
- * net_mstore
- *
- * Same as mstore(), but network order is used for integers and doubles are
- * emitted as strings.
- */
-SV *net_mstore(sv)
-SV *sv;
-{
-	dPERINTERP;
-	TRACEME(("net_mstore"));
-	MBUF_INIT(0);
-	if (!do_store(0, sv, TRUE))	/* Use network order */
-		return &PL_sv_undef;
+	/*
+	 * Final cleanup.
+	 */
 
-	return mbuf2sv();
-}
+	SvREFCNT_dec(frozen);
+	av_undef(av);
+	sv_free((SV *) av);
+	if (!(flags & SHF_IDX_CLASSNAME) && class != buf)
+		Safefree(class);
 
-/*
- * pstore
- *
- * Store the transitive data closure of given object to disk.
- * Returns 0 on error, a true value otherwise.
- */
-int pstore(f, sv)
-PerlIO *f;
-SV *sv;
-{
-	TRACEME(("pstore"));
-	return do_store(f, sv, FALSE);	/* Not in network order */
+	/*
+	 * If we had an <extra> type, then the object was not as simple, and
+	 * we need to restore extra magic now.
+	 */
 
-}
+	if (!extra_type)
+		return sv;
 
-/*
- * net_pstore
- *
- * Same as pstore(), but network order is used for integers and doubles are
- * emitted as strings.
- */
-int net_pstore(f, sv)
-PerlIO *f;
-SV *sv;
-{
-	TRACEME(("net_pstore"));
-	return do_store(f, sv, TRUE);			/* Use network order */
+	TRACEME(("retrieving magic object for 0x%"UVxf"...", PTR2UV(sv)));
+
+	rv = retrieve(cxt, 0);		/* Retrieve <magic object> */
+
+	TRACEME(("restoring the magic object 0x%"UVxf" part of 0x%"UVxf,
+		PTR2UV(rv), PTR2UV(sv)));
+
+	switch (extra_type) {
+	case SHT_TSCALAR:
+		sv_upgrade(sv, SVt_PVMG);
+		break;
+	case SHT_TARRAY:
+		sv_upgrade(sv, SVt_PVAV);
+		AvREAL_off((AV *)sv);
+		break;
+	case SHT_THASH:
+		sv_upgrade(sv, SVt_PVHV);
+		break;
+	default:
+		CROAK(("Forgot to deal with extra type %d", extra_type));
+		break;
+	}
+
+	/*
+	 * Adding the magic only now, well after the STORABLE_thaw hook was called
+	 * means the hook cannot know it deals with an object whose variable is
+	 * tied.  But this is happening when retrieving $o in the following case:
+	 *
+	 *	my %h;
+	 *  tie %h, 'FOO';
+	 *	my $o = bless \%h, 'BAR';
+	 *
+	 * The 'BAR' class is NOT the one where %h is tied into.  Therefore, as
+	 * far as the 'BAR' class is concerned, the fact that %h is not a REAL
+	 * hash but a tied one should not matter at all, and remain transparent.
+	 * This means the magic must be restored by Storable AFTER the hook is
+	 * called.
+	 *
+	 * That looks very reasonable to me, but then I've come up with this
+	 * after a bug report from David Nesting, who was trying to store such
+	 * an object and caused Storable to fail.  And unfortunately, it was
+	 * also the easiest way to retrofit support for blessed ref to tied objects
+	 * into the existing design.  -- RAM, 17/02/2001
+	 */
+
+	sv_magic(sv, rv, mtype, Nullch, 0);
+	SvREFCNT_dec(rv);			/* Undo refcnt inc from sv_magic() */
+
+	return sv;
 }
 
 /*
@@ -1496,14 +3535,12 @@
  * Retrieve reference to some other scalar.
  * Layout is SX_REF <object>, with SX_REF already read.
  */
-static SV *retrieve_ref(f)
-PerlIO *f;
+static SV *retrieve_ref(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	SV *rv;
 	SV *sv;
 
-	TRACEME(("retrieve_ref (#%d)", tagnum));
+	TRACEME(("retrieve_ref (#%d)", cxt->tagnum));
 
 	/*
 	 * We need to create the SV that holds the reference to the yet-to-retrieve
@@ -1515,8 +3552,8 @@
 	 */
 
 	rv = NEWSV(10002, 0);
-	SEEN(rv);				/* Will return if rv is null */
-	sv = retrieve(f);		/* Retrieve <object> */
+	SEEN(rv, cname);		/* Will return if rv is null */
+	sv = retrieve(cxt, 0);	/* Retrieve <object> */
 	if (!sv)
 		return (SV *) 0;	/* Failed */
 
@@ -1541,7 +3578,57 @@
 	SvRV(rv) = sv;				/* $rv = \$sv */
 	SvROK_on(rv);
 
-	TRACEME(("ok (retrieve_ref at 0x%lx)", (unsigned long) rv));
+	TRACEME(("ok (retrieve_ref at 0x%"UVxf")", PTR2UV(rv)));
+
+	return rv;
+}
+
+/*
+ * retrieve_overloaded
+ *
+ * Retrieve reference to some other scalar with overloading.
+ * Layout is SX_OVERLOAD <object>, with SX_OVERLOAD already read.
+ */
+static SV *retrieve_overloaded(stcxt_t *cxt, char *cname)
+{
+	SV *rv;
+	SV *sv;
+	HV *stash;
+
+	TRACEME(("retrieve_overloaded (#%d)", cxt->tagnum));
+
+	/*
+	 * Same code as retrieve_ref(), duplicated to avoid extra call.
+	 */
+
+	rv = NEWSV(10002, 0);
+	SEEN(rv, cname);		/* Will return if rv is null */
+	sv = retrieve(cxt, 0);	/* Retrieve <object> */
+	if (!sv)
+		return (SV *) 0;	/* Failed */
+
+	/*
+	 * WARNING: breaks RV encapsulation.
+	 */
+
+	sv_upgrade(rv, SVt_RV);
+	SvRV(rv) = sv;				/* $rv = \$sv */
+	SvROK_on(rv);
+
+	/*
+	 * Restore overloading magic.
+	 */
+
+	stash = (HV *) SvSTASH (sv);
+	if (!stash || !Gv_AMG(stash))
+		CROAK(("Cannot restore overloading on %s(0x%"UVxf") (package %s)",
+		       sv_reftype(sv, FALSE),
+		       PTR2UV(sv),
+			   stash ? HvNAME(stash) : "<unknown>"));
+
+	SvAMAGIC_on(rv);
+
+	TRACEME(("ok (retrieve_overloaded at 0x%"UVxf")", PTR2UV(rv)));
 
 	return rv;
 }
@@ -1552,18 +3639,16 @@
  * Retrieve tied array
  * Layout is SX_TIED_ARRAY <object>, with SX_TIED_ARRAY already read.
  */
-static SV *retrieve_tied_array(f)
-PerlIO *f;
+static SV *retrieve_tied_array(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	SV *tv;
 	SV *sv;
 
-	TRACEME(("retrieve_tied_array (#%d)", tagnum));
+	TRACEME(("retrieve_tied_array (#%d)", cxt->tagnum));
 
 	tv = NEWSV(10002, 0);
-	SEEN(tv);					/* Will return if tv is null */
-	sv = retrieve(f);			/* Retrieve <object> */
+	SEEN(tv, cname);			/* Will return if tv is null */
+	sv = retrieve(cxt, 0);		/* Retrieve <object> */
 	if (!sv)
 		return (SV *) 0;		/* Failed */
 
@@ -1572,7 +3657,7 @@
 	sv_magic(tv, sv, 'P', Nullch, 0);
 	SvREFCNT_dec(sv);			/* Undo refcnt inc from sv_magic() */
 
-	TRACEME(("ok (retrieve_tied_array at 0x%lx)", (unsigned long) tv));
+	TRACEME(("ok (retrieve_tied_array at 0x%"UVxf")", PTR2UV(tv)));
 
 	return tv;
 }
@@ -1583,18 +3668,16 @@
  * Retrieve tied hash
  * Layout is SX_TIED_HASH <object>, with SX_TIED_HASH already read.
  */
-static SV *retrieve_tied_hash(f)
-PerlIO *f;
+static SV *retrieve_tied_hash(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	SV *tv;
 	SV *sv;
 
-	TRACEME(("retrieve_tied_hash (#%d)", tagnum));
+	TRACEME(("retrieve_tied_hash (#%d)", cxt->tagnum));
 
 	tv = NEWSV(10002, 0);
-	SEEN(tv);					/* Will return if rv is null */
-	sv = retrieve(f);			/* Retrieve <object> */
+	SEEN(tv, cname);			/* Will return if tv is null */
+	sv = retrieve(cxt, 0);		/* Retrieve <object> */
 	if (!sv)
 		return (SV *) 0;		/* Failed */
 
@@ -1602,7 +3685,7 @@
 	sv_magic(tv, sv, 'P', Nullch, 0);
 	SvREFCNT_dec(sv);			/* Undo refcnt inc from sv_magic() */
 
-	TRACEME(("ok (retrieve_tied_hash at 0x%lx)", (unsigned long) tv));
+	TRACEME(("ok (retrieve_tied_hash at 0x%"UVxf")", PTR2UV(tv)));
 
 	return tv;
 }
@@ -1613,18 +3696,16 @@
  * Retrieve tied scalar
  * Layout is SX_TIED_SCALAR <object>, with SX_TIED_SCALAR already read.
  */
-static SV *retrieve_tied_scalar(f)
-PerlIO *f;
+static SV *retrieve_tied_scalar(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	SV *tv;
 	SV *sv;
 
-	TRACEME(("retrieve_tied_scalar (#%d)", tagnum));
+	TRACEME(("retrieve_tied_scalar (#%d)", cxt->tagnum));
 
 	tv = NEWSV(10002, 0);
-	SEEN(tv);					/* Will return if rv is null */
-	sv = retrieve(f);			/* Retrieve <object> */
+	SEEN(tv, cname);			/* Will return if rv is null */
+	sv = retrieve(cxt, 0);		/* Retrieve <object> */
 	if (!sv)
 		return (SV *) 0;		/* Failed */
 
@@ -1632,11 +3713,73 @@
 	sv_magic(tv, sv, 'q', Nullch, 0);
 	SvREFCNT_dec(sv);			/* Undo refcnt inc from sv_magic() */
 
-	TRACEME(("ok (retrieve_tied_scalar at 0x%lx)", (unsigned long) tv));
+	TRACEME(("ok (retrieve_tied_scalar at 0x%"UVxf")", PTR2UV(tv)));
+
+	return tv;
+}
+
+/*
+ * retrieve_tied_key
+ *
+ * Retrieve reference to value in a tied hash.
+ * Layout is SX_TIED_KEY <object> <key>, with SX_TIED_KEY already read.
+ */
+static SV *retrieve_tied_key(stcxt_t *cxt, char *cname)
+{
+	SV *tv;
+	SV *sv;
+	SV *key;
+
+	TRACEME(("retrieve_tied_key (#%d)", cxt->tagnum));
+
+	tv = NEWSV(10002, 0);
+	SEEN(tv, cname);			/* Will return if tv is null */
+	sv = retrieve(cxt, 0);		/* Retrieve <object> */
+	if (!sv)
+		return (SV *) 0;		/* Failed */
+
+	key = retrieve(cxt, 0);		/* Retrieve <key> */
+	if (!key)
+		return (SV *) 0;		/* Failed */
+
+	sv_upgrade(tv, SVt_PVMG);
+	sv_magic(tv, sv, 'p', (char *)key, HEf_SVKEY);
+	SvREFCNT_dec(key);			/* Undo refcnt inc from sv_magic() */
+	SvREFCNT_dec(sv);			/* Undo refcnt inc from sv_magic() */
+
+	return tv;
+}
+
+/*
+ * retrieve_tied_idx
+ *
+ * Retrieve reference to value in a tied array.
+ * Layout is SX_TIED_IDX <object> <idx>, with SX_TIED_IDX already read.
+ */
+static SV *retrieve_tied_idx(stcxt_t *cxt, char *cname)
+{
+	SV *tv;
+	SV *sv;
+	I32 idx;
+
+	TRACEME(("retrieve_tied_idx (#%d)", cxt->tagnum));
+
+	tv = NEWSV(10002, 0);
+	SEEN(tv, cname);			/* Will return if tv is null */
+	sv = retrieve(cxt, 0);		/* Retrieve <object> */
+	if (!sv)
+		return (SV *) 0;		/* Failed */
+
+	RLEN(idx);					/* Retrieve <idx> */
+
+	sv_upgrade(tv, SVt_PVMG);
+	sv_magic(tv, sv, 'p', Nullch, idx);
+	SvREFCNT_dec(sv);			/* Undo refcnt inc from sv_magic() */
 
 	return tv;
 }
 
+
 /*
  * retrieve_lscalar
  *
@@ -1646,22 +3789,20 @@
  * The scalar is "long" in that <length> is larger than LG_SCALAR so it
  * was not stored on a single byte.
  */
-static SV *retrieve_lscalar(f)
-PerlIO *f;
+static SV *retrieve_lscalar(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
-	STRLEN len;
+	I32 len;
 	SV *sv;
 
 	RLEN(len);
-	TRACEME(("retrieve_lscalar (#%d), len = %d", tagnum, len));
+	TRACEME(("retrieve_lscalar (#%d), len = %"IVdf, cxt->tagnum, len));
 
 	/*
 	 * Allocate an empty scalar of the suitable length.
 	 */
 
 	sv = NEWSV(10002, len);
-	SEEN(sv);			/* Associate this new scalar with tag "tagnum" */
+	SEEN(sv, cname);	/* Associate this new scalar with tag "tagnum" */
 
 	/*
 	 * WARNING: duplicates parts of sv_setpv and breaks SV data encapsulation.
@@ -1676,10 +3817,11 @@
 	SvCUR_set(sv, len);				/* Record C string length */
 	*SvEND(sv) = '\0';				/* Ensure it's null terminated anyway */
 	(void) SvPOK_only(sv);			/* Validate string pointer */
-	SvTAINT(sv);					/* External data cannot be trusted */
+	if (cxt->s_tainted)				/* Is input source tainted? */
+		SvTAINT(sv);				/* External data cannot be trusted */
 
-	TRACEME(("large scalar len %d '%s'", len, SvPVX(sv)));
-	TRACEME(("ok (retrieve_lscalar at 0x%lx)", (unsigned long) sv));
+	TRACEME(("large scalar len %"IVdf" '%s'", len, SvPVX(sv)));
+	TRACEME(("ok (retrieve_lscalar at 0x%"UVxf")", PTR2UV(sv)));
 
 	return sv;
 }
@@ -1693,22 +3835,20 @@
  * The scalar is "short" so <length> is single byte. If it is 0, there
  * is no <data> section.
  */
-static SV *retrieve_scalar(f)
-PerlIO *f;
+static SV *retrieve_scalar(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	int len;
 	SV *sv;
 
 	GETMARK(len);
-	TRACEME(("retrieve_scalar (#%d), len = %d", tagnum, len));
+	TRACEME(("retrieve_scalar (#%d), len = %d", cxt->tagnum, len));
 
 	/*
 	 * Allocate an empty scalar of the suitable length.
 	 */
 
 	sv = NEWSV(10002, len);
-	SEEN(sv);			/* Associate this new scalar with tag "tagnum" */
+	SEEN(sv, cname);	/* Associate this new scalar with tag "tagnum" */
 
 	/*
 	 * WARNING: duplicates parts of sv_setpv and breaks SV data encapsulation.
@@ -1722,7 +3862,7 @@
 		sv_upgrade(sv, SVt_PV);
 		SvGROW(sv, 1);
 		*SvEND(sv) = '\0';			/* Ensure it's null terminated anyway */
-		TRACEME(("ok (retrieve_scalar empty at 0x%lx)", (unsigned long) sv));
+		TRACEME(("ok (retrieve_scalar empty at 0x%"UVxf")", PTR2UV(sv)));
 	} else {
 		/*
 		 * Now, for efficiency reasons, read data directly inside the SV buffer,
@@ -1737,9 +3877,48 @@
 	}
 
 	(void) SvPOK_only(sv);			/* Validate string pointer */
-	SvTAINT(sv);					/* External data cannot be trusted */
+	if (cxt->s_tainted)				/* Is input source tainted? */
+		SvTAINT(sv);				/* External data cannot be trusted */
+
+	TRACEME(("ok (retrieve_scalar at 0x%"UVxf")", PTR2UV(sv)));
+	return sv;
+}
+
+/*
+ * retrieve_utf8str
+ *
+ * Like retrieve_scalar(), but tag result as utf8.
+ * If we're retrieving UTF8 data in a non-UTF8 perl, croaks.
+ */
+static SV *retrieve_utf8str(stcxt_t *cxt, char *cname)
+{
+	SV *sv;
+
+	TRACEME(("retrieve_utf8str"));
+
+	sv = retrieve_scalar(cxt, cname);
+	if (sv)
+		SvUTF8_on(sv);
+
+	return sv;
+}
+
+/*
+ * retrieve_lutf8str
+ *
+ * Like retrieve_lscalar(), but tag result as utf8.
+ * If we're retrieving UTF8 data in a non-UTF8 perl, croaks.
+ */
+static SV *retrieve_lutf8str(stcxt_t *cxt, char *cname)
+{
+	SV *sv;
+
+	TRACEME(("retrieve_lutf8str"));
+
+	sv = retrieve_lscalar(cxt, cname);
+	if (sv)
+		SvUTF8_on(sv);
 
-	TRACEME(("ok (retrieve_scalar at 0x%lx)", (unsigned long) sv));
 	return sv;
 }
 
@@ -1749,21 +3928,19 @@
  * Retrieve defined integer.
  * Layout is SX_INTEGER <data>, whith SX_INTEGER already read.
  */
-static SV *retrieve_integer(f)
-PerlIO *f;
+static SV *retrieve_integer(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	SV *sv;
 	IV iv;
 
-	TRACEME(("retrieve_integer (#%d)", tagnum));
+	TRACEME(("retrieve_integer (#%d)", cxt->tagnum));
 
 	READ(&iv, sizeof(iv));
 	sv = newSViv(iv);
-	SEEN(sv);			/* Associate this new scalar with tag "tagnum" */
+	SEEN(sv, cname);	/* Associate this new scalar with tag "tagnum" */
 
-	TRACEME(("integer %d", iv));
-	TRACEME(("ok (retrieve_integer at 0x%lx)", (unsigned long) sv));
+	TRACEME(("integer %"IVdf, iv));
+	TRACEME(("ok (retrieve_integer at 0x%"UVxf")", PTR2UV(sv)));
 
 	return sv;
 }
@@ -1774,16 +3951,14 @@
  * Retrieve defined integer in network order.
  * Layout is SX_NETINT <data>, whith SX_NETINT already read.
  */
-static SV *retrieve_netint(f)
-PerlIO *f;
+static SV *retrieve_netint(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	SV *sv;
-	int iv;
+	I32 iv;
 
-	TRACEME(("retrieve_netint (#%d)", tagnum));
+	TRACEME(("retrieve_netint (#%d)", cxt->tagnum));
 
-	READ(&iv, sizeof(iv));
+	READ_I32(iv);
 #ifdef HAS_NTOHL
 	sv = newSViv((int) ntohl(iv));
 	TRACEME(("network integer %d", (int) ntohl(iv)));
@@ -1791,9 +3966,9 @@
 	sv = newSViv(iv);
 	TRACEME(("network integer (as-is) %d", iv));
 #endif
-	SEEN(sv);			/* Associate this new scalar with tag "tagnum" */
+	SEEN(sv, cname);	/* Associate this new scalar with tag "tagnum" */
 
-	TRACEME(("ok (retrieve_netint at 0x%lx)", (unsigned long) sv));
+	TRACEME(("ok (retrieve_netint at 0x%"UVxf")", PTR2UV(sv)));
 
 	return sv;
 }
@@ -1804,21 +3979,19 @@
  * Retrieve defined double.
  * Layout is SX_DOUBLE <data>, whith SX_DOUBLE already read.
  */
-static SV *retrieve_double(f)
-PerlIO *f;
+static SV *retrieve_double(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	SV *sv;
-	double nv;
+	NV nv;
 
-	TRACEME(("retrieve_double (#%d)", tagnum));
+	TRACEME(("retrieve_double (#%d)", cxt->tagnum));
 
 	READ(&nv, sizeof(nv));
 	sv = newSVnv(nv);
-	SEEN(sv);			/* Associate this new scalar with tag "tagnum" */
+	SEEN(sv, cname);	/* Associate this new scalar with tag "tagnum" */
 
-	TRACEME(("double %lf", nv));
-	TRACEME(("ok (retrieve_double at 0x%lx)", (unsigned long) sv));
+	TRACEME(("double %"NVff, nv));
+	TRACEME(("ok (retrieve_double at 0x%"UVxf")", PTR2UV(sv)));
 
 	return sv;
 }
@@ -1829,22 +4002,20 @@
  * Retrieve defined byte (small integer within the [-128, +127] range).
  * Layout is SX_BYTE <data>, whith SX_BYTE already read.
  */
-static SV *retrieve_byte(f)
-PerlIO *f;
+static SV *retrieve_byte(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	SV *sv;
 	int siv;
 
-	TRACEME(("retrieve_byte (#%d)", tagnum));
+	TRACEME(("retrieve_byte (#%d)", cxt->tagnum));
 
 	GETMARK(siv);
 	TRACEME(("small integer read as %d", (unsigned char) siv));
 	sv = newSViv((unsigned char) siv - 128);
-	SEEN(sv);			/* Associate this new scalar with tag "tagnum" */
+	SEEN(sv, cname);	/* Associate this new scalar with tag "tagnum" */
 
 	TRACEME(("byte %d", (unsigned char) siv - 128));
-	TRACEME(("ok (retrieve_byte at 0x%lx)", (unsigned long) sv));
+	TRACEME(("ok (retrieve_byte at 0x%"UVxf")", PTR2UV(sv)));
 
 	return sv;
 }
@@ -1854,15 +4025,14 @@
  *
  * Return the undefined value.
  */
-static SV *retrieve_undef()
+static SV *retrieve_undef(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	SV* sv;
 
 	TRACEME(("retrieve_undef"));
 
 	sv = newSV(0);
-	SEEN(sv);
+	SEEN(sv, cname);
 
 	return sv;
 }
@@ -1872,14 +4042,13 @@
  *
  * Return the immortal undefined value.
  */
-static SV *retrieve_sv_undef()
+static SV *retrieve_sv_undef(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	SV *sv = &PL_sv_undef;
 
 	TRACEME(("retrieve_sv_undef"));
 
-	SEEN(sv);
+	SEEN(sv, cname);
 	return sv;
 }
 
@@ -1888,14 +4057,13 @@
  *
  * Return the immortal yes value.
  */
-static SV *retrieve_sv_yes()
+static SV *retrieve_sv_yes(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	SV *sv = &PL_sv_yes;
 
 	TRACEME(("retrieve_sv_yes"));
 
-	SEEN(sv);
+	SEEN(sv, cname);
 	return sv;
 }
 
@@ -1904,30 +4072,17 @@
  *
  * Return the immortal no value.
  */
-static SV *retrieve_sv_no()
+static SV *retrieve_sv_no(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	SV *sv = &PL_sv_no;
 
 	TRACEME(("retrieve_sv_no"));
 
-	SEEN(sv);
+	SEEN(sv, cname);
 	return sv;
 }
 
 /*
- * retrieve_other
- *
- * Return an error via croak, since it is not possible that we get here
- * under normal conditions, when facing a file produced via pstore().
- */
-static SV *retrieve_other()
-{
-	croak("Corrupted perl storable file");
-	return (SV *) 0;
-}
-
-/*
  * retrieve_array
  *
  * Retrieve a whole array.
@@ -1936,16 +4091,14 @@
  *
  * When we come here, SX_ARRAY has been read already.
  */
-static SV *retrieve_array(f)
-PerlIO *f;
+static SV *retrieve_array(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	I32 len;
 	I32 i;
 	AV *av;
 	SV *sv;
 
-	TRACEME(("retrieve_array (#%d)", tagnum));
+	TRACEME(("retrieve_array (#%d)", cxt->tagnum));
 
 	/*
 	 * Read length, and allocate array, then pre-extend it.
@@ -1954,7 +4107,7 @@
 	RLEN(len);
 	TRACEME(("size = %d", len));
 	av = newAV();
-	SEEN(av);					/* Will return if array not allocated nicely */
+	SEEN(av, cname);			/* Will return if array not allocated nicely */
 	if (len)
 		av_extend(av, len);
 	else
@@ -1966,14 +4119,14 @@
 
 	for (i = 0; i < len; i++) {
 		TRACEME(("(#%d) item", i));
-		sv = retrieve(f);				/* Retrieve item */
+		sv = retrieve(cxt, 0);			/* Retrieve item */
 		if (!sv)
 			return (SV *) 0;
 		if (av_store(av, i, sv) == 0)
 			return (SV *) 0;
 	}
 
-	TRACEME(("ok (retrieve_array at 0x%lx)", (unsigned long) av));
+	TRACEME(("ok (retrieve_array at 0x%"UVxf")", PTR2UV(av)));
 
 	return (SV *) av;
 }
@@ -1989,10 +4142,8 @@
  *
  * When we come here, SX_HASH has been read already.
  */
-static SV *retrieve_hash(f)
-PerlIO *f;
+static SV *retrieve_hash(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	I32 len;
 	I32 size;
 	I32 i;
@@ -2000,7 +4151,7 @@
 	SV *sv;
 	static SV *sv_h_undef = (SV *) 0;		/* hv_store() bug */
 
-	TRACEME(("retrieve_hash (#%d)", tagnum));
+	TRACEME(("retrieve_hash (#%d)", cxt->tagnum));
 
 	/*
 	 * Read length, allocate table.
@@ -2009,7 +4160,7 @@
 	RLEN(len);
 	TRACEME(("size = %d", len));
 	hv = newHV();
-	SEEN(hv);			/* Will return if table not allocated properly */
+	SEEN(hv, cname);		/* Will return if table not allocated properly */
 	if (len == 0)
 		return (SV *) hv;	/* No data follow if table empty */
 
@@ -2023,7 +4174,7 @@
 		 */
 
 		TRACEME(("(#%d) value", i));
-		sv = retrieve(f);
+		sv = retrieve(cxt, 0);
 		if (!sv)
 			return (SV *) 0;
 
@@ -2049,7 +4200,7 @@
 			return (SV *) 0;
 	}
 
-	TRACEME(("ok (retrieve_hash at 0x%lx)", (unsigned long) hv));
+	TRACEME(("ok (retrieve_hash at 0x%"UVxf")", PTR2UV(hv)));
 
 	return (SV *) hv;
 }
@@ -2064,17 +4215,15 @@
  *
  * When we come here, SX_ARRAY has been read already.
  */
-static SV *old_retrieve_array(f)
-PerlIO *f;
+static SV *old_retrieve_array(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	I32 len;
 	I32 i;
 	AV *av;
 	SV *sv;
 	int c;
 
-	TRACEME(("old_retrieve_array (#%d)", tagnum));
+	TRACEME(("old_retrieve_array (#%d)", cxt->tagnum));
 
 	/*
 	 * Read length, and allocate array, then pre-extend it.
@@ -2083,7 +4232,7 @@
 	RLEN(len);
 	TRACEME(("size = %d", len));
 	av = newAV();
-	SEEN(av);					/* Will return if array not allocated nicely */
+	SEEN(av, 0);				/* Will return if array not allocated nicely */
 	if (len)
 		av_extend(av, len);
 	else
@@ -2100,16 +4249,16 @@
 			continue;			/* av_extend() already filled us with undef */
 		}
 		if (c != SX_ITEM)
-			(void) retrieve_other();	/* Will croak out */
+			(void) retrieve_other((stcxt_t *) 0, 0);	/* Will croak out */
 		TRACEME(("(#%d) item", i));
-		sv = retrieve(f);				/* Retrieve item */
+		sv = retrieve(cxt, 0);						/* Retrieve item */
 		if (!sv)
 			return (SV *) 0;
 		if (av_store(av, i, sv) == 0)
 			return (SV *) 0;
 	}
 
-	TRACEME(("ok (old_retrieve_array at 0x%lx)", (unsigned long) av));
+	TRACEME(("ok (old_retrieve_array at 0x%"UVxf")", PTR2UV(av)));
 
 	return (SV *) av;
 }
@@ -2126,10 +4275,8 @@
  *
  * When we come here, SX_HASH has been read already.
  */
-static SV *old_retrieve_hash(f)
-PerlIO *f;
+static SV *old_retrieve_hash(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	I32 len;
 	I32 size;
 	I32 i;
@@ -2138,7 +4285,7 @@
 	int c;
 	static SV *sv_h_undef = (SV *) 0;		/* hv_store() bug */
 
-	TRACEME(("old_retrieve_hash (#%d)", tagnum));
+	TRACEME(("old_retrieve_hash (#%d)", cxt->tagnum));
 
 	/*
 	 * Read length, allocate table.
@@ -2147,7 +4294,7 @@
 	RLEN(len);
 	TRACEME(("size = %d", len));
 	hv = newHV();
-	SEEN(hv);				/* Will return if table not allocated properly */
+	SEEN(hv, 0);			/* Will return if table not allocated properly */
 	if (len == 0)
 		return (SV *) hv;	/* No data follow if table empty */
 
@@ -2173,11 +4320,11 @@
 			sv = SvREFCNT_inc(sv_h_undef);
 		} else if (c == SX_VALUE) {
 			TRACEME(("(#%d) value", i));
-			sv = retrieve(f);
+			sv = retrieve(cxt, 0);
 			if (!sv)
 				return (SV *) 0;
 		} else
-			(void) retrieve_other();	/* Will croak out */
+			(void) retrieve_other((stcxt_t *) 0, 0);	/* Will croak out */
 
 		/*
 		 * Get key.
@@ -2188,7 +4335,7 @@
 
 		GETMARK(c);
 		if (c != SX_KEY)
-			(void) retrieve_other();	/* Will croak out */
+			(void) retrieve_other((stcxt_t *) 0, 0);	/* Will croak out */
 		RLEN(size);						/* Get key size */
 		KBUFCHK(size);					/* Grow hash key read pool if needed */
 		if (size)
@@ -2204,60 +4351,14 @@
 			return (SV *) 0;
 	}
 
-	TRACEME(("ok (retrieve_hash at 0x%lx)", (unsigned long) hv));
+	TRACEME(("ok (retrieve_hash at 0x%"UVxf")", PTR2UV(hv)));
 
 	return (SV *) hv;
 }
 
-/*
- * Dynamic dispatching tables for SV retrieval.
- */
-
-static SV *(*sv_old_retrieve[])() = {
-	0,						/* SX_OBJECT -- entry unused dynamically */
-	retrieve_lscalar,		/* SX_LSCALAR */
-	old_retrieve_array,		/* SX_ARRAY -- for pre-0.6 binaries */
-	old_retrieve_hash,		/* SX_HASH -- for pre-0.6 binaries */
-	retrieve_ref,			/* SX_REF */
-	retrieve_undef,			/* SX_UNDEF */
-	retrieve_integer,		/* SX_INTEGER */
-	retrieve_double,		/* SX_DOUBLE */
-	retrieve_byte,			/* SX_BYTE */
-	retrieve_netint,		/* SX_NETINT */
-	retrieve_scalar,		/* SX_SCALAR */
-	retrieve_tied_array,	/* SX_ARRAY */
-	retrieve_tied_hash,		/* SX_HASH */
-	retrieve_tied_scalar,	/* SX_SCALAR */
-	retrieve_other,			/* SX_SV_UNDEF not supported */
-	retrieve_other,			/* SX_SV_YES not supported */
-	retrieve_other,			/* SX_SV_NO not supported */
-	retrieve_other,			/* SX_ERROR */
-};
-
-static SV *(*sv_retrieve[])() = {
-	0,						/* SX_OBJECT -- entry unused dynamically */
-	retrieve_lscalar,		/* SX_LSCALAR */
-	retrieve_array,			/* SX_ARRAY */
-	retrieve_hash,			/* SX_HASH */
-	retrieve_ref,			/* SX_REF */
-	retrieve_undef,			/* SX_UNDEF */
-	retrieve_integer,		/* SX_INTEGER */
-	retrieve_double,		/* SX_DOUBLE */
-	retrieve_byte,			/* SX_BYTE */
-	retrieve_netint,		/* SX_NETINT */
-	retrieve_scalar,		/* SX_SCALAR */
-	retrieve_tied_array,	/* SX_ARRAY */
-	retrieve_tied_hash,		/* SX_HASH */
-	retrieve_tied_scalar,	/* SX_SCALAR */
-	retrieve_sv_undef,		/* SX_SV_UNDEF */
-	retrieve_sv_yes,		/* SX_SV_YES */
-	retrieve_sv_no,			/* SX_SV_NO */
-	retrieve_other,			/* SX_ERROR */
-};
-
-static SV *(**sv_retrieve_vtbl)();	/* One of the above -- XXX for threads */
-
-#define RETRIEVE(x)	(*sv_retrieve_vtbl[(x) >= SX_ERROR ? SX_ERROR : (x)])
+/***
+ *** Retrieval engine.
+ ***/
 
 /*
  * magic_check
@@ -2270,21 +4371,22 @@
  * Note that there's no byte ordering info emitted when network order was
  * used at store time.
  */
-static SV *magic_check(f)
-PerlIO *f;
+static SV *magic_check(stcxt_t *cxt)
 {
-	dPERINTERP;
 	char buf[256];
 	char byteorder[256];
 	int c;
 	int use_network_order;
-	int version;
+	int version_major;
+	int version_minor = 0;
+
+	TRACEME(("magic_check"));
 
 	/*
 	 * The "magic number" is only for files, not when freezing in memory.
 	 */
 
-	if (f) {
+	if (cxt->fio) {
 		STRLEN len = sizeof(magicstr) - 1;
 		STRLEN old_len;
 
@@ -2304,7 +4406,7 @@
 		buf[old_len] = '\0';			/* Is now null-terminated */
 
 		if (strcmp(buf, old_magicstr))
-			croak("File is not a perl storable");
+			CROAK(("File is not a perl storable"));
 	}
 
 magic_ok:
@@ -2315,11 +4417,47 @@
 	 */
 
 	GETMARK(use_network_order);
-	version = use_network_order >> 1;
-	sv_retrieve_vtbl = version ? sv_retrieve : sv_old_retrieve;
-	TRACEME(("binary image version is %d", version));
+	version_major = use_network_order >> 1;
+	cxt->retrieve_vtbl = version_major ? sv_retrieve : sv_old_retrieve;
 
-	if (netorder = (use_network_order & 0x1))
+	TRACEME(("magic_check: netorder = 0x%x", use_network_order));
+
+
+	/*
+	 * Starting with 0.7 (binary major 2), a full byte is dedicated to the
+	 * minor version of the protocol.  See magic_write().
+	 */
+
+	if (version_major > 1)
+		GETMARK(version_minor);
+
+	cxt->ver_major = version_major;
+	cxt->ver_minor = version_minor;
+
+	TRACEME(("binary image version is %d.%d", version_major, version_minor));
+
+	/*
+	 * Inter-operability sanity check: we can't retrieve something stored
+	 * using a format more recent than ours, because we have no way to
+	 * know what has changed, and letting retrieval go would mean a probable
+	 * failure reporting a "corrupted" storable file.
+	 */
+
+	if (
+		version_major > STORABLE_BIN_MAJOR ||
+			(version_major == STORABLE_BIN_MAJOR &&
+			version_minor > STORABLE_BIN_MINOR)
+	)
+		CROAK(("Storable binary image v%d.%d more recent than I am (v%d.%d)",
+			version_major, version_minor,
+			STORABLE_BIN_MAJOR, STORABLE_BIN_MINOR));
+
+	/*
+	 * If they stored using network order, there's no byte ordering
+	 * information to check.
+	 */
+
+	if (cxt->netorder = (use_network_order & 0x1))
 		return &PL_sv_undef;			/* No byte ordering info */
 
 	sprintf(byteorder, "%lx", (unsigned long) BYTEORDER);
@@ -2328,19 +4466,25 @@
 	buf[c] = '\0';						/* Is now */
 
 	if (strcmp(buf, byteorder))
-		croak("Byte order is not compatible");
+		CROAK(("Byte order is not compatible"));
 	
 	GETMARK(c);		/* sizeof(int) */
 	if ((int) c != sizeof(int))
-		croak("Integer size is not compatible");
+		CROAK(("Integer size is not compatible"));
 
 	GETMARK(c);		/* sizeof(long) */
 	if ((int) c != sizeof(long))
-		croak("Long integer size is not compatible");
+		CROAK(("Long integer size is not compatible"));
 
 	GETMARK(c);		/* sizeof(char *) */
 	if ((int) c != sizeof(char *))
-		croak("Pointer integer size is not compatible");
+		CROAK(("Pointer integer size is not compatible"));
+
+	if (version_major >= 2 && version_minor >= 2) {
+		GETMARK(c);		/* sizeof(NV) */
+		if ((int) c != sizeof(NV))
+			CROAK(("Double size is not compatible"));
+	}
 
 	return &PL_sv_undef;	/* OK */
 }
@@ -2352,10 +4496,8 @@
  * root SV (which may be an AV or an HV for what we care).
  * Returns null if there is a problem.
  */
-static SV *retrieve(f)
-PerlIO *f;
+static SV *retrieve(stcxt_t *cxt, char *cname)
 {
-	dPERINTERP;
 	int type;
 	SV **svh;
 	SV *sv;
@@ -2372,9 +4514,9 @@
 	 * no longer supported, hence the final "goto" in the "if" block.
 	 */
 
-	if (hseen) {							/* Retrieving old binary */
+	if (cxt->hseen) {						/* Retrieving old binary */
 		stag_t tag;
-		if (netorder) {
+		if (cxt->netorder) {
 			I32 nettag;
 			READ(&nettag, sizeof(I32));		/* Ordered sequence of I32 */
 			tag = (stag_t) nettag;
@@ -2384,20 +4526,20 @@
 		GETMARK(type);
 		if (type == SX_OBJECT) {
 			I32 tagn;
-			svh = hv_fetch(hseen, (char *) &tag, sizeof(tag), FALSE);
+			svh = hv_fetch(cxt->hseen, (char *) &tag, sizeof(tag), FALSE);
 			if (!svh)
-				croak("Old tag 0x%x should have been mapped already", tag);
+				CROAK(("Old tag 0x%x should have been mapped already", tag));
 			tagn = SvIV(*svh);	/* Mapped tag number computed earlier below */
 
 			/*
 			 * The following code is common with the SX_OBJECT case below.
 			 */
 
-			svh = av_fetch(aseen, tagn, FALSE);
+			svh = av_fetch(cxt->aseen, tagn, FALSE);
 			if (!svh)
-				croak("Object #%d should have been retrieved already", tagn);
+				CROAK(("Object #%d should have been retrieved already", tagn));
 			sv = *svh;
-			TRACEME(("already retrieved at 0x%lx", (unsigned long) sv));
+			TRACEME(("has retrieved #%d at 0x%"UVxf, tagn, PTR2UV(sv)));
 			SvREFCNT_inc(sv);	/* One more reference to this same sv */
 			return sv;			/* The SV pointer where object was retrieved */
 		}
@@ -2410,7 +4552,8 @@
 		 * tag number. See test for SX_OBJECT above to see how this is perused.
 		 */
 
-		if (!hv_store(hseen, (char *) &tag, sizeof(tag), newSViv(tagnum), 0))
+		if (!hv_store(cxt->hseen, (char *) &tag, sizeof(tag),
+				newSViv(cxt->tagnum), 0))
 			return (SV *) 0;
 
 		goto first_time;
@@ -2420,24 +4563,24 @@
 	 * Regular post-0.6 binary format.
 	 */
 
+again:
 	GETMARK(type);
 
 	TRACEME(("retrieve type = %d", type));
 
 	/*
-	 * If the object type is SX_OBJECT, then we're dealing with an object we
-	 * should have already retrieved. Otherwise, we've got a new one....
+	 * Are we dealing with an object we should have already retrieved?
 	 */
 
 	if (type == SX_OBJECT) {
 		I32 tag;
-		READ(&tag, sizeof(I32));
+		READ_I32(tag);
 		tag = ntohl(tag);
-		svh = av_fetch(aseen, tag, FALSE);
+		svh = av_fetch(cxt->aseen, tag, FALSE);
 		if (!svh)
-			croak("Object #%d should have been retrieved already", tag);
+			CROAK(("Object #%d should have been retrieved already", tag));
 		sv = *svh;
-		TRACEME(("already retrieved at 0x%lx", (unsigned long) sv));
+		TRACEME(("had retrieved #%d at 0x%"UVxf, tag, PTR2UV(sv)));
 		SvREFCNT_inc(sv);	/* One more reference to this same sv */
 		return sv;			/* The SV pointer where object was retrieved */
 	}
@@ -2448,48 +4591,45 @@
 	 * Okay, first time through for this one.
 	 */
 
-	sv = RETRIEVE(type)(f);
+	sv = RETRIEVE(cxt, type)(cxt, cname);
 	if (!sv)
 		return (SV *) 0;			/* Failed */
 
 	/*
+	 * Old binary formats (pre-0.7).
+	 *
 	 * Final notifications, ended by SX_STORED may now follow.
 	 * Currently, the only pertinent notification to apply on the
 	 * freshly retrieved object is either:
-	 *    SX_BLESS <char-len> <classname> for short classnames.
-	 *    SX_LG_BLESS <int-len> <classname> for larger one (rare!).
+	 *    SX_CLASS <char-len> <classname> for short classnames.
+	 *    SX_LG_CLASS <int-len> <classname> for larger one (rare!).
 	 * Class name is then read into the key buffer pool used by
 	 * hash table key retrieval.
 	 */
 
-	while ((type = GETCHAR()) != SX_STORED) {
-		I32 len;
-		HV *stash;
-		SV *ref;
-		switch (type) {
-		case SX_BLESS:
-			GETMARK(len);			/* Length coded on a single char */
-			break;
-		case SX_LG_BLESS:			/* Length coded on a regular integer */
-			RLEN(len);
-			break;
-		case EOF:
-		default:
-			return (SV *) 0;		/* Failed */
+	if (cxt->ver_major < 2) {
+		while ((type = GETCHAR()) != SX_STORED) {
+			I32 len;
+			switch (type) {
+			case SX_CLASS:
+				GETMARK(len);			/* Length coded on a single char */
+				break;
+			case SX_LG_CLASS:			/* Length coded on a regular integer */
+				RLEN(len);
+				break;
+			case EOF:
+			default:
+				return (SV *) 0;		/* Failed */
+			}
+			KBUFCHK(len);				/* Grow buffer as necessary */
+			if (len)
+				READ(kbuf, len);
+			kbuf[len] = '\0';			/* Mark string end */
+			BLESS(sv, kbuf);
 		}
-		KBUFCHK(len);				/* Grow buffer as necessary */
-		if (len)
-			READ(kbuf, len);
-		kbuf[len] = '\0';			/* Mark string end */
-		TRACEME(("blessing 0x%lx in %s", (unsigned long) sv, kbuf));
-		stash = gv_stashpv(kbuf, TRUE);
-		ref = newRV_noinc(sv);		/* To please sv_bless() */
-		(void) sv_bless(ref, stash);
-		SvRV(ref) = 0;
-		SvREFCNT_dec(ref);			/* Reclaim temporary reference */
 	}
 
-	TRACEME(("ok (retrieved 0x%lx, refcnt=%d, %s)", (unsigned long) sv,
+	TRACEME(("ok (retrieved 0x%"UVxf", refcnt=%d, %s)", PTR2UV(sv),
 		SvREFCNT(sv) - 1, sv_reftype(sv, FALSE)));
 
 	return sv;	/* Ok */
@@ -2501,65 +4641,175 @@
  * Retrieve data held in file and return the root object.
  * Common routine for pretrieve and mretrieve.
  */
-static SV *do_retrieve(f)
-PerlIO *f;
+static SV *do_retrieve(
+	PerlIO *f,
+	SV *in,
+	int optype)
 {
-	dPERINTERP;
+	dSTCXT;
 	SV *sv;
+	int is_tainted;				/* Is input source tainted? */
+	struct extendable msave;	/* Where potentially valid mbuf is saved */
+
+	TRACEME(("do_retrieve (optype = 0x%x)", optype));
+
+	optype |= ST_RETRIEVE;
+
+	/*
+	 * Sanity assertions for retrieve dispatch tables.
+	 */
+
+	ASSERT(sizeof(sv_old_retrieve) == sizeof(sv_retrieve),
+		("old and new retrieve dispatch table have same size"));
+	ASSERT(sv_old_retrieve[SX_ERROR] == retrieve_other,
+		("SX_ERROR entry correctly initialized in old dispatch table"));
+	ASSERT(sv_retrieve[SX_ERROR] == retrieve_other,
+		("SX_ERROR entry correctly initialized in new dispatch table"));
+
+	/*
+	 * Workaround for CROAK leak: if they enter with a "dirty" context,
+	 * free up memory for them now.
+	 */
+
+	if (cxt->s_dirty)
+		clean_context(cxt);
+
+	/*
+	 * Now that STORABLE_xxx hooks exist, it is possible that they try to
+	 * re-enter retrieve() via the hooks.
+	 */
+
+	if (cxt->entry)
+		cxt = allocate_context(cxt);
+
+	cxt->entry++;
+
+	ASSERT(cxt->entry == 1, ("starting new recursion"));
+	ASSERT(!cxt->s_dirty, ("clean context"));
+
+	/*
+	 * Prepare context.
+	 *
+	 * Data is loaded into the memory buffer when f is NULL, unless `in' is
+	 * also NULL, in which case we're expecting the data to already lie
+	 * in the buffer (dclone case).
+	 */
+
+	KBUFINIT();			 		/* Allocate hash key reading pool once */
+
+	if (!f && in) {
+		StructCopy(&cxt->membuf, &msave, struct extendable);
+		MBUF_LOAD(in);
+	}
 
-	TRACEME(("do_retrieve"));
-	KBUFINIT();			 	/* Allocate hash key reading pool once */
 
 	/*
 	 * Magic number verifications.
+	 *
+	 * This needs to be done before calling init_retrieve_context()
+	 * since the format indication in the file are necessary to conduct
+	 * some of the initializations.
 	 */
 
-	if (!magic_check(f))
-		croak("Magic number checking on perl storable failed");
+	cxt->fio = f;				/* Where I/O are performed */
+
+	if (!magic_check(cxt))
+		CROAK(("Magic number checking on storable %s failed",
+			cxt->fio ? "file" : "string"));
 
-	TRACEME(("data stored in %s format", netorder ? "net order" : "native"));
+	TRACEME(("data stored in %s format",
+		cxt->netorder ? "net order" : "native"));
 
 	/*
-	 * If retrieving an old binary version, the sv_retrieve_vtbl variable is
-	 * set to sv_old_retrieve. We'll need a hash table to keep track of
-	 * the correspondance between the tags and the tag number used by the
-	 * new retrieve routines.
+	 * Check whether input source is tainted, so that we don't wrongly
+	 * taint perfectly good values...
+	 *
+	 * We assume file input is always tainted.  If both `f' and `in' are
+	 * NULL, then we come from dclone, and tainted is already filled in
+	 * the context.  That's a kludge, but the whole dclone() thing is
+	 * already quite a kludge anyway! -- RAM, 15/09/2000.
+	 */
+
+	is_tainted = f ? 1 : (in ? SvTAINTED(in) : cxt->s_tainted);
+	TRACEME(("input source is %s", is_tainted ? "tainted" : "trusted"));
+	init_retrieve_context(cxt, optype, is_tainted);
+
+	ASSERT(is_retrieving(), ("within retrieve operation"));
+
+	sv = retrieve(cxt, 0);		/* Recursively retrieve object, get root SV */
+
+	/*
+	 * Final cleanup.
 	 */
 
-	hseen = (sv_retrieve_vtbl == sv_old_retrieve) ? newHV() : 0;
+	if (!f && in)
+		StructCopy(&msave, &cxt->membuf, struct extendable);
+
+	/*
+	 * The "root" context is never freed.
+	 */
 
-	aseen = newAV();		/* Table where retrieved objects are kept */
-	tagnum = 0;				/* Have to count objects too */
-	sv = retrieve(f);		/* Recursively retrieve object, get root SV */
-	av_undef(aseen);		/* Free retrieved object table */
-	sv_free((SV *) aseen);	/* Free AV */
+	clean_retrieve_context(cxt);
+	if (cxt->prev)				/* This context was stacked */
+		free_context(cxt);		/* It was not the "root" context */
 
-	if (hseen)
-		sv_free((SV *) hseen);	/* Free HV if created above */
+	/*
+	 * Prepare returned value.
+	 */
 
 	if (!sv) {
 		TRACEME(("retrieve ERROR"));
-		return &PL_sv_undef;	/* Something went wrong, return undef */
+		return &PL_sv_undef;		/* Something went wrong, return undef */
 	}
 
-	TRACEME(("retrieve got %s(0x%lx)",
-		sv_reftype(sv, FALSE), (unsigned long) sv));
+	TRACEME(("retrieve got %s(0x%"UVxf")",
+		sv_reftype(sv, FALSE), PTR2UV(sv)));
 
 	/*
-	 * Build a reference to the SV returned by pretrieve even if it is
-	 * already one and not a scalar, for consistency reasons.
-	 *
 	 * Backward compatibility with Storable-0.5 at 9 (which we know we
 	 * are retrieving if hseen is non-null): don't create an extra RV
 	 * for objects since we special-cased it at store time.
+	 *
+	 * Build a reference to the SV returned by pretrieve even if it is
+	 * already one and not a scalar, for consistency reasons.
+	 *
+	 * NB: although context might have been cleaned, the value of `cxt->hseen'
+	 * remains intact, and can be used as a flag.
 	 */
 
-	if (hseen) {
+	if (cxt->hseen) {			/* Was not handling overloading by then */
 		SV *rv;
 		if (sv_type(sv) == svis_REF && (rv = SvRV(sv)) && SvOBJECT(rv))
 			return sv;
 	}
 
+	/*
+	 * If reference is overloaded, restore behaviour.
+	 *
+	 * NB: minor glitch here: normally, overloaded refs are stored specially
+	 * so that we can croak when behaviour cannot be re-installed, and also
+	 * avoid testing for overloading magic at each reference retrieval.
+	 *
+	 * Unfortunately, the root reference is implicitely stored, so we must
+	 * check for possible overloading now.  Furthermore, if we don't restore
+	 * overloading, we cannot croak as if the original ref was, because we
+	 * have no way to determine whether it was an overloaded ref or not in
+	 * the first place.
+	 *
+	 * It's a pity that overloading magic is attached to the rv, and not to
+	 * the underlying sv as blessing is.
+	 */
+
+	if (SvOBJECT(sv)) {
+		HV *stash = (HV *) SvSTASH (sv);
+		SV *rv = newRV_noinc(sv);
+		if (stash && Gv_AMG(stash)) {
+			SvAMAGIC_on(rv);
+			TRACEME(("restored overloading on root reference"));
+		}
+		return rv;
+	}
+
 	return newRV_noinc(sv);
 }
 
@@ -2568,11 +4818,10 @@
  *
  * Retrieve data held in file and return the root object, undef on error.
  */
-SV *pretrieve(f)
-PerlIO *f;
+SV *pretrieve(PerlIO *f)
 {
 	TRACEME(("pretrieve"));
-	return do_retrieve(f);
+	return do_retrieve(f, Nullsv, 0);
 }
 
 /*
@@ -2580,23 +4829,16 @@
  *
  * Retrieve data held in scalar and return the root object, undef on error.
  */
-SV *mretrieve(sv)
-SV *sv;
+SV *mretrieve(SV *sv)
 {
-	dPERINTERP;
-	struct extendable mcommon;			/* Temporary save area for global */
-	SV *rsv;							/* Retrieved SV pointer */
-
 	TRACEME(("mretrieve"));
-	StructCopy(&membuf, &mcommon, struct extendable);
-
-	MBUF_LOAD(sv);
-	rsv = do_retrieve(0);
-
-	StructCopy(&mcommon, &membuf, struct extendable);
-	return rsv;
+	return do_retrieve((PerlIO*) 0, sv, 0);
 }
 
+/***
+ *** Deep cloning
+ ***/
+
 /*
  * dclone
  *
@@ -2606,51 +4848,70 @@
  * there. Not that efficient, but it should be faster than doing it from
  * pure perl anyway.
  */
-SV *dclone(sv)
-SV *sv;
+SV *dclone(SV *sv)
 {
-	dPERINTERP;
+	dSTCXT;
 	int size;
+	stcxt_t *real_context;
+	SV *out;
 
 	TRACEME(("dclone"));
 
-	MBUF_INIT(0);
-	if (!do_store(0, sv, FALSE))		/* Not in network order! */
-		return &PL_sv_undef;			/* Error during store */
+	/*
+	 * Workaround for CROAK leak: if they enter with a "dirty" context,
+	 * free up memory for them now.
+	 */
+
+	if (cxt->s_dirty)
+		clean_context(cxt);
+
+	/*
+	 * do_store() optimizes for dclone by not freeing its context, should
+	 * we need to allocate one because we're deep cloning from a hook.
+	 */
+
+	if (!do_store((PerlIO*) 0, sv, ST_CLONE, FALSE, (SV**) 0))
+		return &PL_sv_undef;				/* Error during store */
+
+	/*
+	 * Because of the above optimization, we have to refresh the context,
+	 * since a new one could have been allocated and stacked by do_store().
+	 */
+
+	{ dSTCXT; real_context = cxt; }		/* Sub-block needed for macro */
+	cxt = real_context;					/* And we need this temporary... */
+
+	/*
+	 * Now, `cxt' may refer to a new context.
+	 */
+
+	ASSERT(!cxt->s_dirty, ("clean context"));
+	ASSERT(!cxt->entry, ("entry will not cause new context allocation"));
 
 	size = MBUF_SIZE();
 	TRACEME(("dclone stored %d bytes", size));
-
 	MBUF_INIT(size);
-	return do_retrieve(0);
-}
 
-/*
- * last_op_in_netorder
- *
- * Returns whether last operation was made using network order.
- *
- * This is typically out-of-band information that might prove useful
- * to people wishing to convert native to network order data when used.
- */
-int last_op_in_netorder()
-{
-	dPERINTERP;
+	/*
+	 * Since we're passing do_retrieve() both a NULL file and sv, we need
+	 * to pre-compute the taintedness of the input by setting cxt->tainted
+	 * to whatever state our own input string was.	-- RAM, 15/09/2000
+	 *
+	 * do_retrieve() will free non-root context.
+	 */
 
-	return netorder;
-}
+	cxt->s_tainted = SvTAINTED(sv);
+	out = do_retrieve((PerlIO*) 0, Nullsv, ST_CLONE);
 
-/*
- * init_perinterp
- *
- * Called once per "thread" (interpreter) to initialize some global context.
- */
-static void init_perinterp() {
-    INIT_PERINTERP;
-    netorder = 0;	/* true if network order used */
-    forgive_me = -1;	/* whether to be forgiving... */
+	TRACEME(("dclone returns 0x%"UVxf, PTR2UV(out)));
+
+	return out;
 }
 
+/***
+ *** Glue with perl.
+ ***/
+
 /*
  * The Perl IO GV object distinguishes between input and output for sockets
  * but not for plain files. To allow Storable to transparently work on
@@ -2706,3 +4967,9 @@
 int
 last_op_in_netorder()
 
+int
+is_storing()
+
+int
+is_retrieving()
+

Modified: trunk/orca/packages/Storable-1.0.11/Storable.pm
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/Storable.pm	(original)
+++ trunk/orca/packages/Storable-1.0.11/Storable.pm	Sat Jul 13 21:27:08 2002
@@ -1,42 +1,46 @@
-;# $Id: Storable.pm,v 0.6.1.9 2000/03/02 22:19:47 ram Exp $
+;# $Id: Storable.pm,v 1.0.1.10 2001/03/15 00:20:25 ram Exp $
 ;#
-;#  Copyright (c) 1995-1998, Raphael Manfredi
+;#  Copyright (c) 1995-2000, Raphael Manfredi
 ;#  
-;#  You may redistribute only under the terms of the Artistic License,
-;#  as specified in the README file that comes with the distribution.
+;#  You may redistribute only under the same terms as Perl 5, as specified
+;#  in the README file that comes with the distribution.
 ;#
 ;# $Log: Storable.pm,v $
-;# Revision 0.6.1.9  2000/03/02 22:19:47  ram
-;# patch9: updated version number
+;# Revision 1.0.1.10  2001/03/15 00:20:25  ram
+;# patch11: updated version number
 ;#
-;# Revision 0.6.1.8  2000/02/10 18:47:11  ram
-;# patch8: documented last_op_in_netorder()
+;# Revision 1.0.1.9  2001/02/17 12:37:32  ram
+;# patch10: forgot to increase version number at previous patch
 ;#
-;# Revision 0.6.1.7  1999/10/20 17:07:31  ram
-;# patch7: forgot to update VERSION
+;# Revision 1.0.1.8  2001/02/17 12:24:37  ram
+;# patch8: fixed incorrect error message
 ;#
-;# Revision 0.6.1.6  1999/10/19 19:21:27  ram
-;# patch6: Added mention of japanese translation
+;# Revision 1.0.1.7  2001/01/03 09:39:02  ram
+;# patch7: added CAN_FLOCK to determine whether we can flock() or not
 ;#
-;# Revision 0.6.1.5  1999/09/14 20:11:22  ram
-;# patch5: updated version number
+;# Revision 1.0.1.6  2000/11/05 17:20:25  ram
+;# patch6: increased version number
 ;#
-;# Revision 0.6.1.4  1999/07/12  12:36:04  ram
-;# patch4: changed my e-mail to pobox, updated version number.
+;# Revision 1.0.1.5  2000/10/26 17:10:18  ram
+;# patch5: documented that store() and retrieve() can return undef
+;# patch5: added paragraph explaining the auto require for thaw hooks
 ;#
-;# Revision 0.6.1.3  1998/07/03  11:32:52  ram
-;# patch3: recent optimizations increased store() throughput
-;# patch3: increased revision number
+;# Revision 1.0.1.4  2000/10/23 18:02:57  ram
+;# patch4: protected calls to flock() for dos platform
+;# patch4: added logcarp emulation if they don't have Log::Agent
 ;#
-;# Revision 0.6.1.2  1998/06/22  08:58:53  ram
-;# patch2: added Jeff Gresham to the list of contributors
-;# patch2: increased revision number
+;# Revision 1.0.1.3  2000/09/29 19:49:01  ram
+;# patch3: updated version number
 ;#
-;# Revision 0.6.1.1  1998/06/12  09:45:09  ram
-;# patch1: increased version number
+;# Revision 1.0.1.2  2000/09/28 21:42:51  ram
+;# patch2: added lock_store lock_nstore lock_retrieve
 ;#
-;# Revision 0.6  1998/06/04  16:08:20  ram
-;# Baseline for first beta release.
+;# Revision 1.0.1.1  2000/09/17 16:46:21  ram
+;# patch1: documented that doubles are stringified by nstore()
+;# patch1: added Salvador Ortiz Garcia in CREDITS section
+;#
+;# Revision 1.0  2000/09/01 19:40:41  ram
+;# Baseline for first official release.
 ;#
 
 require DynaLoader;
@@ -45,18 +49,74 @@
 
 @EXPORT = qw(store retrieve);
 @EXPORT_OK = qw(
-	nstore store_fd nstore_fd retrieve_fd
+	nstore store_fd nstore_fd fd_retrieve
 	freeze nfreeze thaw
 	dclone
+	retrieve_fd
+	lock_store lock_nstore lock_retrieve
 );
 
 use AutoLoader;
-use Carp;
 use vars qw($forgive_me $VERSION);
 
-$VERSION = '0.609';
+$VERSION = '1.011';
 *AUTOLOAD = \&AutoLoader::AUTOLOAD;		# Grrr...
 
+#
+# Use of Log::Agent is optional
+#
+
+eval "use Log::Agent";
+
+unless (defined @Log::Agent::EXPORT) {
+	eval q{
+		sub logcroak {
+			require Carp;
+			Carp::croak(@_);
+		}
+		sub logcarp {
+			require Carp;
+			Carp::carp(@_);
+		}
+	};
+}
+
+#
+# They might miss :flock in Fcntl
+#
+
+BEGIN {
+	require Fcntl;
+	if (exists $Fcntl::EXPORT_TAGS{'flock'}) {
+		Fcntl->import(':flock');
+	} else {
+		eval q{
+			sub LOCK_SH ()	{1}
+			sub LOCK_EX ()	{2}
+		};
+	}
+}
+
+sub logcroak;
+sub logcarp;
+
+sub retrieve_fd { &fd_retrieve }		# Backward compatibility
+
+#
+# Determine whether locking is possible, but only when needed.
+#
+
+my $CAN_FLOCK;
+
+sub CAN_FLOCK {
+	return $CAN_FLOCK if defined $CAN_FLOCK;
+	require Config; import Config;
+	return $CAN_FLOCK =
+		$Config{'d_flock'} ||
+		$Config{'d_fcntl_can_lock'} ||
+		$Config{'d_lockf'};
+}
+
 bootstrap Storable;
 1;
 __END__
@@ -70,7 +130,7 @@
 # removed.
 #
 sub store {
-	return _store(0, @_);
+	return _store(\&pstore, @_, 0);
 }
 
 #
@@ -79,25 +139,55 @@
 # Same as store, but in network order.
 #
 sub nstore {
-	return _store(1, @_);
+	return _store(\&net_pstore, @_, 0);
+}
+
+#
+# lock_store
+#
+# Same as store, but flock the file first (advisory locking).
+#
+sub lock_store {
+	return _store(\&pstore, @_, 1);
+}
+
+#
+# lock_nstore
+#
+# Same as nstore, but flock the file first (advisory locking).
+#
+sub lock_nstore {
+	return _store(\&net_pstore, @_, 1);
 }
 
 # Internal store to file routine
 sub _store {
-	my $netorder = shift;
+	my $xsptr = shift;
 	my $self = shift;
-	my ($file) = @_;
-	croak "Not a reference" unless ref($self);
-	croak "Too many arguments" unless @_ == 1;	# Watch out for @foo in arglist
+	my ($file, $use_locking) = @_;
+	logcroak "not a reference" unless ref($self);
+	logcroak "wrong argument number" unless @_ == 2;	# No @foo in arglist
 	local *FILE;
-	open(FILE, ">$file") || croak "Can't create $file: $!";
+	open(FILE, ">$file") || logcroak "can't create $file: $!";
 	binmode FILE;				# Archaic systems...
+	if ($use_locking) {
+		unless (&CAN_FLOCK) {
+			logcarp "Storable::lock_store: fcntl/flock emulation broken on $^O";
+			return undef;
+		}
+		flock(FILE, LOCK_EX) ||
+			logcroak "can't get exclusive lock on $file: $!";
+		truncate FILE, 0;
+		# Unlocking will happen when FILE is closed
+	}
+	my $da = $@;				# Don't mess if called from exception handler
 	my $ret;
 	# Call C routine nstore or pstore, depending on network order
-	eval { $ret = $netorder ? net_pstore(*FILE, $self) : pstore(*FILE, $self) };
+	eval { $ret = &$xsptr(*FILE, $self) };
 	close(FILE) or $ret = undef;
 	unlink($file) or warn "Can't unlink $file: $!\n" if $@ || !defined $ret;
-	croak $@ if $@ =~ s/\.?\n$/,/;
+	logcroak $@ if $@ =~ s/\.?\n$/,/;
+	$@ = $da;
 	return $ret ? $ret : undef;
 }
 
@@ -108,7 +198,7 @@
 # Returns undef if an I/O error occurred.
 #
 sub store_fd {
-	return _store_fd(0, @_);
+	return _store_fd(\&pstore, @_);
 }
 
 #
@@ -118,22 +208,24 @@
 #
 sub nstore_fd {
 	my ($self, $file) = @_;
-	return _store_fd(1, @_);
+	return _store_fd(\&net_pstore, @_);
 }
 
 # Internal store routine on opened file descriptor
 sub _store_fd {
-	my $netorder = shift;
+	my $xsptr = shift;
 	my $self = shift;
 	my ($file) = @_;
-	croak "Not a reference" unless ref($self);
-	croak "Too many arguments" unless @_ == 1;	# Watch out for @foo in arglist
+	logcroak "not a reference" unless ref($self);
+	logcroak "too many arguments" unless @_ == 1;	# No @foo in arglist
 	my $fd = fileno($file);
-	croak "Not a valid file descriptor" unless defined $fd;
+	logcroak "not a valid file descriptor" unless defined $fd;
+	my $da = $@;				# Don't mess if called from exception handler
 	my $ret;
 	# Call C routine nstore or pstore, depending on network order
-	eval { $ret = $netorder ? net_pstore($file, $self) : pstore($file, $self) };
-	croak $@ if $@ =~ s/\.?\n$/,/;
+	eval { $ret = &$xsptr($file, $self) };
+	logcroak $@ if $@ =~ s/\.?\n$/,/;
+	$@ = $da;
 	return $ret ? $ret : undef;
 }
 
@@ -144,7 +236,7 @@
 # containing the result.
 #
 sub freeze {
-	_freeze(0, @_);
+	_freeze(\&mstore, @_);
 }
 
 #
@@ -153,21 +245,24 @@
 # Same as freeze but in network order.
 #
 sub nfreeze {
-	_freeze(1, @_);
+	_freeze(\&net_mstore, @_);
 }
 
 # Internal freeze routine
 sub _freeze {
-	my $netorder = shift;
+	my $xsptr = shift;
 	my $self = shift;
-	croak "Not a reference" unless ref($self);
-	croak "Too many arguments" unless @_ == 0;	# Watch out for @foo in arglist
+	logcroak "not a reference" unless ref($self);
+	logcroak "too many arguments" unless @_ == 0;	# No @foo in arglist
+	my $da = $@;				# Don't mess if called from exception handler
 	my $ret;
 	# Call C routine mstore or net_mstore, depending on network order
-	eval { $ret = $netorder ? net_mstore($self) : mstore($self) };
-	croak $@ if $@ =~ s/\.?\n$/,/;
+	eval { $ret = &$xsptr($self) };
+	logcroak $@ if $@ =~ s/\.?\n$/,/;
+	$@ = $da;
 	return $ret ? $ret : undef;
 }
+
 #
 # retrieve
 #
@@ -175,29 +270,55 @@
 # object of that tree.
 #
 sub retrieve {
-	my ($file) = @_;
+	_retrieve($_[0], 0);
+}
+
+#
+# lock_retrieve
+#
+# Same as retrieve, but with advisory locking.
+#
+sub lock_retrieve {
+	_retrieve($_[0], 1);
+}
+
+# Internal retrieve routine
+sub _retrieve {
+	my ($file, $use_locking) = @_;
 	local *FILE;
-	open(FILE, "$file") || croak "Can't open $file: $!";
+	open(FILE, $file) || logcroak "can't open $file: $!";
 	binmode FILE;							# Archaic systems...
 	my $self;
+	my $da = $@;							# Could be from exception handler
+	if ($use_locking) {
+		unless (&CAN_FLOCK) {
+			logcarp "Storable::lock_store: fcntl/flock emulation broken on $^O";
+			return undef;
+		}
+		flock(FILE, LOCK_SH) || logcroak "can't get shared lock on $file: $!";
+		# Unlocking will happen when FILE is closed
+	}
 	eval { $self = pretrieve(*FILE) };		# Call C routine
 	close(FILE);
-	croak $@ if $@ =~ s/\.?\n$/,/;
+	logcroak $@ if $@ =~ s/\.?\n$/,/;
+	$@ = $da;
 	return $self;
 }
 
 #
-# retrieve_fd
+# fd_retrieve
 #
 # Same as retrieve, but perform from an already opened file descriptor instead.
 #
-sub retrieve_fd {
+sub fd_retrieve {
 	my ($file) = @_;
 	my $fd = fileno($file);
-	croak "Not a valid file descriptor" unless defined $fd;
+	logcroak "not a valid file descriptor" unless defined $fd;
 	my $self;
+	my $da = $@;							# Could be from exception handler
 	eval { $self = pretrieve($file) };		# Call C routine
-	croak $@ if $@ =~ s/\.?\n$/,/;
+	logcroak $@ if $@ =~ s/\.?\n$/,/;
+	$@ = $da;
 	return $self;
 }
 
@@ -211,8 +332,10 @@
 	my ($frozen) = @_;
 	return undef unless defined $frozen;
 	my $self;
+	my $da = $@;							# Could be from exception handler
 	eval { $self = mretrieve($frozen) };	# Call C routine
-	croak $@ if $@ =~ s/\.?\n$/,/;
+	logcroak $@ if $@ =~ s/\.?\n$/,/;
+	$@ = $da;
 	return $self;
 }
 
@@ -235,8 +358,8 @@
  # Storing to and retrieving from an already opened file
  store_fd \@array, \*STDOUT;
  nstore_fd \%table, \*STDOUT;
- $aryref = retrieve_fd(\*SOCKET);
- $hashref = retrieve_fd(\*SOCKET);
+ $aryref = fd_retrieve(\*SOCKET);
+ $hashref = fd_retrieve(\*SOCKET);
 
  # Serializing to memory
  $serialized = freeze \%table;
@@ -245,6 +368,12 @@
  # Deep (recursive) cloning
  $cloneref = dclone($ref);
 
+ # Advisory locking
+ use Storable qw(lock_store lock_nstore lock_retrieve)
+ lock_store \%table, 'file';
+ lock_nstore \%table, 'file';
+ $hashref = lock_retrieve('file');
+
 =head1 DESCRIPTION
 
 The Storable package brings persistency to your perl data structures
@@ -270,22 +399,24 @@
 
 At the cost of a slight header overhead, you may store to an already
 opened file descriptor using the C<store_fd> routine, and retrieve
-from a file via C<retrieve_fd>. Those names aren't imported by default,
+from a file via C<fd_retrieve>. Those names aren't imported by default,
 so you will have to do that explicitely if you need those routines.
 The file descriptor you supply must be already opened, for read
 if you're going to retrieve and for write if you wish to store.
 
 	store_fd(\%table, *STDOUT) || die "can't store to stdout\n";
-	$hashref = retrieve_fd(*STDIN);
+	$hashref = fd_retrieve(*STDIN);
 
 You can also store data in network order to allow easy sharing across
 multiple platforms, or when storing on a socket known to be remotely
 connected. The routines to call have an initial C<n> prefix for I<network>,
 as in C<nstore> and C<nstore_fd>. At retrieval time, your data will be
 correctly restored so you don't have to know whether you're restoring
-from native or network ordered data.
+from native or network ordered data.  Double values are stored stringified
+to ensure portability as well, at the slight risk of loosing some precision
+in the last decimals.
 
-When using C<retrieve_fd>, objects are retrieved in sequence, one
+When using C<fd_retrieve>, objects are retrieved in sequence, one
 object (i.e. one recursive tree) per associated C<store_fd>.
 
 If you're more from the object-oriented camp, you can inherit from
@@ -310,10 +441,31 @@
 C<nfreeze> instead to get a portable image.
 
 Note that freezing an object structure and immediately thawing it
-actually achieves a deep cloning of that structure. Storable provides
-you with a C<dclone> interface which does not create that intermediary
-scalar but instead freezes the structure in some internal memory space
-and then immediatly thaws it out.
+actually achieves a deep cloning of that structure:
+
+    dclone(.) = thaw(freeze(.))
+
+Storable provides you with a C<dclone> interface which does not create
+that intermediary scalar but instead freezes the structure in some
+internal memory space and then immediatly thaws it out.
+
+=head1 ADVISORY LOCKING
+
+The C<lock_store> and C<lock_nstore> routine are equivalent to C<store>
+and C<nstore>, only they get an exclusive lock on the file before
+writing.  Likewise, C<lock_retrieve> performs as C<retrieve>, but also
+gets a shared lock on the file before reading.
+
+Like with any advisory locking scheme, the protection only works if
+you systematically use C<lock_store> and C<lock_retrieve>.  If one
+side of your application uses C<store> whilst the other uses C<lock_retrieve>,
+you will get no protection at all.
+
+The internal advisory locking is implemented using Perl's flock() routine.
+If your system does not support any form of flock(), or if you share
+your files across NFS, you might wish to use other forms of locking by
+using modules like LockFile::Simple which lock a file using a filesystem
+entry, instead of locking the file descriptor.
 
 =head1 SPEED
 
@@ -321,17 +473,6 @@
 optimization have been made when manipulating perl internals, to
 sacrifice encapsulation for the benefit of a greater speed.
 
-Storage is now slightly slower than retrieval since the former has to
-also store data in a hash table to keep track of which objects
-have been stored already, whilst the latter uses an array instead of
-a hash table.
-
-On my HP 9000/712 machine running HPUX 9.03 and with perl 5.004, I can
-store 0.85 Mbyte/s and I can retrieve at 0.90 Mbytes/s, approximatively
-(CPU + system time).
-This was measured with Benchmark and the I<Magic: The Gathering>
-database from Tom Christiansen (1.6 Mbytes on disk).
-
 =head1 CANONICAL REPRESENTATION
 
 Normally Storable stores elements of hashes in the order they are
@@ -345,12 +486,181 @@
 Canonical order does not imply network order, those are two orthogonal
 settings.
 
+=head1 ERROR REPORTING
+
+Storable uses the "exception" paradigm, in that it does not try to workaround
+failures: if something bad happens, an exception is generated from the
+caller's perspective (see L<Carp> and C<croak()>).  Use eval {} to trap
+those exceptions.
+
+When Storable croaks, it tries to report the error via the C<logcroak()>
+routine from the C<Log::Agent> package, if it is available.
+
+Normal errors are reported by having store() or retrieve() return C<undef>.
+Such errors are usually I/O errors (or truncated stream errors at retrieval).
+
 =head1 WIZARDS ONLY
 
+=head2 Hooks
+
+Any class may define hooks that will be called during the serialization
+and deserialization process on objects that are instances of that class.
+Those hooks can redefine the way serialization is performed (and therefore,
+how the symetrical deserialization should be conducted).
+
+Since we said earlier:
+
+    dclone(.) = thaw(freeze(.))
+
+everything we say about hooks should also hold for deep cloning. However,
+hooks get to know whether the operation is a mere serialization, or a cloning.
+
+Therefore, when serializing hooks are involved,
+
+    dclone(.) <> thaw(freeze(.))
+
+Well, you could keep them in sync, but there's no guarantee it will always
+hold on classes somebody else wrote.  Besides, there is little to gain in
+doing so: a serializing hook could only keep one attribute of an object,
+which is probably not what should happen during a deep cloning of that
+same object.
+
+Here is the hooking interface:
+
+=over
+
+=item C<STORABLE_freeze> I<obj>, I<cloning>
+
+The serializing hook, called on the object during serialization.  It can be
+inherited, or defined in the class itself, like any other method.
+
+Arguments: I<obj> is the object to serialize, I<cloning> is a flag indicating
+whether we're in a dclone() or a regular serialization via store() or freeze().
+
+Returned value: A LIST C<($serialized, $ref1, $ref2, ...)> where $serialized
+is the serialized form to be used, and the optional $ref1, $ref2, etc... are
+extra references that you wish to let the Storable engine serialize.
+
+At deserialization time, you will be given back the same LIST, but all the
+extra references will be pointing into the deserialized structure.
+
+The B<first time> the hook is hit in a serialization flow, you may have it
+return an empty list.  That will signal the Storable engine to further
+discard that hook for this class and to therefore revert to the default
+serialization of the underlying Perl data.  The hook will again be normally
+processed in the next serialization.
+
+Unless you know better, serializing hook should always say:
+
+    sub STORABLE_freeze {
+        my ($self, $cloning) = @_;
+        return if $cloning;         # Regular default serialization
+        ....
+    }
+
+in order to keep reasonable dclone() semantics.
+
+=item C<STORABLE_thaw> I<obj>, I<cloning>, I<serialized>, ...
+
+The deserializing hook called on the object during deserialization.
+But wait. If we're deserializing, there's no object yet... right?
+
+Wrong: the Storable engine creates an empty one for you.  If you know Eiffel,
+you can view C<STORABLE_thaw> as an alternate creation routine.
+
+This means the hook can be inherited like any other method, and that
+I<obj> is your blessed reference for this particular instance.
+
+The other arguments should look familiar if you know C<STORABLE_freeze>:
+I<cloning> is true when we're part of a deep clone operation, I<serialized>
+is the serialized string you returned to the engine in C<STORABLE_freeze>,
+and there may be an optional list of references, in the same order you gave
+them at serialization time, pointing to the deserialized objects (which
+have been processed courtesy of the Storable engine).
+
+When the Storable engine does not find any C<STORABLE_thaw> hook routine,
+it tries to load the class by requiring the package dynamically (using
+the blessed package name), and then re-attempts the lookup.  If at that
+time the hook cannot be located, the engine croaks.  Note that this mechanism
+will fail if you define several classes in the same file, but perlmod(1)
+warned you.
+
+It is up to you to use these information to populate I<obj> the way you want.
+
+Returned value: none.
+
+=back
+
+=head2 Predicates
+
+Predicates are not exportable.  They must be called by explicitely prefixing
+them with the Storable package name.
+
+=over
+
+=item C<Storable::last_op_in_netorder>
+
 The C<Storable::last_op_in_netorder()> predicate will tell you whether
 network order was used in the last store or retrieve operation.  If you
 don't know how to use this, just forget about it.
 
+=item C<Storable::is_storing>
+
+Returns true if within a store operation (via STORABLE_freeze hook).
+
+=item C<Storable::is_retrieving>
+
+Returns true if within a retrieve operation, (via STORABLE_thaw hook).
+
+=back
+
+=head2 Recursion
+
+With hooks comes the ability to recurse back to the Storable engine.  Indeed,
+hooks are regular Perl code, and Storable is convenient when it comes to
+serialize and deserialize things, so why not use it to handle the
+serialization string?
+
+There are a few things you need to know however:
+
+=over
+
+=item *
+
+You can create endless loops if the things you serialize via freeze()
+(for instance) point back to the object we're trying to serialize in the hook.
+
+=item *
+
+Shared references among objects will not stay shared: if we're serializing
+the list of object [A, C] where both object A and C refer to the SAME object
+B, and if there is a serializing hook in A that says freeze(B), then when
+deserializing, we'll get [A', C'] where A' refers to B', but C' refers to D,
+a deep clone of B'.  The topology was not preserved.
+
+=back
+
+That's why C<STORABLE_freeze> lets you provide a list of references
+to serialize.  The engine guarantees that those will be serialized in the
+same context as the other objects, and therefore that shared objects will
+stay shared.
+
+In the above [A, C] example, the C<STORABLE_freeze> hook could return:
+
+	("something", $self->{B})
+
+and the B part would be serialized by the engine.  In C<STORABLE_thaw>, you
+would get back the reference to the B' object, deserialized for you.
+
+Therefore, recursion should normally be avoided, but is nonetheless supported.
+
+=head2 Deep Cloning
+
+There is a new Clone module available on CPAN which implements deep cloning
+natively, i.e. without freezing to memory and thawing the result.  It is
+aimed to replace Storable's dclone() some day.  However, it does not currently
+support Storable hooks to redefine the way deep cloning is performed.
+
 =head1 EXAMPLES
 
 Here are some code samples showing a possible usage of Storable:
@@ -420,10 +730,18 @@
 operations on the same data structures, you will get different
 results.
 
-Due to the aforementionned optimizations, Storable is at the mercy
-of perl's internal redesign or structure changes. If that bothers
-you, you can try convincing Larry that what is used in Storable
-should be documented and consistently kept in future revisions.
+When storing doubles in network order, their value is stored as text.
+However, you should also not expect non-numeric floating-point values
+such as infinity and "not a number" to pass successfully through a
+nstore()/retrieve() pair.
+
+As Storable neither knows nor cares about character sets (although it
+does know that characters may be more than eight bits wide), any difference
+in the interpretation of character codes between a host and a target
+system is your problem.  In particular, if host and target use different
+code points to represent the characters used in the text representation
+of floating-point numbers, you will not be able be able to exchange
+floating-point data, even with nstore().
 
 =head1 CREDITS
 
@@ -431,11 +749,17 @@
 
 	Jarkko Hietaniemi <jhi at iki.fi>
 	Ulrich Pfeifer <pfeifer at charly.informatik.uni-dortmund.de>
-	Benjamin A. Holzman <benjamin.a.holzman at bender.com>
+	Benjamin A. Holzman <bah at ecnvantage.com>
 	Andrew Ford <A.Ford at ford-mason.co.uk>
 	Gisle Aas <gisle at aas.no>
 	Jeff Gresham <gresham_jeffrey at jpmorgan.com>
 	Murray Nesbitt <murray at activestate.com>
+	Marc Lehmann <pcg at opengroup.org>
+	Justin Banks <justinb at wamnet.com>
+	Jarkko Hietaniemi <jhi at iki.fi> (AGAIN, as perl 5.7.0 Pumpkin!)
+	Salvador Ortiz Garcia <sog at msg.com.mx>
+	Dominic Dunlop <domo at computer.org>
+	Erik Haugan <erik at solbors.no>
 
 for their bug reports, suggestions and contributions.
 
@@ -446,7 +770,8 @@
 simply counting the objects instead of tagging them (leading to
 a binary incompatibility for the Storable image starting at version
 0.6--older images are of course still properly understood).
-Murray Nesbitt made Storable thread-safe.
+Murray Nesbitt made Storable thread-safe.  Marc Lehmann added overloading
+and reference to tied items support.
 
 =head1 TRANSLATIONS
 
@@ -458,4 +783,9 @@
 
 Raphael Manfredi F<E<lt>Raphael_Manfredi at pobox.comE<gt>>
 
+=head1 SEE ALSO
+
+Clone(3).
+
 =cut
+

Modified: trunk/orca/packages/Storable-1.0.11/MANIFEST
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/MANIFEST	(original)
+++ trunk/orca/packages/Storable-1.0.11/MANIFEST	Sat Jul 13 21:27:09 2002
@@ -1,15 +1,23 @@
-README                      Read this first
+ChangeLog                   Changes since baseline
 MANIFEST                    This shipping list
 Makefile.PL                 Generic Makefile template
+README                      Read this first
 Storable.pm                 The perl side of Storable
 Storable.xs                 The C side of Storable
-patchlevel.h                Records current patchlevel
+t/blessed.t                 Test blessed objects
 t/canonical.t               Test canonical hash table dumping
+t/compat-0.6.t              Test backward compatibility with 0.6 at 11
 t/dclone.t                  Test deep cloning
 t/dump.pl                   Small utility to dump data structures
+t/forgive.t                 Test forgiveness
+t/forgive.t                 Test if $Storable::forgive_me works
 t/freeze.t                  Test memory store (freeze/thaw) operations
+t/lock.t                    Test advisory locking routines
+t/overload.t                Test overloaded behaviour
+t/recurse.t                 Test recursive calls
 t/retrieve.t                Test retrieve operation
 t/store.t                   Test store operation
-t/forgive.t                 Test if $Storable::forgive_me works
 t/tied.t                    Test serialization of tied SVs.
-ChangeLog                   Changes since baseline
+t/tied_hook.t               Test tied SVs with hooks
+t/tied_items.t              Test ref to items in tied hash/array
+t/utf8.t                    Test UTF8 strings

Modified: trunk/orca/packages/Storable-1.0.11/Makefile.PL
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/Makefile.PL	(original)
+++ trunk/orca/packages/Storable-1.0.11/Makefile.PL	Sat Jul 13 21:27:09 2002
@@ -1,13 +1,16 @@
-# $Id: Makefile.PL,v 0.6 1998/06/04 16:08:18 ram Exp $
+# $Id: Makefile.PL,v 1.0.1.1 2001/01/03 09:38:39 ram Exp $
 #
-#  Copyright (c) 1995-1998, Raphael Manfredi
+#  Copyright (c) 1995-2000, Raphael Manfredi
 #  
-#  You may redistribute only under the terms of the Artistic License,
-#  as specified in the README file that comes with the distribution.
+#  You may redistribute only under the same terms as Perl 5, as specified
+#  in the README file that comes with the distribution.
 #
 # $Log: Makefile.PL,v $
-# Revision 0.6  1998/06/04 16:08:18  ram
-# Baseline for first beta release.
+# Revision 1.0.1.1  2001/01/03 09:38:39  ram
+# patch7: removed spurious 'clean' entry
+#
+# Revision 1.0  2000/09/01 19:40:41  ram
+# Baseline for first official release.
 #
 
 use ExtUtils::MakeMaker;
@@ -16,8 +19,8 @@
 WriteMakefile(
     'NAME'			=> 'Storable',
     'DISTNAME'		=> "Storable",
+	'MAN3PODS'		=> {},
     'VERSION_FROM'	=> 'Storable.pm',
     'dist'			=> { SUFFIX => 'gz', COMPRESS => 'gzip -f' },
-    'clean'			=> {'FILES' => '*%'},
 );
 

Modified: trunk/orca/packages/Storable-1.0.11/ChangeLog
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/ChangeLog	(original)
+++ trunk/orca/packages/Storable-1.0.11/ChangeLog	Sat Jul 13 21:27:10 2002
@@ -1,3 +1,257 @@
+Thu Mar 15 01:22:32 MET 2001   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+	Last version was wrongly compiling with assertions on, due
+	to an edit glitch.  That did not cause any problem (apart from
+	a slight performance loss) excepted on Win* platforms, where the
+	assertion code does not compile.
+
+Sat Feb 17 13:37:37 MET 2001   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+	Version 1.0.10.
+
+	Forgot to increase version number at previous patch (there were
+	two of them, which is why we jump from 1.0.8 to 1.0.10).
+
+Sat Feb 17 13:35:00 MET 2001   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+	Version 1.0.8, binary format 2.4.
+
+	Fixed incorrect error message.
+
+	Now bless objects ASAP at retrieve time, which is meant to fix
+	two bugs:
+
+	* Indirect references to overloaded object were not able to
+	  restore overloading if the object was not blessed yet,
+	  which was possible since blessing occurred only after the
+	  recursive retrieval.
+
+	* Storable hooks asking for serialization of blessed ref could
+	  get un-blessed refs at retrieval time, for the very same
+	  reason.
+
+	The fix implemented here was suggested by Nick Ing-Simmons.
+
+	Added support for blessed ref to tied structures.  This is the
+	cause for the binary format change.
+
+	Added EBCDIC version of the compatibility test with 0.6.11,
+	from Peter Prymmer
+
+	Added tests for the new features, and to make sure the bugs they
+	are meant to fix are indeed fixed.
+
+Wed Jan  3 10:43:18 MET 2001   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+	Removed spurious 'clean' entry in Makefile.PL.
+
+	Added CAN_FLOCK to determine whether we can flock() or not,
+	by inspecting Perl's configuration parameters, as determined
+	by Configure.
+
+	Trace offending package when overloading cannot be restored
+	on a scalar.
+
+	Made context cleanup safer to avoid dup freeing, mostly in the
+	presence of repeated exceptions during store/retrieve (which can
+	cause memory leaks anyway, so it's just additional safety, not a
+	definite fix).
+
+Sun Nov  5 18:23:48 MET 2000   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+	Version 1.0.6.
+
+	Fixed severe "object lost" bug for STORABLE_freeze returns,
+	when refs to lexicals, taken within the hook, were to be
+	serialized by Storable.  Enhanced the t/recurse.t test to
+	stress hook a little more with refs to lexicals.
+
+Thu Oct 26 19:14:38 MEST 2000   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+	Version 1.0.5.
+
+	Documented that store() and retrieve() can return undef.
+	That is, the error reporting is not always made via exceptions,
+	as the paragraph on error reporting was implying.
+
+	Auto requires module of blessed ref when STORABLE_thaw misses.
+	When the Storable engine looks for the STORABLE_thaw hook and
+	does not find it, it now tries to require the package into which
+	the blessed reference is.
+
+	Just check $^O, in t/lock.t: there's no need to pull the whole
+	Config module for that.
+
+Mon Oct 23 20:03:49 MEST 2000   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+	Version 1.0.4.
+
+	Protected calls to flock() for DOS platform: apparently, the
+	flock/fcnlt emulation is reported to be broken on that
+	platform.
+
+	Added logcarp emulation if they don't have Log::Agent, since
+	we now use it to carp when lock_store/lock_retrieve is used
+	on DOS.
+
+Fri Sep 29 21:52:29 MEST 2000   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+	Version 1.0.3.
+
+	Avoid using "tainted" and "dirty" since Perl remaps them via
+	cpp (i.e. #define).  This is deeply harmful when threading
+	is enabled.  This concerned both the context structure and
+	local variable and argument names.  Brrr..., scary!
+
+Thu Sep 28 23:46:39 MEST 2000   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+	Version 1.0.2.
+
+	Fixed spelling in README.
+
+	Added lock_store, lock_nstore, and lock_retrieve (advisory locking)
+	after a proposal from Erik Haugan <erik at solbors.no>.
+
+	Perls before 5.004_04 lack newSVpvn, added remapping in XS.
+
+	Fixed stupid typo in the t/utf8.t test.
+
+Sun Sep 17 18:51:10 MEST 2000   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+	Version 1.0.1, binary format 2.3.
+
+	Documented that doubles are stored stringified by nstore().
+
+	Added Salvador Ortiz Garcia in CREDITS section,  He identified
+	a bug in the store hooks and proposed the right fix: the class
+	id was allocated too soon.  His bug case was also added to
+	the regression test suite.
+
+	Now only taint retrieved data when source was tainted.  A bug
+	discovered by Marc Lehmann.
+
+	Added support for UTF-8 strings, a contribution of Marc Lehmann.
+	This is normally only activated in post-5.6 perls.
+
+Thu Aug 31 23:06:06 MEST 2000   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+	First official release Storable 1.0, for inclusion in perl 5.7.0.
+	The license scheme is now compatible with Perl's.
+
+Thu Aug 24 01:02:02 MEST 2000   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+
+	ANSI-fied most of the code, preparing for Perl core integration.
+	The next version of Storable will be 0.8, and will be integrated
+	into the Perl core (development branch).
+
+	Dispatch tables were moved upfront to relieve some compilers,
+	especially on AIX and Windows platforms.
+
+	Merged 64-bit fixes from perl5-porters.
+
+Mon Aug 14 09:22:04 MEST 2000   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+	Added a refcnt dec in retrieve_tied_key(): sv_magic() increases
+	the refcnt on the mg_ptr as well.
+
+	Removed spurious dependency to Devel::Peek, which was used for
+	testing only in t/tied_items.t.  Thanks to Conrad Heiney
+	<conrad at fringehead.org> for spotting it first.
+
+Sun Aug 13 22:12:59 MEST 2000   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+	Marc Lehmann kindly contributed code to add overloading support
+	and to handle references to tied variables.
+
+	Rewrote leading blurb about compatibility to make it clearer what
+	"backward compatibility" is about: when I say 0.7 is backward
+	compatible with 0.6, it means the revision 0.7 can read files
+	produced by 0.6.
+
+	Mention new Clone(3) extension in SEE ALSO.
+
+	Was wrongly optimizing for "undef" values in hashes by not
+	fully recursing: as a result, tied "undef" values were incorrectly
+	serialized.
+
+Sun Jul 30 12:59:17 MEST 2000   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+	First revision of Storable 0.7.
+
+	The serializing format is new, known as version 2.0.  It is fully
+	backward compatible with 0.6.  Earlier formats are deprecated and
+	have not even been tested: next version will drop pre-0.6 format.
+
+	Changes since 0.6 at 11:
+
+	- Moved interface to the "beta" status.  Some tiny parts are still
+	  subject to change, but nothing important enough to warrant an "alpha"
+	  status any longer.
+
+	- Slightly reduced the size of the Storable image by factorizing
+	  object class names and removing final object storage notification due
+	  to a redesign of the blessed object storing.
+
+	- Classes can now redefine how they wish their instances to be serialized
+	  and/or deep cloned.  Serializing hooks are written in Perl code.
+
+	- The engine is now fully re-entrant.
+
+Sun Apr  2 23:47:50 MEST 2000   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+	Added provision to detect more recent binary formats, since
+	the new upcoming Storable-0.7 will use a different format.
+	In order to prevent attempting the de-serialization of newer
+	formats by older versions, I'm adding this now to the 0.6 series.
+
+	I'm expecting this revision to be the last of the 0.6 series.
+	Unless it does not work with perl 5.6, which I don't use yet,
+	and therefore against which I cannot test.
+
+Wed Mar 29 19:55:21 MEST 2000   Raphael Manfredi <Raphael_Manfredi at pobox.com>
+
+. Description:
+
+	Added note about format incompatibilities with old versions
+	(i.e. pre 0.5 at 9 formats, which cannot be understood as there
+	was no versionning information in the file by then).
+
+	Protect all $@ variables when eval {} used, to avoid corrupting
+	it when store/retrieve is called within an exception handler.
+
+	Mistakenly included "patchlevel.h" instead of <patchlevel.h>,
+	preventing Perl's patchlevel from being included, which is
+	needed starting from 5.6.
+
 Tue May 12 09:15:15 METDST 1998   Raphael Manfredi <Raphael_Manfredi at grenoble.hp.com>
 
 . Description:

Modified: trunk/orca/packages/Storable-1.0.11/README
==============================================================================
--- trunk/orca/packages/Storable-1.0.11/README	(original)
+++ trunk/orca/packages/Storable-1.0.11/README	Sat Jul 13 21:27:10 2002
@@ -1,157 +1,73 @@
-                         Storable 0.6
-               Copyright (c) 1995-1998, Raphael Manfredi
+                         Storable 1.0
+               Copyright (c) 1995-2000, Raphael Manfredi
 
 ------------------------------------------------------------------------
     This program is free software; you can redistribute it and/or modify
-    it under the terms of the Artistic License, a copy of which can be
-    found with perl.
+    it under the same terms as Perl 5 itself.
 
     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
-    Artistic License for more details.
+    Perl 5 License schemes for more details.
 ------------------------------------------------------------------------
 
-       *** This is beta software -- use at your own risks ***
++=======================================================================
+| Storable is distributed as a module, but is also part of the official
+| Perl core distribution.  Maintenance is still done by the Author,
+| whilst the perl5-porters ensure that no change to the Perl internals
+| can break the version of Storable distributed with it.
++=======================================================================
 
 The Storable extension brings persistency to your data.
-This extension is NOT thread-safe and should not be used by threaded perls.
 
-You may recursively store to disk any data structure, no matter
-how complex and circular it is, provided it contains only SCALAR,
-ARRAY, HASH and references to those items, blessed or not.
+You may recursively store to disk any data structure, no matter how
+complex and circular it is, provided it contains only SCALAR, ARRAY,
+HASH (possibly tied) and references (possibly blessed) to those items.
 
 At a later stage, or in another program, you may retrieve data from
 the stored file and recreate the same hiearchy in memory. If you
 had blessed references, the retrieved references are blessed into
 the same package, so you must make sure you have access to the
-same perl class than the one used to create the relevant objects.
+same perl class as the one used to create the relevant objects.
 
-For instance:
+There is also a dclone() routine which performs an optimized mirroring
+of any data structure, preserving its topology.
 
-	use Storable;
-
-	$scalar = 'scalar';
-	$hash{$scalar} = 'value';
-	$ref = \%hash;
-	@array = ('first', undef, $scalar, $ref, \$ref);
-
-	&show(\@array);
-
-	store(\@array, 'store');
-	$root = retrieve('store');
-
-	print '-' x 10, "\n";
-	&show($root) if ref($root) eq 'ARRAY';
-
-	sub show {
-		my ($aref) = @_;
-		foreach $i (@{$aref}) {
-			unless (defined $i) {
-				print "undef\n";
-				next;
-			}
-			print "$i";
-			print " ($$i)" if ref($i) eq 'SCALAR';
-			print "\n";
-		}
-	}
-
-
-when run on my machine produces:
-
-	first
-	undef
-	scalar
-	HASH(0x4001eec0)
-	SCALAR(0x4001ee60)
-	----------
-	first
-	undef
-	scalar
-	HASH(0x40021fd4)
-	SCALAR(0x40017008)
-
-You can see that items are retrieved in memory at some other place,
-but the topology of the retrieved data is the same as the original.
-
-I had first written Storable in Perl, but the results were disappointing,
-because it took almost 20 seconds to store 200K worth of data. By having
-the heart of Storable in C, I can store the same amount of data in about
-0.6 seconds. To retrieve the same data, it takes roughly 1.0 seconds,
-because you have to allocate objects in memory whereas storing merely
-traverses structures.
-
-More accurately, using Benchmark, I get (for a 236802 byte long stored
-file):
-
-	  Machine       Time to store       Time to retrieve
-	                 (cpu + sys)           (cpu + sys)
-	HP 9000/712         0.61 s                1.02 s
-	HP 9000/856         0.33 s                0.39 s
-
-To store/retrieve the "Magic: The Gathering" (MTG) database (1.9 Mb) in
-native format:
-
-	  Machine       Time to store       Time to retrieve
-	                 (cpu + sys)           (cpu + sys)
-	HP 9000/712         1.95 s                2.19 s
-
-That's roughly 1Mb/s for store and 0.86Mb/s for retrieve.
-
-NOTE: The above figures were valid for Storable-0.5 and earlier. No
-similar benchmarking have been made with Storable-0.6 and higher,
-which use a different binary image.
-
-Comparison of Storable-0.5 at 9 and Storable-0.6 at 3 on a version of
-Tom Christiansen's MTG database (1.8 Mb in native 0.5 format, 1.6 Mb
-only in 0.6 format) gives:
-
-    Version    Storable Image   "store"    "nstore"   "retrieve"
-                 Size in Mb     in Kb/s     in Kb/s     in Kb/s
-
-	 0.5 at 9          1.817         801         701         692
-	 0.6 at 3          1.526         880         851         870
-
-Kb/s rates refer to the size of the Storable image. Since the image
-is shorter with version 0.6, we must normalize the results to compare
-relative speed correctly, and therefore measure the overall time it
-takes to store/retrieve the same database. We get:
-
-    Version    Storable Image   "store"    "nstore"   "retrieve"
-                 Size in Mb     in secs     in secs     in secs
-
-	 0.5 at 9          1.817         2.32        2.65        2.69
-	 0.6 at 3          1.526         1.78        1.84        1.80
-
-Notice the important gain at retrieval time, due to the fact that we
-now use an array instead of a hash table to keep track of retrieved
-objects. I have no explaination for the relative speed-up of nstore
-operations other than the fact that less tests for "netorder" are made.
+Objects (blessed references) may also redefine the way storage and
+retrieval is performed, and/or what deep cloning should do on those
+objects.
 
 To compile this extension, run:
 
-	perl Makefile.PL [PERL_SRC=...where you put perl sources...]
-	make
-	make install
+    perl Makefile.PL [PERL_SRC=...where you put perl sources...]
+    make
+    make install
 
 There is an embeded POD manual page in Storable.pm.
 
 Raphael Manfredi <Raphael_Manfredi at pobox.com>
 
-Thanks to:
+------------------------------------------------------------------------
+Thanks to (in chronological order):
 
-	Jarkko Hietaniemi <jhi at iki.fi>
-	Ulrich Pfeifer <pfeifer at charly.informatik.uni-dortmund.de>
-	Benjamin A. Holzman <benjamin.a.holzman at bender.com>
-	Andrew Ford <A.Ford at ford-mason.co.uk>
-	Gisle Aas <gisle at aas.no>
-	Jeff Gresham <gresham_jeffrey at jpmorgan.com>
-	Murray Nesbitt <murray at activestate.com>
-	Albert N. Micheev <Albert.N.Micheev at f80.n5049.z2.fidonet.org>
+    Jarkko Hietaniemi <jhi at iki.fi>
+    Ulrich Pfeifer <pfeifer at charly.informatik.uni-dortmund.de>
+    Benjamin A. Holzman <bah at ecnvantage.com>
+    Andrew Ford <A.Ford at ford-mason.co.uk>
+    Gisle Aas <gisle at aas.no>
+    Jeff Gresham <gresham_jeffrey at jpmorgan.com>
+    Murray Nesbitt <murray at activestate.com>
+    Albert N. Micheev <Albert.N.Micheev at f80.n5049.z2.fidonet.org>
+    Marc Lehmann <pcg at opengroup.org>
+	Justin Banks <justinb at wamnet.com>
+	Jarkko Hietaniemi <jhi at iki.fi> (AGAIN, as perl 5.7.0 Pumpking!)
+	Salvador Ortiz Garcia <sog at msg.com.mx>
+	Dominic Dunlop <domo at computer.org>
+	Erik Haugan <erik at solbors.no>
 
 for their contributions.
 
 There is a Japanese translation of this man page available at
 http://member.nifty.ne.jp/hippo2000/perltips/storable.htm,
 courtesy of Kawai, Takanori <kawai at nippon-rad.co.jp>.
+------------------------------------------------------------------------

Deleted: trunk/orca/packages/Storable-1.0.11/patchlevel.h

Added: trunk/orca/packages/TimeDate-1.10/t/getdate.t
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/t/getdate.t	(original)
+++ trunk/orca/packages/TimeDate-1.10/t/getdate.t	Sat Jul 13 21:27:12 2002
@@ -0,0 +1,181 @@
+#!/usr/local/bin/perl -w
+
+#Thanks to Andreas Koenig for converting all those dates to numbers
+#and adding the folloing acknowledgement into Date/t/getdate.t
+#Thanks to Graham Barr for writing these tests. Slightly adjusted for
+#the C version by Andreas Koenig, 96-06-08.
+   
+use  Date::Parse;
+
+$data = qq!1995-01-24                ;790905600
+1995-06-24                           ;803952000
+92/01/02 12:01			     ;694353660
+92/01/02 12:01 AM		     ;694310460
+92/01/02 12:01 PM		     ;694353660
+1995-01-24  GMT                      ;790905600
+1995-01-24  BST                      ;790902000
+1995-06-24  GMT                      ;803952000
+1995-06-24  BST                      ;803948400
+Wed, 16 Jun 94 07:29:35 CST    	     ;771773375
+Wed, 16 Nov 94 07:29:35 CST 	     ;784992575
+Mon, 21 Nov 94 07:42:23 CST 	     ;785425343
+Mon, 21 Nov 94 04:28:18 CST 	     ;785413698
+Tue, 15 Nov 94 09:15:10 GMT 	     ;784890910
+Wed, 16 Nov 94 09:39:49 GMT 	     ;784978789
+Wed, 16 Nov 94 09:23:17 GMT 	     ;784977797
+Wed, 16 Nov 94 12:39:49 GMT 	     ;784989589
+Wed, 16 Nov 94 14:03:06 GMT 	     ;784994586
+Wed, 16 Nov 94 05:30:51 CST 	     ;784985451
+Thu, 17 Nov 94 03:19:30 CST 	     ;785063970
+1994:11:21T14:05:32+0000 	     ;785426732
+Mon, 21 Nov 94 14:05:32 GMT 	     ;785426732
+Mon, 14 Nov 94 15:08:49 CST 	     ;784847329
+Wed, 16 Nov 94 14:48:06 GMT 	     ;784997286
+Thu, 17 Nov 94 14:22:03 GMT 	     ;785082123
+Wed, 16 Nov 94 14:36:00 GMT 	     ;784996560
+Wed, 16 Nov 94 09:23:17 GMT 	     ;784977797
+Wed, 16 Nov 94 10:01:43 GMT 	     ;784980103
+Wed, 16 Nov 94 15:03:35 GMT 	     ;784998215
+Mon, 21 Nov 94 13:55:19 GMT 	     ;785426119
+Wed, 16 Nov 94 08:46:11 CST 	     ;784997171
+Wed, 9 Nov 1994 09:50:32 -0500 (EST) ;784392632
+Thu, 13 Oct 94 10:13:13 -0700	     ;782068393
+Sat, 19 Nov 1994 16:59:14 +0100      ;785260754
+Thu, 3 Nov 94 14:10:47 EST 	     ;783889847
+Thu, 3 Nov 94 21:51:09 EST 	     ;783917469
+Fri, 4 Nov 94 9:24:52 EST 	     ;783959092
+Wed, 9 Nov 94 09:38:54 EST 	     ;784391934
+Mon, 14 Nov 94 13:20:12 EST 	     ;784837212
+Wed, 16 Nov 94 17:09:13 EST 	     ;785023753
+Tue, 15 Nov 94 12:27:01 PST 	     ;784931221
+Fri, 18 Nov 1994 07:34:05 -0600      ;785165645
+Mon, 21 Nov 94 14:34:28 -0500 	     ;785446468
+Fri, 18 Nov 1994 12:05:47 -0800 (PST);785189147
+Fri, 18 Nov 1994 12:36:26 -0800 (PST);785190986
+Wed, 16 Nov 1994 15:58:58 GMT 	     ;785001538
+Sun, 06 Nov 94 14:27:40 -0500 	     ;784150060
+Mon, 07 Nov 94 08:20:13 -0500 	     ;784214413
+Mon, 07 Nov 94 16:48:42 -0500 	     ;784244922
+Wed, 09 Nov 94 15:46:16 -0500 	     ;784413976
+Sun, 6 Nov 1994 02:38:17 -0800 	     ;784118297
+Tue, 1 Nov 1994 13:53:49 -0500 	     ;783716029
+Tue, 15 Nov 94 08:31:59 +0100 	     ;784884719
+Sun, 6 Nov 1994 11:09:12 -0500 (IST) ;784138152
+Fri, 4 Nov 94 12:52:10 EST 	     ;783971530
+Mon, 31 Oct 1994 14:17:39 -0500 (EST);783631059
+Mon, 14 Nov 94 11:25:00 CST 	     ;784833900
+Mon, 14 Nov 94 13:26:29 CST 	     ;784841189
+Fri, 18 Nov 94 8:42:47 CST 	     ;785169767
+Thu, 17 Nov 94 14:32:01 +0900 	     ;785050321
+Wed, 2 Nov 94 18:16:31 +0100 	     ;783796591
+Fri, 18 Nov 94 10:46:26 +0100 	     ;785151986
+Tue, 8 Nov 1994 22:39:28 +0200 	     ;784327168
+Wed, 16 Nov 1994 10:01:08 -0500 (EST);784998068
+Wed, 2 Nov 1994 16:59:42 -0800 	     ;783824382
+Wed, 9 Nov 94 10:00:23 PST 	     ;784404023
+Fri, 18 Nov 94 17:01:43 PST 	     ;785206903
+Mon, 14 Nov 1994 14:47:46 -0500      ;784842466
+Mon, 21 Nov 1994 04:56:04 -0500 (EST);785411764
+Mon, 21 Nov 1994 11:50:12 -0800      ;785447412
+Sat, 5 Nov 1994 14:04:16 -0600 (CST) ;784065856
+Sat, 05 Nov 94 13:10:13 MST 	     ;784066213
+Wed, 02 Nov 94 10:47:48 -0800 	     ;783802068
+Wed, 02 Nov 94 13:19:15 -0800 	     ;783811155
+Thu, 03 Nov 94 15:27:07 -0800 	     ;783905227
+Fri, 04 Nov 94 09:12:12 -0800 	     ;783969132
+Wed, 9 Nov 1994 10:13:03 +0000 (GMT) ;784375983
+Wed, 9 Nov 1994 15:28:37 +0000 (GMT) ;784394917
+Wed, 2 Nov 1994 17:37:41 +0100 (MET) ;783794261
+05 Nov 94 14:22:19 PST 		     ;784074139
+16 Nov 94 22:28:20 PST 		     ;785053700
+Tue, 1 Nov 1994 19:51:15 -0800 	     ;783748275
+Wed, 2 Nov 94 12:21:23 GMT 	     ;783778883
+Fri, 18 Nov 94 18:07:03 GMT 	     ;785182023
+Wed, 16 Nov 1994 11:26:27 -0500      ;785003187
+Sun, 6 Nov 1994 13:48:49 -0500 	     ;784147729
+Tue, 8 Nov 1994 13:19:37 -0800 	     ;784329577
+Fri, 18 Nov 1994 11:01:12 -0800      ;785185272
+Mon, 21 Nov 1994 00:47:58 -0500      ;785396878
+Mon, 7 Nov 1994 14:22:48 -0800 (PST) ;784246968
+Wed, 16 Nov 1994 15:56:45 -0800 (PST);785030205
+Thu, 3 Nov 1994 13:17:47 +0000 	     ;783868667
+Wed, 9 Nov 1994 17:32:50 -0500 (EST) ;784420370
+Wed, 9 Nov 94 16:31:52 PST	     ;784427512
+Wed, 09 Nov 94 10:41:10 -0800	     ;784406470
+Wed, 9 Nov 94 08:42:22 MST	     ;784395742
+Mon, 14 Nov 1994 08:32:13 -0800	     ;784830733
+Mon, 14 Nov 1994 11:34:32 -0500 (EST);784830872
+Mon, 14 Nov 94 16:48:09 GMT	     ;784831689
+Tue, 15 Nov 1994 10:27:33 +0000      ;784895253
+Wed, 02 Nov 94 13:56:54 MST 	     ;783809814
+Thu, 03 Nov 94 15:24:45 MST 	     ;783901485
+Thu, 3 Nov 1994 15:13:53 -0700 (MST) ;783900833
+Fri, 04 Nov 94 08:15:13 MST 	     ;783962113
+Thu, 3 Nov 94 18:15:47 EST	     ;783904547
+Tue, 08 Nov 94 07:02:33 MST 	     ;784303353
+Thu, 3 Nov 94 18:15:47 EST	     ;783904547
+Tue, 15 Nov 94 07:26:05 MST 	     ;784909565
+Wed, 2 Nov 1994 00:00:55 -0600 (CST) ;783756055
+Sun, 6 Nov 1994 01:19:13 -0600 (CST) ;784106353
+Mon, 7 Nov 1994 23:16:57 -0600 (CST) ;784271817
+Tue, 08 Nov 1994 13:21:21 -0600	     ;784322481
+Mon, 07 Nov 94 13:47:37 PST          ;784244857
+Tue, 08 Nov 94 11:23:19 PST 	     ;784322599
+Tue, 01 Nov 1994 11:28:25 -0800      ;783718105
+Tue, 15 Nov 1994 13:11:47 -0800      ;784933907
+Tue, 15 Nov 1994 13:18:38 -0800      ;784934318
+Tue, 15 Nov 1994 0:18:38 -0800 	     ;784887518
+!;
+
+require Time::Local;
+my $offset = Time::Local::timegm(0,0,0,1,0,70);
+
+ at data = split(/\n/, $data);
+
+print "1..", scalar(@data),"\n";
+$loop = 1;
+
+printf "# offset = %d\n", $offset;
+
+foreach (@data){
+    my($str,$time_expect) = split ';', $_;
+    my $time = Date::Parse::str2time($str);
+
+    if($loop < 6) {
+
+        # The first five tests are parsed in the current time zone
+        # But the check number is in GMT
+
+        my @lt = localtime($time_expect);
+        my @gt = gmtime($time_expect);
+
+        $tzsec = ($gt[1] - $lt[1]) * 60 + ($gt[2] - $lt[2]) * 3600;
+
+        my($lday,$gday) = ($lt[7],$gt[7]);
+        if($lt[5] > $gt[5]) {
+	    $tzsec -= 24 * 3600;
+        }
+        elsif($gt[5] > $lt[5]) {
+	    $tzsec += 24 * 3600;
+        }
+        else {
+	    $tzsec += ($gt[7] - $lt[7]) * (24 * 3600);
+        }
+        $time -= $tzsec;
+    }
+
+    $time_expect += $offset;
+
+    if($time==$time_expect) {
+	print "ok $loop\n";
+    }
+    else {
+        require Date::Format;
+	print "-"x50,"\nFAIL $loop\n";
+        printf "%s\nDiff:    %d\n", $str, $time - $time_expect;
+        printf "Expect: %10d %s",$time_expect,Date::Format::ctime($time_expect);
+        printf "Got:    %10d %s",$time, Date::Format::ctime($time);
+    }
+    $loop++;
+}
+

Added: trunk/orca/packages/TimeDate-1.10/t/date.t
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/t/date.t	(original)
+++ trunk/orca/packages/TimeDate-1.10/t/date.t	Sat Jul 13 21:27:12 2002
@@ -0,0 +1,157 @@
+#!/usr/local/bin/perl -w
+
+use Date::Parse;
+use Date::Format qw(time2str);
+
+$data = qq!1995-01-24
+1995-01-24:09:08:17.1823213
+Wed, 16 Jun 94 07:29:35 CST 
+Wed, 16 Nov 94 07:29:35 CST 
+Mon, 21 Nov 94 07:42:23 CST 
+Mon, 21 Nov 94 04:28:18 CST 
+Tue, 15 Nov 94 09:15:10 GMT 
+Wed, 16 Nov 94 09:39:49 GMT 
+Wed, 16 Nov 94 09:23:17 GMT 
+Wed, 16 Nov 94 12:39:49 GMT 
+Wed, 16 Nov 94 14:03:06 GMT 
+Wed, 16 Nov 94 05:30:51 CST 
+Thu, 17 Nov 94 03:19:30 CST 
+Mon, 21 Nov 94 14:05:32 GMT 
+Mon, 14 Nov 94 15:08:49 CST 
+Wed, 16 Nov 94 14:48:06 GMT 
+Thu, 17 Nov 94 14:22:03 GMT 
+Wed, 16 Nov 94 14:36:00 GMT 
+Wed, 16 Nov 94 09:23:17 GMT 
+Wed, 16 Nov 94 10:01:43 GMT 
+Wed, 16 Nov 94 15:03:35 GMT 
+Mon, 21 Nov 94 13:55:19 GMT 
+Wed, 16 Nov 94 08:46:11 CST 
+21 dec 17:05
+21-dec 17:05
+21/dec 17:05
+21/dec/93 17:05
+dec 21 1994 17:05
+dec 21 94 17:05
+dec 21 94 17:05 GMT
+dec 21 94 17:05 BST
+dec 21 94 00:05 -1700
+dec 21 94 17:05 -1700
+Wed, 9 Nov 1994 09:50:32 -0500 (EST) 
+Thu, 13 Oct 94 10:13:13 -0700
+Sat, 19 Nov 1994 16:59:14 +0100 
+Thu, 3 Nov 94 14:10:47 EST 
+Thu, 3 Nov 94 21:51:09 EST 
+Fri, 4 Nov 94 9:24:52 EST 
+Wed, 9 Nov 94 09:38:54 EST 
+Mon, 14 Nov 94 13:20:12 EST 
+Wed, 16 Nov 94 17:09:13 EST 
+Tue, 15 Nov 94 12:27:01 PST 
+Fri, 18 Nov 1994 07:34:05 -0600 
+Mon, 21 Nov 94 14:34:28 -0500 
+Fri, 18 Nov 1994 12:05:47 -0800 (PST) 
+Fri, 18 Nov 1994 12:36:26 -0800 (PST) 
+Wed, 16 Nov 1994 15:58:58 GMT 
+1999 10:02:18 "GMT"
+Sun, 06 Nov 94 14:27:40 -0500 
+Mon, 07 Nov 94 08:20:13 -0500 
+Mon, 07 Nov 94 16:48:42 -0500 
+Wed, 09 Nov 94 15:46:16 -0500 
+Fri, 4 Nov 94 16:17:40 "PST 
+Wed, 16 Nov 94 12:43:37 "PST 
+Sun, 6 Nov 1994 02:38:17 -0800 
+Tue, 1 Nov 1994 13:53:49 -0500 
+Tue, 15 Nov 94 08:31:59 +0100 
+Sun, 6 Nov 1994 11:09:12 -0500 (IST) 
+Fri, 4 Nov 94 12:52:10 EST 
+Mon, 31 Oct 1994 14:17:39 -0500 (EST) 
+Mon, 14 Nov 94 11:25:00 CST 
+Mon, 14 Nov 94 13:26:29 CST 
+Fri, 18 Nov 94 8:42:47 CST 
+Thu, 17 Nov 94 14:32:01 +0900 
+Wed, 2 Nov 94 18:16:31 +0100 
+Fri, 18 Nov 94 10:46:26 +0100 
+Tue, 8 Nov 1994 22:39:28 +0200 
+Wed, 16 Nov 1994 10:01:08 -0500 (EST) 
+Wed, 2 Nov 1994 16:59:42 -0800 
+Wed, 9 Nov 94 10:00:23 PST 
+Fri, 18 Nov 94 17:01:43 PST 
+Mon, 14 Nov 1994 14:47:46 -0500 
+Mon, 21 Nov 1994 04:56:04 -0500 (EST) 
+Mon, 21 Nov 1994 11:50:12 -0800 
+Sat, 5 Nov 1994 14:04:16 -0600 (CST) 
+Sat, 05 Nov 94 13:10:13 MST 
+Wed, 02 Nov 94 10:47:48 -0800 
+Wed, 02 Nov 94 13:19:15 -0800 
+Thu, 03 Nov 94 15:27:07 -0800 
+Fri, 04 Nov 94 09:12:12 -0800 
+Wed, 9 Nov 1994 10:13:03 +0000 (GMT) 
+Wed, 9 Nov 1994 15:28:37 +0000 (GMT) 
+Wed, 2 Nov 1994 17:37:41 +0100 (MET) 
+05 Nov 94 14:22:19 PST 
+16 Nov 94 22:28:20 PST 
+Tue, 1 Nov 1994 19:51:15 -0800 
+Wed, 2 Nov 94 12:21:23 GMT 
+Fri, 18 Nov 94 18:07:03 GMT 
+Wed, 16 Nov 1994 11:26:27 -0500 
+Sun, 6 Nov 1994 13:48:49 -0500 
+Tue, 8 Nov 1994 13:19:37 -0800 
+Fri, 18 Nov 1994 11:01:12 -0800 
+Mon, 21 Nov 1994 00:47:58 -0500 
+Mon, 7 Nov 1994 14:22:48 -0800 (PST) 
+Wed, 16 Nov 1994 15:56:45 -0800 (PST) 
+Thu, 3 Nov 1994 13:17:47 +0000 
+Wed, 9 Nov 1994 17:32:50 -0500 (EST)
+Wed, 9 Nov 94 16:31:52 PST
+Wed, 09 Nov 94 10:41:10 -0800
+Wed, 9 Nov 94 08:42:22 MST
+Mon, 14 Nov 1994 08:32:13 -0800
+Mon, 14 Nov 1994 11:34:32 -0500 (EST)
+Mon, 14 Nov 94 16:48:09 GMT
+Tue, 15 Nov 1994 10:27:33 +0000 
+Wed, 02 Nov 94 13:56:54 MST 
+Thu, 03 Nov 94 15:24:45 MST 
+Thu, 3 Nov 1994 15:13:53 -0700 (MST)
+Fri, 04 Nov 94 08:15:13 MST 
+Thu, 3 Nov 94 18:15:47 EST
+Tue, 08 Nov 94 07:02:33 MST 
+Thu, 3 Nov 94 18:15:47 EST
+Tue, 15 Nov 94 07:26:05 MST 
+Wed, 2 Nov 1994 00:00:55 -0600 (CST) 
+Sun, 6 Nov 1994 01:19:13 -0600 (CST) 
+Mon, 7 Nov 1994 23:16:57 -0600 (CST) 
+Tue, 08 Nov 1994 13:21:21 -0600 
+Mon, 07 Nov 94 13:47:37 PST 
+Tue, 08 Nov 94 11:23:19 PST 
+Tue, 01 Nov 1994 11:28:25 -0800 
+Tue, 15 Nov 1994 13:11:47 -0800 
+Tue, 15 Nov 1994 13:18:38 -0800 
+Tue, 15 Nov 1994 0:18:38 -0800 
+!;
+
+ at data = split(/\n/, $data);
+
+print "1..", scalar(@data),"\n";
+$loop = 1;
+
+foreach (@data)
+{
+ $time = str2time($_);
+
+ if(defined $time)
+  {
+   $x = time2str("%a %b %e %T %Y %Z",$time,'GMT');
+
+   printf "%-40s\t%s\n", $_,$x,"\n";
+
+   $y = str2time($x);
+
+   print "",($y == $time) ? "ok $loop\n" : "FAIL $loop\n";
+  }
+ else
+  {
+   print "FAIL $loop\n";
+  }
+
+ $loop++;
+}
+

Added: trunk/orca/packages/TimeDate-1.10/t/lang.t
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/t/lang.t	(original)
+++ trunk/orca/packages/TimeDate-1.10/t/lang.t	Sat Jul 13 21:27:13 2002
@@ -0,0 +1,24 @@
+#!/usr/local/bin/perl -w
+
+use  Date::Language;
+
+
+my $time = time;
+my $v;
+
+my @lang = qw(English German Italian);
+
+print "1..", scalar(@lang),"\n";
+
+my $loop = 1;
+my $lang;
+
+foreach $lang (@lang)
+{
+ my $l = Date::Language->new($lang);
+ $v = $l->str2time($l->ctime($time));
+
+ print $v == $time ? "ok $loop\n" : "FAIL $loop\n";
+ $loop++;
+}
+

Added: trunk/orca/packages/TimeDate-1.10/t/format.t
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/t/format.t	(original)
+++ trunk/orca/packages/TimeDate-1.10/t/format.t	Sat Jul 13 21:27:13 2002
@@ -0,0 +1,178 @@
+
+use Date::Format qw(ctime time2str);
+use Date::Language;
+
+print "1..147\n";
+
+my $i = 1;
+
+$pkg = 'Date::Format::Generic';
+
+while(<DATA>) {
+  chomp;
+  if (/^(\d+)/) {
+    $t = $1;
+    next;
+  }
+  elsif (/^(\w+)/) {
+    $pkg = Date::Language->new($1);
+    next;
+  }
+
+  my($fmt,$res) = split(/\t+/,$_);
+  my $str = $pkg->time2str($fmt,$t,'GMT');
+  print "# '$fmt'$res'$str'\nnot " unless $str eq $res;
+  print "ok ",$i++,"\n";
+}
+
+__DATA__
+936709362 # Tue Sep  7 11:22:42 1999 GMT
+%y	99
+%Y	1999
+%%	%
+%a	Tue
+%A	Tuesday
+%b	Sep
+%B	September
+%c	09/07/99 13:02:42
+%C	Tue Sep  7 13:02:42 GMT 1999
+%d	07
+%e	 7
+%D	09/07/99
+%h	Sep
+%H	13
+%I	01
+%j	250
+%k	13
+%l	 1
+%m	09
+%M	02
+%o	 7th
+%p	PM
+%q	3
+%r	01:02:42 PM
+%R	13:02
+%s	936709362
+%S	42
+%T	13:02:42
+%U	36
+%w	2
+%W	36
+%x	09/07/99
+%X	13:02:42
+%y	99
+%Y	1999
+%Z	GMT
+%z	+0000
+%Od	VII
+%Oe	VII
+%OH	XIII
+%OI	I
+%Oj	CCL
+%Ok	XIII
+%Ol	I
+%Om	IX
+%OM	II
+%Oq	III
+%OY	MCMXCIX
+%Oy	XCIX
+German
+%y	99
+%Y	1999
+%%	%
+%a	Die
+%A	Dienstag
+%b	Sep
+%B	September
+%c	09/07/99 13:02:42
+%C	Die Sep  7 13:02:42 GMT 1999
+%d	07
+%e	 7
+%D	09/07/99
+%h	Sep
+%H	13
+%I	01
+%j	250
+%k	13
+%l	 1
+%m	09
+%M	02
+%o	 7.
+%p	PM
+%q	3
+%r	01:02:42 PM
+%R	13:02
+%s	936709362
+%S	42
+%T	13:02:42
+%U	36
+%w	2
+%W	36
+%x	09/07/99
+%X	13:02:42
+%y	99
+%Y	1999
+%Z	GMT
+%z	+0000
+%Od	VII
+%Oe	VII
+%OH	XIII
+%OI	I
+%Oj	CCL
+%Ok	XIII
+%Ol	I
+%Om	IX
+%OM	II
+%Oq	III
+%OY	MCMXCIX
+%Oy	XCIX
+Italian
+%y	99
+%Y	1999
+%%	%
+%a	Mar
+%A	Martedi
+%b	Set
+%B	Settembre
+%c	09/07/99 13:02:42
+%C	Mar Set  7 13:02:42 GMT 1999
+%d	07
+%e	 7
+%D	09/07/99
+%h	Set
+%H	13
+%I	01
+%j	250
+%k	13
+%l	 1
+%m	09
+%M	02
+%o	 7th
+%p	PM
+%q	3
+%r	01:02:42 PM
+%R	13:02
+%s	936709362
+%S	42
+%T	13:02:42
+%U	36
+%w	2
+%W	36
+%x	09/07/99
+%X	13:02:42
+%y	99
+%Y	1999
+%Z	GMT
+%z	+0000
+%Od	VII
+%Oe	VII
+%OH	XIII
+%OI	I
+%Oj	CCL
+%Ok	XIII
+%Ol	I
+%Om	IX
+%OM	II
+%Oq	III
+%OY	MCMXCIX
+%Oy	XCIX

Added: trunk/orca/packages/TimeDate-1.10/lib/Date/Format.pm
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/lib/Date/Format.pm	(original)
+++ trunk/orca/packages/TimeDate-1.10/lib/Date/Format.pm	Sat Jul 13 21:27:14 2002
@@ -0,0 +1,398 @@
+# Date::Format $Id: //depot/TimeDate/lib/Date/Format.pm#4 $
+#
+# Copyright (c) 1995-1999 Graham Barr. All rights reserved. This program is free
+# software; you can redistribute it and/or modify it under the same terms
+# as Perl itself.
+
+package Date::Format;
+
+use     strict;
+use     vars qw(@EXPORT @ISA $VERSION);
+require Exporter;
+
+$VERSION = "2.20";
+ at ISA     = qw(Exporter);
+ at EXPORT  = qw(time2str strftime ctime asctime);
+
+sub time2str ($;$$)
+{
+ Date::Format::Generic->time2str(@_);
+}
+
+sub strftime ($\@;$)
+{
+ Date::Format::Generic->strftime(@_);
+}
+
+sub ctime ($;$)
+{
+ my($t,$tz) = @_;
+ Date::Format::Generic->time2str("%a %b %e %T %Y\n", $t, $tz); 
+}
+
+sub asctime (\@;$)
+{
+ my($t,$tz) = @_;
+ Date::Format::Generic->strftime("%a %b %e %T %Y\n", $t, $tz); 
+}
+
+##
+##
+##
+
+package Date::Format::Generic;
+
+use vars qw($epoch $tzname);
+use Time::Zone;
+use Time::Local;
+
+sub ctime
+{
+ my($me,$t,$tz) = @_;
+ $me->time2str("%a %b %e %T %Y\n", $t, $tz); 
+}
+
+sub asctime
+{
+ my($me,$t,$tz) = @_;
+ $me->strftime("%a %b %e %T %Y\n", $t, $tz); 
+}
+
+sub _subs
+{
+ my $fn;
+ $_[1] =~ s/
+		%(O?[%a-zA-Z])
+	   /
+                ($_[0]->can("format_$1") || sub { $1 })->($_[0]);
+	   /sgeox;
+
+ $_[1];
+}
+
+sub strftime 
+{
+ my($pkg,$fmt,$time);
+
+ ($pkg,$fmt,$time,$tzname) = @_;
+
+ my $me = ref($pkg) ? $pkg : bless [];
+
+ if(defined $tzname)
+  {
+   $tzname = uc $tzname;
+
+   $tzname = sprintf("%+05d",$tzname)
+	unless($tzname =~ /\D/);
+
+   $epoch = timegm(@{$time}->[0..5]);
+
+   @$me = gmtime($epoch + tz_offset($tzname) - tz_offset());
+  }
+ else
+  {
+   @$me = @$time;
+   undef $epoch;
+  }
+
+ _subs($me,$fmt);
+}
+
+sub time2str
+{
+ my($pkg,$fmt,$time);
+
+ ($pkg,$fmt,$time,$tzname) = @_;
+
+ my $me = ref($pkg) ? $pkg : bless [], $pkg;
+
+ $epoch = $time;
+
+ if(defined $tzname)
+  {
+   $tzname = uc $tzname;
+
+   $tzname = sprintf("%+05d",$tzname)
+	unless($tzname =~ /\D/);
+
+   $time += tz_offset($tzname);
+   @$me = gmtime($time);
+  }
+ else
+  {
+   @$me = localtime($time);
+  }
+ _subs($me,$fmt);
+}
+
+my(@DoW, at MoY, at DoWs, at MoYs, at AMPM,%format, at Dsuf);
+
+ at DoW = qw(Sunday Monday Tuesday Wednesday Thursday Friday Saturday);
+
+ at MoY = qw(January February March April May June
+          July August September October November December);
+
+ at DoWs = map { substr($_,0,3) } @DoW;
+ at MoYs = map { substr($_,0,3) } @MoY;
+
+ at AMPM = qw(AM PM);
+
+ at Dsuf = (qw(th st nd rd th th th th th th)) x 3;
+ at Dsuf[11,12,13] = qw(th th th);
+ at Dsuf[30,31] = qw(th st);
+
+%format = ('x' => "%m/%d/%y",
+           'C' => "%a %b %e %T %Z %Y",
+           'X' => "%H:%M:%S",
+          );
+
+my @locale;
+my $locale = "/usr/share/lib/locale/LC_TIME/default";
+local *LOCALE;
+
+if(open(LOCALE,"$locale"))
+ {
+  chop(@locale = <LOCALE>);
+  close(LOCALE);
+
+  @MoYs = @locale[0 .. 11];
+  @MoY  = @locale[12 .. 23];
+  @DoWs = @locale[24 .. 30];
+  @DoW  = @locale[31 .. 37];
+  @format{"X","x","C"} =  @locale[38 .. 40];
+  @AMPM = @locale[41 .. 42];
+ }
+
+sub wkyr {
+    my($wstart, $wday, $yday) = @_;
+    $wday = ($wday + 7 - $wstart) % 7;
+    return int(($yday - $wday + 13) / 7 - 1);
+}
+
+##
+## these 6 formatting routins need to be *copied* into the language
+## specific packages
+##
+
+my @roman = ('',qw(I II III IV V VI VII VIII IX));
+sub roman {
+  my $n = shift;
+
+  $n =~ s/(\d)$//;
+  my $r = $roman[ $1 ];
+
+  if($n =~ s/(\d)$//) {
+    (my $t = $roman[$1]) =~ tr/IVX/XLC/;
+    $r = $t . $r;
+  }
+  if($n =~ s/(\d)$//) {
+    (my $t = $roman[$1]) =~ tr/IVX/CDM/;
+    $r = $t . $r;
+  }
+  if($n =~ s/(\d)$//) {
+    (my $t = $roman[$1]) =~ tr/IVX/M../;
+    $r = $t . $r;
+  }
+  $r;
+}
+
+sub format_a { $DoWs[$_[0]->[6]] }
+sub format_A { $DoW[$_[0]->[6]] }
+sub format_b { $MoYs[$_[0]->[4]] }
+sub format_B { $MoY[$_[0]->[4]] }
+sub format_h { $MoYs[$_[0]->[4]] }
+sub format_p { $_[0]->[2] >= 12 ?  $AMPM[1] : $AMPM[0] }
+
+sub format_d { sprintf("%02d",$_[0]->[3]) }
+sub format_e { sprintf("%2d",$_[0]->[3]) }
+sub format_H { sprintf("%02d",$_[0]->[2]) }
+sub format_I { sprintf("%02d",$_[0]->[2] % 12 || 12)}
+sub format_j { sprintf("%03d",$_[0]->[7] + 1) }
+sub format_k { sprintf("%2d",$_[0]->[2]) }
+sub format_l { sprintf("%2d",$_[0]->[2] % 12 || 12)}
+sub format_m { sprintf("%02d",$_[0]->[4] + 1) }
+sub format_M { sprintf("%02d",$_[0]->[1]) }
+sub format_q { sprintf("%01d",int($_[0]->[4] / 3) + 1) }
+sub format_s { 
+   $epoch = timegm(@{$_[0]}->[0..5])
+	unless defined $epoch;
+   sprintf("%d",$epoch) 
+}
+sub format_S { sprintf("%02d",$_[0]->[0]) }
+sub format_U { wkyr(0, $_[0]->[6], $_[0]->[7]) }
+sub format_w { $_[0]->[6] }
+sub format_W { wkyr(1, $_[0]->[6], $_[0]->[7]) }
+sub format_y { sprintf("%02d",$_[0]->[5] % 100) }
+sub format_Y { sprintf("%04d",$_[0]->[5] + 1900) }
+
+sub format_Z {
+ my $o = tz_local_offset(timelocal(@{$_[0]}[0..5]));
+ defined $tzname ? $tzname : uc tz_name($o, $_[0]->[8]);
+}
+
+sub format_z {
+ my $t = timelocal(@{$_[0]}[0..5]);
+ my $o = defined $tzname ? tz_offset($tzname, $t) : tz_offset(undef,$t);
+ sprintf("%+03d%02d", int($o / 3600), abs(int($o % 3600)));
+}
+
+sub format_c { &format_x . " " . &format_X }
+sub format_D { &format_m . "/" . &format_d . "/" . &format_y  }      
+sub format_r { &format_I . ":" . &format_M . ":" . &format_S . " " . &format_p  }   
+sub format_R { &format_H . ":" . &format_M }
+sub format_T { &format_H . ":" . &format_M . ":" . &format_S }
+sub format_t { "\t" }
+sub format_n { "\n" }
+sub format_o { sprintf("%2d%s",$_[0]->[3],$Dsuf[$_[0]->[3]]) }
+sub format_x { my $f = $format{'x'}; _subs($_[0],$f); }
+sub format_X { my $f = $format{'X'}; _subs($_[0],$f); }
+sub format_C { my $f = $format{'C'}; _subs($_[0],$f); }
+
+sub format_Od { roman(format_d(@_)) }
+sub format_Oe { roman(format_e(@_)) }
+sub format_OH { roman(format_H(@_)) }
+sub format_OI { roman(format_I(@_)) }
+sub format_Oj { roman(format_j(@_)) }
+sub format_Ok { roman(format_k(@_)) }
+sub format_Ol { roman(format_l(@_)) }
+sub format_Om { roman(format_m(@_)) }
+sub format_OM { roman(format_M(@_)) }
+sub format_Oq { roman(format_q(@_)) }
+sub format_Oy { roman(format_y(@_)) }
+sub format_OY { roman(format_Y(@_)) }
+
+1;
+__END__
+
+=head1 NAME
+
+Date::Format - Date formating subroutines
+
+=head1 SYNOPSIS
+
+	use Date::Format;
+	
+	@lt = timelocal(time);
+	
+	print time2str($template, time);
+	print strftime($template, @lt);
+	
+	print time2str($template, time, $zone);
+	print strftime($template, @lt, $zone);
+	
+	print ctime(time);
+	print ascctime(@lt);
+	
+	print ctime(time, $zone);
+	print asctime(@lt, $zone);
+
+=head1 DESCRIPTION
+
+This module provides routines to format dates into ASCII strings. They
+correspond to the C library routines C<strftime> and C<ctime>.
+
+=over 4
+
+=item time2str(TEMPLATE, TIME [, ZONE])
+
+C<time2str> converts C<TIME> into an ASCII string using the conversion
+specification given in C<TEMPLATE>. C<ZONE> if given specifies the zone
+which the output is required to be in, C<ZONE> defaults to your current zone.
+
+
+=item strftime(TEMPLATE, TIME [, ZONE])
+
+C<strftime> is similar to C<time2str> with the exception that the time is
+passed as an array, such as the array returned by C<localtime>.
+
+=item ctime(TIME [, ZONE])
+
+C<ctime> calls C<time2str> with the given arguments using the
+conversion specification C<"%a %b %e %T %Y\n">
+
+=item asctime(TIME [, ZONE])
+
+C<asctime> calls C<time2str> with the given arguments using the
+conversion specification C<"%a %b %e %T %Y\n">
+
+=back
+
+=head1 MULTI-LANGUAGE SUPPORT
+
+Date::Format is capable of formating into several languages, these are
+English, French, German and Italian. Changing the language is done via
+a static method call, for example
+
+	Date::Format->language('German');
+
+will change the language in which all subsequent dates are formatted.
+
+This is only a first pass, I am considering changing this to be
+
+	$lang = Date::Language->new('German');
+	$lang->time2str("%a %b %e %T %Y\n", time);
+
+I am open to suggestions on this.
+
+=head1 CONVERSION SPECIFICATION
+
+Each conversion specification  is  replaced  by  appropriate
+characters   as   described  in  the  following  list.   The
+appropriate  characters  are  determined  by   the   LC_TIME
+category of the program's locale.
+
+	%%	PERCENT
+	%a	day of the week abbr
+	%A	day of the week
+	%b	month abbr
+	%B 	month
+	%c	MM/DD/YY HH:MM:SS
+	%C 	ctime format: Sat Nov 19 21:05:57 1994
+	%d 	numeric day of the month, with leading zeros (eg 01..31)
+	%e 	numeric day of the month, without leading zeros (eg 1..31)
+	%D 	MM/DD/YY
+	%h 	month abbr
+	%H 	hour, 24 hour clock, leading 0's)
+	%I 	hour, 12 hour clock, leading 0's)
+	%j 	day of the year
+	%k 	hour
+	%l 	hour, 12 hour clock
+	%m 	month number, starting with 1
+	%M 	minute, leading 0's
+	%n 	NEWLINE
+	%o	ornate day of month -- "1st", "2nd", "25th", etc.
+	%p 	AM or PM 
+	%q	Quarter number, starting with 1
+	%r 	time format: 09:05:57 PM
+	%R 	time format: 21:05
+	%s	seconds since the Epoch, UCT
+	%S 	seconds, leading 0's
+	%t 	TAB
+	%T 	time format: 21:05:57
+	%U 	week number, Sunday as first day of week
+	%w 	day of the week, numerically, Sunday == 0
+	%W 	week number, Monday as first day of week
+	%x 	date format: 11/19/94
+	%X 	time format: 21:05:57
+	%y	year (2 digits)
+	%Y	year (4 digits)
+	%Z 	timezone in ascii. eg: PST
+	%z	timezone in format -/+0000
+
+C<%d>, C<%e>, C<%H>, C<%I>, C<%j>, C<%k>, C<%l>, C<%m>, C<%M>, C<%q>,
+C<%y> and C<%Y> can be output in Roman numerals by prefixing the letter
+with C<O>, e.g. C<%OY> will output the year as roman numerals.
+
+=head1 AUTHOR
+
+Graham Barr <gbarr at pobox.com>
+
+=head1 COPYRIGHT
+
+Copyright (c) 1995-1999 Graham Barr. All rights reserved. This program is free
+software; you can redistribute it and/or modify it under the same terms
+as Perl itself.
+
+=cut
+
+

Added: trunk/orca/packages/TimeDate-1.10/lib/Date/Language/French.pm
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/lib/Date/Language/French.pm	(original)
+++ trunk/orca/packages/TimeDate-1.10/lib/Date/Language/French.pm	Sat Jul 13 21:27:14 2002
@@ -0,0 +1,38 @@
+##
+## French tables, contributed by Emmanuel Bataille (bem at residents.frmug.org)
+##
+
+package Date::Language::French;
+
+use Date::Language ();
+use vars qw(@ISA @DoW @DoWs @MoY @MoYs @AMPM @Dsuf %MoY %DoW $VERSION);
+ at ISA = qw(Date::Language);
+$VERSION = "1.01";
+
+ at DoW = qw(dimanche lundi mardi mercredi vendredi samedi);
+ at MoY = qw(janvier février mars avril mai juin 
+          juillet août septembre octobre novembre décembre);
+ at DoWs = map { substr($_,0,3) } @DoW;
+ at MoYs = map { substr($_,0,4) } @MoY; # 4 insteed of 3 'cause [juin] [juil]let
+ at AMPM = qw(AM PM);
+
+ at Dsuf = (qw(er e e e e e e e e e)) x 3;
+# Not need..
+# @Dsuf[11,12,13] = qw(th th th);
+# @Dsuf[30,31] = qw(th st);
+
+ at MoY{@MoY}  = (0 .. scalar(@MoY));
+ at MoY{@MoYs} = (0 .. scalar(@MoYs));
+ at DoW{@DoW}  = (0 .. scalar(@DoW));
+ at DoW{@DoWs} = (0 .. scalar(@DoWs));
+
+# Formatting routines
+
+sub format_a { $DoWs[$_[0]->[6]] }
+sub format_A { $DoW[$_[0]->[6]] }
+sub format_b { $MoYs[$_[0]->[4]] }
+sub format_B { $MoY[$_[0]->[4]] }
+sub format_h { $MoYs[$_[0]->[4]] }
+sub format_p { $_[0]->[2] >= 12 ?  $AMPM[1] : $AMPM[0] }
+
+1;

Added: trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Austrian.pm
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Austrian.pm	(original)
+++ trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Austrian.pm	Sat Jul 13 21:27:15 2002
@@ -0,0 +1,35 @@
+##
+## Austrian tables
+##
+
+package Date::Language::Austrian;
+
+use Date::Language ();
+use vars qw(@ISA @DoW @DoWs @MoY @MoYs @AMPM @Dsuf %MoY %DoW $VERSION);
+ at ISA = qw(Date::Language);
+$VERSION = "1.01";
+
+ at MoY  = qw(Jänner Feber März April Mai Juni
+	   Juli August September Oktober November Dezember);
+ at MoYs = qw(Jän Feb Mär Apr Mai Jun Jul Aug Sep Oct Nov Dez);
+ at DoW  = qw(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag);
+ at DoWs = qw(Son Mon Die Mit Don Fre Sam);
+
+ at AMPM = @{Date::Language::English::AMPM};
+ at Dsuf = @{Date::Language::English::Dsuf};
+
+ at MoY{@MoY}  = (0 .. scalar(@MoY));
+ at MoY{@MoYs} = (0 .. scalar(@MoYs));
+ at DoW{@DoW}  = (0 .. scalar(@DoW));
+ at DoW{@DoWs} = (0 .. scalar(@DoWs));
+
+# Formatting routines
+
+sub format_a { $DoWs[$_[0]->[6]] }
+sub format_A { $DoW[$_[0]->[6]] }
+sub format_b { $MoYs[$_[0]->[4]] }
+sub format_B { $MoY[$_[0]->[4]] }
+sub format_h { $MoYs[$_[0]->[4]] }
+sub format_p { $_[0]->[2] >= 12 ?  $AMPM[1] : $AMPM[0] }
+
+1;

Added: trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Dutch.pm
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Dutch.pm	(original)
+++ trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Dutch.pm	Sat Jul 13 21:27:15 2002
@@ -0,0 +1,39 @@
+##
+## Dutch tables
+## Contributed by Johannes la Poutre <jlpoutre at corp.nl.home.com>
+##
+
+package Date::Language::Dutch;
+
+use Date::Language ();
+use vars qw(@ISA @DoW @DoWs @MoY @MoYs @AMPM @Dsuf %MoY %DoW $VERSION);
+ at ISA = qw(Date::Language);
+$VERSION = "1.01";
+
+ at MoY  = qw(januari februari maart april mei juni juli
+           augustus september oktober november december);
+ at MoYs = map(substr($_, 0, 3), @MoY);
+ at DoW  = map($_ . "dag", qw(zon maan dins woens donder vrij zater));
+ at DoWs = map(substr($_, 0, 2), @DoW);
+
+# these aren't normally used...
+ at AMPM = qw(VM NM);
+ at Dsuf = ('e') x 31;
+
+
+ at MoY{@MoY}  = (0 .. scalar(@MoY));
+ at MoY{@MoYs} = (0 .. scalar(@MoYs));
+ at DoW{@DoW}  = (0 .. scalar(@DoW));
+ at DoW{@DoWs} = (0 .. scalar(@DoWs));
+
+# Formatting routines
+
+sub format_a { $DoWs[$_[0]->[6]] }
+sub format_A { $DoW[$_[0]->[6]] }
+sub format_b { $MoYs[$_[0]->[4]] }
+sub format_B { $MoY[$_[0]->[4]] }
+sub format_h { $MoYs[$_[0]->[4]] }
+sub format_p { $_[0]->[2] >= 12 ?  $AMPM[1] : $AMPM[0] }
+sub format_o { sprintf("%2de",$_[0]->[3]) }
+
+1;

Added: trunk/orca/packages/TimeDate-1.10/lib/Date/Language/English.pm
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/lib/Date/Language/English.pm	(original)
+++ trunk/orca/packages/TimeDate-1.10/lib/Date/Language/English.pm	Sat Jul 13 21:27:16 2002
@@ -0,0 +1,37 @@
+##
+## English tables
+##
+
+package Date::Language::English;
+
+use Date::Language ();
+use vars qw(@ISA @DoW @DoWs @MoY @MoYs @AMPM @Dsuf %MoY %DoW $VERSION);
+ at ISA = qw(Date::Language);
+$VERSION = "1.01";
+
+ at DoW = qw(Sunday Monday Tuesday Wednesday Thursday Friday Saturday);
+ at MoY = qw(January February March April May June
+	  July August September October November December);
+ at DoWs = map { substr($_,0,3) } @DoW;
+ at MoYs = map { substr($_,0,3) } @MoY;
+ at AMPM = qw(AM PM);
+
+ at Dsuf = (qw(th st nd rd th th th th th th)) x 3;
+ at Dsuf[11,12,13] = qw(th th th);
+ at Dsuf[30,31] = qw(th st);
+
+ at MoY{@MoY}  = (0 .. scalar(@MoY));
+ at MoY{@MoYs} = (0 .. scalar(@MoYs));
+ at DoW{@DoW}  = (0 .. scalar(@DoW));
+ at DoW{@DoWs} = (0 .. scalar(@DoWs));
+
+# Formatting routines
+
+sub format_a { $DoWs[$_[0]->[6]] }
+sub format_A { $DoW[$_[0]->[6]] }
+sub format_b { $MoYs[$_[0]->[4]] }
+sub format_B { $MoY[$_[0]->[4]] }
+sub format_h { $MoYs[$_[0]->[4]] }
+sub format_p { $_[0]->[2] >= 12 ?  $AMPM[1] : $AMPM[0] }
+
+1;

Added: trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Norwegian.pm
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Norwegian.pm	(original)
+++ trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Norwegian.pm	Sat Jul 13 21:27:16 2002
@@ -0,0 +1,35 @@
+##
+## Norwegian tables
+##
+
+package Date::Language::Norwegian;
+
+use Date::Language ();
+use vars qw(@ISA @DoW @DoWs @MoY @MoYs @AMPM @Dsuf %MoY %DoW $VERSION);
+ at ISA = qw(Date::Language);
+$VERSION = "1.01";
+
+ at MoY  = qw(Januar Februar Mars April Mai Juni
+	   Juli August September Oktober November Desember);
+ at MoYs = qw(Jan Feb Mar Apr Mai Jun Jul Aug Sep Okt Nov Des);
+ at DoW  = qw(Søndag Mandag Tirsdag Onsdag Torsdag Fredag Lørdag Søndag);
+ at DoWs = qw(Søn Man Tir Ons Tor Fre Lør Søn);
+
+ at AMPM =   @{Date::Language::English::AMPM};
+ at Dsuf =   @{Date::Language::English::Dsuf};
+
+ at MoY{@MoY}  = (0 .. scalar(@MoY));
+ at MoY{@MoYs} = (0 .. scalar(@MoYs));
+ at DoW{@DoW}  = (0 .. scalar(@DoW));
+ at DoW{@DoWs} = (0 .. scalar(@DoWs));
+
+# Formatting routines
+
+sub format_a { $DoWs[$_[0]->[6]] }
+sub format_A { $DoW[$_[0]->[6]] }
+sub format_b { $MoYs[$_[0]->[4]] }
+sub format_B { $MoY[$_[0]->[4]] }
+sub format_h { $MoYs[$_[0]->[4]] }
+sub format_p { $_[0]->[2] >= 12 ?  $AMPM[1] : $AMPM[0] }
+
+1;

Added: trunk/orca/packages/TimeDate-1.10/lib/Date/Language/German.pm
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/lib/Date/Language/German.pm	(original)
+++ trunk/orca/packages/TimeDate-1.10/lib/Date/Language/German.pm	Sat Jul 13 21:27:17 2002
@@ -0,0 +1,37 @@
+##
+## German tables
+##
+
+package Date::Language::German;
+
+use Date::Language ();
+use vars qw(@ISA @DoW @DoWs @MoY @MoYs @AMPM @Dsuf %MoY %DoW $VERSION);
+ at ISA = qw(Date::Language);
+$VERSION = "1.01";
+
+ at MoY  = qw(Januar Februar März April Mai Juni
+	   Juli August September Oktober November Dezember);
+ at MoYs = qw(Jan Feb Mär Apr Mai Jun Jul Aug Sep Oct Nov Dez);
+ at DoW  = qw(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag);
+ at DoWs = qw(Son Mon Die Mit Don Fre Sam);
+
+require Date::Language::English;
+ at AMPM =   @{Date::Language::English::AMPM};
+ at Dsuf =   @{Date::Language::English::Dsuf};
+
+ at MoY{@MoY}  = (0 .. scalar(@MoY));
+ at MoY{@MoYs} = (0 .. scalar(@MoYs));
+ at DoW{@DoW}  = (0 .. scalar(@DoW));
+ at DoW{@DoWs} = (0 .. scalar(@DoWs));
+
+# Formatting routines
+
+sub format_a { $DoWs[$_[0]->[6]] }
+sub format_A { $DoW[$_[0]->[6]] }
+sub format_b { $MoYs[$_[0]->[4]] }
+sub format_B { $MoY[$_[0]->[4]] }
+sub format_h { $MoYs[$_[0]->[4]] }
+sub format_p { $_[0]->[2] >= 12 ?  $AMPM[1] : $AMPM[0] }
+sub format_o { sprintf("%2d.",$_[0]->[3]) }
+
+1;

Added: trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Czech.pm
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Czech.pm	(original)
+++ trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Czech.pm	Sat Jul 13 21:27:17 2002
@@ -0,0 +1,58 @@
+##
+## Czech tables
+##
+## Contributed by Honza Pazdziora 
+
+package Date::Language::Czech;
+
+use vars qw(@ISA @DoW @DoWs @MoY @MoYs @MoY2 @AMPM %MoY %DoW $VERSION);
+ at ISA = qw(Date::Language Date::Format::Generic);
+$VERSION = "1.01";
+
+ at MoY = qw(leden únor bøezen duben kvìten èerven èervenec srpen záøí
+	      øíjen listopad prosinec);
+ at MoYs = qw(led únor bøe dub kvì èvn èec srp záøí øíj lis pro);
+ at MoY2 = @MoY;
+for (@MoY2)
+      { s!en$!na! or s!ec$!ce! or s!ad$!adu! or s!or$!ora!; }
+
+ at DoW = qw(nedìle pondìlí úterý støeda ètvrtek pátek sobota);
+ at DoWs = qw(Ne Po Út St Èt Pá So);
+
+ at AMPM = qw(dop. odp.);
+
+ at MoY{@MoY}  = (0 .. scalar(@MoY));
+ at MoY{@MoYs} = (0 .. scalar(@MoYs));
+ at DoW{@DoW}  = (0 .. scalar(@DoW));
+ at DoW{@DoWs} = (0 .. scalar(@DoWs));
+
+# Formatting routines
+
+sub format_a { $DoWs[$_[0]->[6]] }
+sub format_A { $DoW[$_[0]->[6]] }
+sub format_b { $MoYs[$_[0]->[4]] }
+sub format_B { $MoY[$_[0]->[4]] }
+sub format_h { $MoYs[$_[0]->[4]] }
+sub format_p { $_[0]->[2] >= 12 ?  $AMPM[1] : $AMPM[0] }
+
+sub format_d { $_[0]->[3] }
+sub format_m { $_[0]->[4] + 1 }
+sub format_o { $_[0]->[3] . '.' }
+
+sub format_Q { $MoY2[$_[0]->[4]] }
+
+sub time2str {
+      my $ref = shift;
+      my @a = @_;
+      $a[0] =~ s/(%[do]\.?\s?)%B/$1%Q/;
+      $ref->SUPER::time2str(@a);
+      }
+
+sub strftime {
+      my $ref = shift;
+      my @a = @_;
+      $a[0] =~ s/(%[do]\.?\s?)%B/$1%Q/;
+      $ref->SUPER::time2str(@a);
+      }
+
+1;

Added: trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Italian.pm
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Italian.pm	(original)
+++ trunk/orca/packages/TimeDate-1.10/lib/Date/Language/Italian.pm	Sat Jul 13 21:27:18 2002
@@ -0,0 +1,35 @@
+##
+## Italian tables
+##
+
+package Date::Language::Italian;
+
+use Date::Language ();
+use vars qw(@ISA @DoW @DoWs @MoY @MoYs @AMPM @Dsuf %MoY %DoW $VERSION);
+ at ISA = qw(Date::Language);
+$VERSION = "1.01";
+
+ at MoY  = qw(Gennaio Febbraio Marzo Aprile Maggio Giugno
+	   Luglio Agosto Settembre Ottobre Novembre Dicembre);
+ at MoYs = qw(Gen Feb Mar Apr Mag Giu Lug Ago Set Ott Nov Dic);
+ at DoW  = qw(Domenica Lunedi Martedi Mercoledi Giovedi Venerdi Sabato);
+ at DoWs = qw(Dom Lun Mar Mer Gio Ven Sab);
+
+ at AMPM =   @{Date::Language::English::AMPM};
+ at Dsuf =   @{Date::Language::English::Dsuf};
+
+ at MoY{@MoY}  = (0 .. scalar(@MoY));
+ at MoY{@MoYs} = (0 .. scalar(@MoYs));
+ at DoW{@DoW}  = (0 .. scalar(@DoW));
+ at DoW{@DoWs} = (0 .. scalar(@DoWs));
+
+# Formatting routines
+
+sub format_a { $DoWs[$_[0]->[6]] }
+sub format_A { $DoW[$_[0]->[6]] }
+sub format_b { $MoYs[$_[0]->[4]] }
+sub format_B { $MoY[$_[0]->[4]] }
+sub format_h { $MoYs[$_[0]->[4]] }
+sub format_p { $_[0]->[2] >= 12 ?  $AMPM[1] : $AMPM[0] }
+
+1;

Added: trunk/orca/packages/TimeDate-1.10/lib/Date/Parse.pm
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/lib/Date/Parse.pm	(original)
+++ trunk/orca/packages/TimeDate-1.10/lib/Date/Parse.pm	Sat Jul 13 21:27:18 2002
@@ -0,0 +1,370 @@
+# Date::Parse $Id: //depot/TimeDate/lib/Date/Parse.pm#5 $
+#
+# Copyright (c) 1995 Graham Barr. All rights reserved. This program is free
+# software; you can redistribute it and/or modify it under the same terms
+# as Perl itself.
+
+package Date::Parse;
+
+require 5.000;
+use strict;
+use vars qw($VERSION @ISA @EXPORT);
+use Time::Local;
+use Carp;
+use Time::Zone;
+use Exporter;
+
+ at ISA = qw(Exporter);
+ at EXPORT = qw(&strtotime &str2time &strptime);
+
+$VERSION = "2.20";
+
+my %month = (
+	january		=> 0,
+	february	=> 1,
+	march		=> 2,
+	april		=> 3,
+	may		=> 4,
+	june		=> 5,
+	july		=> 6,
+	august		=> 7,
+	september	=> 8,
+	sept		=> 8,
+	october		=> 9,
+	november	=> 10,
+	december	=> 11,
+	);
+
+my %day = (
+	sunday		=> 0,
+	monday		=> 1,
+	tuesday		=> 2,
+	tues		=> 2,
+	wednesday	=> 3,
+	wednes		=> 3,
+	thursday	=> 4,
+	thur		=> 4,
+	thurs		=> 4,
+	friday		=> 5,
+	saturday	=> 6,
+	);
+
+my @suf = (qw(th st nd rd th th th th th th)) x 3;
+ at suf[11,12,13] = qw(th th th);
+
+#Abbreviations
+
+map { $month{substr($_,0,3)} = $month{$_} } keys %month;
+map { $day{substr($_,0,3)}   = $day{$_} }   keys %day;
+
+my $strptime = <<'ESQ';
+ my %month = map { lc $_ } %$mon_ref;
+ my $daypat = join("|", map { lc $_ } reverse sort keys %$day_ref);
+ my $monpat = join("|", reverse sort keys %month);
+ my $sufpat = join("|", reverse sort map { lc $_ } @$suf_ref);
+
+ my %ampm = (
+	am => 0,
+	pm => 12
+	);
+
+ # allow map am +. a.m.
+ map { my($z) = $_; $z =~ s#(\w)#$1\.#g; $ampm{$z} = $ampm{$_} } keys %ampm;
+
+ my($AM, $PM) = (0,12);
+
+sub {
+
+  my $dtstr = lc shift;
+  my $merid = 24;
+
+  my($year,$month,$day,$hh,$mm,$ss,$zone,$dst);
+
+  $zone = tz_offset(shift) if @_;
+
+  1 while $dtstr =~ s#\([^\(\)]*\)# #o;
+
+  $dtstr =~ s#(\A|\n|\Z)# #sog;
+
+  # ignore day names
+  $dtstr =~ s#([\d\w\s])[\.\,]\s#$1 #sog;
+  $dtstr =~ s#($daypat)\s*(den\s)?# #o;
+  # Time: 12:00 or 12:00:00 with optional am/pm
+  
+  if ($dtstr =~ s/(\d{4})([-:]?)(\d\d)\2(\d\d)[Tt](\d\d)([-:]?)(\d\d)\6(\d\d)/ /) {
+    ($year,$month,$day,$hh,$mm,$ss) = ($1,$3-1,$4,$5,$7,$8);
+  }
+  else {
+
+    if ($dtstr =~ s#[:\s](\d\d?):(\d\d?)(:(\d\d?)(?:\.\d+)?)?\s*([ap]\.?m\.?)?\s# #o) {
+      ($hh,$mm,$ss) = ($1,$2,$4 || 0);
+      $merid = $ampm{$5} if $5;
+    }
+
+    # Time: 12 am
+    
+    elsif ($dtstr =~ s#\s(\d\d?)\s*([ap]\.?m\.?)\s# #o) {
+      ($hh,$mm,$ss) = ($1,0,0);
+      $merid = $ampm{$2};
+    }
+    
+    # Date: 12-June-96 (using - . or /)
+    
+    if ($dtstr =~ s#\s(\d\d?)([\-\./])($monpat)(\2(\d\d+))?\s# #o) {
+      ($month,$day) = ($month{$3},$1);
+      $year = $5 if $5;
+    }
+    
+    # Date: 12-12-96 (using '-', '.' or '/' )
+    
+    elsif ($dtstr =~ s#\s(\d\d*)([\-\./])(\d\d?)(\2(\d\d+))?\s# #o) {
+      ($month,$day) = ($1 - 1,$3);
+
+      if ($5) {
+	$year = $5;
+	# Possible match for 1995-01-24 (short mainframe date format);
+	($year,$month,$day) = ($1, $3 - 1, $5) if $month > 12;
+      }
+    }
+    elsif ($dtstr =~ s#\s(\d+)\s*($sufpat)?\s*($monpat)# #o) {
+      ($month,$day) = ($month{$3},$1);
+    }
+    elsif ($dtstr =~ s#($monpat)\s*(\d+)\s*($sufpat)?\s# #o) {
+      ($month,$day) = ($month{$1},$2);
+    }
+
+    # Date: 961212
+
+    elsif ($dtstr =~ s#\s(\d\d)(\d\d)(\d\d)\s# #o) {
+      ($year,$month,$day) = ($1,$2-1,$3);
+    }
+
+    $year = $1 if !defined($year) and $dtstr =~ s#\s(\d{2}(\d{2})?)[\s\.,]# #o;
+
+  }
+
+  # Zone
+
+  $dst = 1 if $dtstr =~ s#\bdst\b##o;
+
+  if ($dtstr =~ s#\s"?([a-z]{3,4})(dst|\d+[a-z]*|_[a-z]+)?"?\s# #o) {
+    $dst = 1 if $2 and $2 eq 'dst';
+    $zone = tz_offset($1);
+    return unless defined $zone;
+  }
+  elsif ($dtstr =~ s#\s([a-z]{3,4})?([\-\+]?)-?(\d\d?)(\d\d)?(00)?\s# #o) {
+    my $m = defined($4) ? "$2$4" : 0;
+    my $h = "$2$3";
+    $zone = defined($1) ? tz_offset($1) : 0;
+    return unless defined $zone;
+    $zone += 60 * ($m + (60 * $h));
+  }
+
+  if ($dtstr =~ /\S/) {
+    # now for some dumb dates
+    if ($dtstr =~ s/^\s*(ut?|z)\s*$//) {
+      $zone = 0;
+    }
+    elsif ($dtstr =~ s#\s([a-z]{3,4})?([\-\+]?)-?(\d\d?)(\d\d)?(00)?\s# #o) {
+      my $m = defined($4) ? "$2$4" : 0;
+      my $h = "$2$3";
+      $zone = defined($1) ? tz_offset($1) : 0;
+      return unless defined $zone;
+      $zone += 60 * ($m + (60 * $h));
+    }
+
+    return if $dtstr =~ /\S/o;
+  }
+
+  if (defined $hh) {
+    if ($hh == 12) {
+      $hh = 0 if $merid == $AM;
+    }
+    elsif ($merid == $PM) {
+      $hh += 12;
+    }
+  }
+
+  $year -= 1900 if defined $year && $year > 1900;
+
+  $zone += 3600 if defined $zone && $dst;
+
+  return ($ss,$mm,$hh,$day,$month,$year,$zone);
+}
+ESQ
+
+use vars qw($day_ref $mon_ref $suf_ref $obj);
+
+sub gen_parser
+{
+ local($day_ref,$mon_ref,$suf_ref,$obj) = @_;
+
+ if($obj)
+  {
+   my $obj_strptime = $strptime;
+   substr($obj_strptime,index($strptime,"sub")+6,0) = <<'ESQ';
+ shift; # package
+ESQ
+   return eval "$obj_strptime";
+  }
+
+ eval "$strptime";
+
+}
+
+*strptime = gen_parser(\%day,\%month,\@suf);
+
+sub str2time
+{
+ my @t = strptime(@_);
+
+ return undef
+	unless @t;
+
+ my($ss,$mm,$hh,$day,$month,$year,$zone) = @t;
+ my @lt  = localtime(time);
+
+ $hh    ||= 0;
+ $mm    ||= 0;
+ $ss    ||= 0;
+
+ $month = $lt[4]
+	unless(defined $month);
+
+ $day  = $lt[3]
+	unless(defined $day);
+
+ $year = ($month > $lt[4]) ? ($lt[5] - 1) : $lt[5]
+	unless(defined $year);
+
+ return undef
+	unless($month <= 11 && $day >= 1 && $day <= 31
+		&& $hh <= 23 && $mm <= 59 && $ss <= 59);
+
+ my $result;
+
+ if (defined $zone) {
+   $result = eval {
+     local $SIG{__DIE__} = sub {}; # Ick!
+     timegm($ss,$mm,$hh,$day,$month,$year);
+   };
+   return undef
+     if !defined $result
+        or $result == -1
+           && join("",$ss,$mm,$hh,$day,$month,$year)
+     	        ne "595923311169";
+   $result -= $zone;
+ }
+ else {
+   $result = eval {
+     local $SIG{__DIE__} = sub {}; # Ick!
+     timelocal($ss,$mm,$hh,$day,$month,$year);
+   };
+   return undef
+     if !defined $result
+        or $result == -1
+           && join("",$ss,$mm,$hh,$day,$month,$year)
+     	        ne join("",(localtime(-1))[0..5]);
+ }
+
+ return $result;
+}
+
+1;
+
+__END__
+
+
+=head1 NAME
+
+Date::Parse - Parse date strings into time values
+
+=head1 SYNOPSIS
+
+	use Date::Parse;
+	
+	$time = str2time($date);
+	
+	($ss,$mm,$hh,$day,$month,$year,$zone) = strptime($date);
+
+=head1 DESCRIPTION
+
+C<Date::Parse> provides two routines for parsing date strings into time values.
+
+=over 4
+
+=item str2time(DATE [, ZONE])
+
+C<str2time> parses C<DATE> and returns a unix time value, or undef upon failure.
+C<ZONE>, if given, specifies the timezone to assume when parsing if the
+date string does not specify a timezome.
+
+=item strptime(DATE [, ZONE])
+
+C<strptime> takes the same arguments as str2time but returns an array of
+values C<($ss,$mm,$hh,$day,$month,$year,$zone)>. Elements are only defined
+if they could be extracted from the date string. The C<$zone> element is
+the timezone offset in seconds from GMT. An empty array is returned upon
+failure.
+
+=head1 MULTI-LANGUAGE SUPPORT
+
+Date::Parse is capable of parsing dates in several languages, these are
+English, French, German and Italian. Changing the language is done via
+a static method call, for example
+
+	Date::Parse->language('German');
+
+will cause Date::Parse to attempt to parse any subsequent dates in German.
+
+This is only a first pass, I am considering changing this to be
+
+	$lang = Date::Language->new('German');
+	$lang->str2time("25 Jun 1996 21:09:55 +0100");
+
+I am open to suggestions on this.
+
+=head1 EXAMPLE DATES
+
+Below is a sample list of dates that are known to be parsable with Date::Parse
+
+ 1995:01:24:09:08:17.1823213           ISO-8601
+ 1995-01-24:09:08:17.1823213
+ Wed, 16 Jun 94 07:29:35 CST           Comma and day name are optional 
+ Thu, 13 Oct 94 10:13:13 -0700
+ Wed, 9 Nov 1994 09:50:32 -0500 (EST)  Text in ()'s will be ignored.
+ 21 dec 17:05                          Will be parsed in the current time zone
+ 21-dec 17:05
+ 21/dec 17:05
+ 21/dec/93 17:05
+ 1999 10:02:18 "GMT"
+ 16 Nov 94 22:28:20 PST 
+
+=head1 BUGS
+
+When both the month and the date are specified in the date as numbers
+they are always parsed assuming that the month number comes before the
+date. This is the usual format used in American dates.
+
+The reason why it is like this and not dynamic is that it must be
+deterministic. Several people have suggested using the current locale,
+but this will not work as the date being parsed may not be in the format
+of the current locale.
+
+My plans to address this, which will be in a future release, is to allow
+the programmer to state what order they want these values parsed in.
+
+=head1 AUTHOR
+
+Graham Barr <gbarr at pobox.com>
+
+=head1 COPYRIGHT
+
+Copyright (c) 1995 Graham Barr. All rights reserved. This program is free
+software; you can redistribute it and/or modify it under the same terms
+as Perl itself.
+
+=cut
+
+# $Id: //depot/TimeDate/lib/Date/Parse.pm#5 $
+

Added: trunk/orca/packages/TimeDate-1.10/lib/Date/Language.pm
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/lib/Date/Language.pm	(original)
+++ trunk/orca/packages/TimeDate-1.10/lib/Date/Language.pm	Sat Jul 13 21:27:19 2002
@@ -0,0 +1,83 @@
+
+package Date::Language;
+
+use     strict;
+use     Time::Local;
+use     Carp;
+use     vars qw($VERSION @ISA);
+require Date::Format;
+
+$VERSION = "1.10";
+ at ISA     = qw(Date::Format::Generic);
+
+sub new
+{
+ my $self = shift;
+ my $type = shift || $self;
+
+ $type =~ s/^(\w+)$/Date::Language::$1/;
+
+ croak "Bad language"
+	unless $type =~ /^[\w:]+$/;
+
+ eval "require $type"
+	or croak $@;
+
+ bless [], $type;
+}
+
+# Stop AUTOLOAD being called ;-)
+sub DESTROY {}
+
+sub AUTOLOAD
+{
+ use vars qw($AUTOLOAD);
+
+ if($AUTOLOAD =~ /::strptime\Z/o)
+  {
+   my $self = $_[0];
+   my $type = ref($self) || $self;
+   require Date::Parse;
+
+   no strict 'refs';
+   *{"${type}::strptime"} = Date::Parse::gen_parser(
+	\%{"${type}::DoW"},
+	\%{"${type}::MoY"},
+	\@{"${type}::Dsuf"},
+	1);
+
+   goto &{"${type}::strptime"};
+  }
+
+ croak "Undefined method &$AUTOLOAD called";
+}
+
+sub str2time
+{
+ my $me = shift;
+ my @t = $me->strptime(@_);
+
+ return undef
+	unless @t;
+
+ my($ss,$mm,$hh,$day,$month,$year,$zone) = @t;
+ my @lt  = localtime(time);
+
+ $hh    ||= 0;
+ $mm    ||= 0;
+ $ss    ||= 0;
+
+ $month = $lt[4]
+	unless(defined $month);
+
+ $day  = $lt[3]
+	unless(defined $day);
+
+ $year = ($month > $lt[4]) ? ($lt[5] - 1) : $lt[5]
+	unless(defined $year);
+
+ return defined $zone ? timegm($ss,$mm,$hh,$day,$month,$year) - $zone
+    	    	      : timelocal($ss,$mm,$hh,$day,$month,$year);
+}
+
+1;

Added: trunk/orca/packages/TimeDate-1.10/lib/Time/Zone.pm
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/lib/Time/Zone.pm	(original)
+++ trunk/orca/packages/TimeDate-1.10/lib/Time/Zone.pm	Sat Jul 13 21:27:19 2002
@@ -0,0 +1,277 @@
+
+package Time::Zone;
+
+=head1 NAME
+
+Time::Zone -- miscellaneous timezone manipulations routines
+
+=head1 SYNOPSIS
+
+	use Time::Zone;
+	print tz2zone();
+	print tz2zone($ENV{'TZ'});
+	print tz2zone($ENV{'TZ'}, time());
+	print tz2zone($ENV{'TZ'}, undef, $isdst);
+	$offset = tz_local_offset();
+	$offset = tz_offset($TZ);
+
+=head1 DESCRIPTION
+
+This is a collection of miscellaneous timezone manipulation routines.
+
+C<tz2zone()> parses the TZ environment variable and returns a timezone
+string suitable for inclusion in L<date>-like output.  It opionally takes
+a timezone string, a time, and a is-dst flag.
+
+C<tz_local_offset()> determins the offset from GMT time in seconds.  It
+only does the calculation once.
+
+C<tz_offset()> determines the offset from GMT in seconds of a specified
+timezone.  
+
+C<tz_name()> determines the name of the timezone based on its offset
+
+=head1 AUTHORS
+
+Graham Barr <gbarr at pobox.com>
+David Muir Sharnoff <muir at idiom.com>
+Paul Foley <paul at ascent.com>
+
+=cut
+
+require 5.002;
+
+require Exporter;
+use Carp;
+use strict;
+use vars qw(@ISA @EXPORT $VERSION @tz_local);
+
+ at ISA = qw(Exporter);
+ at EXPORT = qw(tz2zone tz_local_offset tz_offset tz_name);
+$VERSION = "2.20";
+
+# Parts stolen from code by Paul Foley <paul at ascent.com>
+
+sub tz2zone (;$$$)
+{
+	my($TZ, $time, $isdst) = @_;
+
+	use vars qw(%tzn_cache);
+
+	$TZ = defined($ENV{'TZ'}) ? ( $ENV{'TZ'} ? $ENV{'TZ'} : 'GMT' ) : ''
+	    unless $TZ;
+
+	# Hack to deal with 'PST8PDT' format of TZ
+	# Note that this can't deal with all the esoteric forms, but it
+	# does recognize the most common: [:]STDoff[DST[off][,rule]]
+
+	if (! defined $isdst) {
+		my $j;
+		$time = time() unless $time;
+		($j, $j, $j, $j, $j, $j, $j, $j, $isdst) = localtime($time);
+	}
+
+	if (defined $tzn_cache{$TZ}->[$isdst]) {
+		return $tzn_cache{$TZ}->[$isdst];
+	}
+      
+	if ($TZ =~ /^
+		    ( [^:\d+\-,] {3,} )
+		    ( [+-] ?
+		      \d {1,2}
+		      ( : \d {1,2} ) {0,2} 
+		    )
+		    ( [^\d+\-,] {3,} )?
+		    /x
+	    ) {
+		$TZ = $isdst ? $4 : $1;
+		$tzn_cache{$TZ} = [ $1, $4 ];
+	} else {
+		$tzn_cache{$TZ} = [ $TZ, $TZ ];
+	}
+	return $TZ;
+}
+
+sub tz_local_offset (;$)
+{
+	my ($time) = @_;
+
+	$time = time() unless $time;
+	my (@l) = localtime($time);
+	my $isdst = $l[8];
+
+	if (defined($tz_local[$isdst])) {
+		return $tz_local[$isdst];
+	}
+
+	$tz_local[$isdst] = &calc_off($time);
+
+	return $tz_local[$isdst];
+}
+
+sub calc_off
+{
+	my ($time) = @_;
+
+	my (@l) = localtime($time);
+	my (@g) = gmtime($time);
+
+	my $off;
+
+	$off =     $l[0] - $g[0]
+		+ ($l[1] - $g[1]) * 60
+		+ ($l[2] - $g[2]) * 3600;
+
+	# subscript 7 is yday.
+
+	if ($l[7] == $g[7]) {
+		# done
+	} elsif ($l[7] == $g[7] + 1) {
+		$off += 86400;
+	} elsif ($l[7] == $g[7] - 1) {
+		$off -= 86400;
+	} elsif ($l[7] < $g[7]) {
+		# crossed over a year boundry!
+		# localtime is beginning of year, gmt is end
+		# therefore local is ahead
+		$off += 86400;
+	} else {
+		$off -= 86400;
+	}
+
+	return $off;
+}
+
+# constants
+
+CONFIG: {
+	use vars qw(%dstZone %zoneOff %dstZoneOff %Zone);
+
+	my @dstZone = (
+	#   "ndt"  =>   -2*3600-1800,	 # Newfoundland Daylight   
+	    "adt"  =>   -3*3600,  	 # Atlantic Daylight   
+	    "edt"  =>   -4*3600,  	 # Eastern Daylight
+	    "cdt"  =>   -5*3600,  	 # Central Daylight
+	    "mdt"  =>   -6*3600,  	 # Mountain Daylight
+	    "pdt"  =>   -7*3600,  	 # Pacific Daylight
+	    "ydt"  =>   -8*3600,  	 # Yukon Daylight
+	    "hdt"  =>   -9*3600,  	 # Hawaii Daylight
+	    "bst"  =>   +1*3600,  	 # British Summer   
+	    "mest" =>   +2*3600,  	 # Middle European Summer   
+	    "sst"  =>   +2*3600,  	 # Swedish Summer
+	    "fst"  =>   +2*3600,  	 # French Summer
+            "eest" =>   +3*3600,         # Eastern European Summer
+	    "wadt" =>   +8*3600,  	 # West Australian Daylight
+	    "kdt"  =>  +10*3600,	 # Korean Daylight
+	#   "cadt" =>  +10*3600+1800,	 # Central Australian Daylight
+	    "eadt" =>  +11*3600,  	 # Eastern Australian Daylight
+	    "nzd"  =>  +13*3600,  	 # New Zealand Daylight   
+	    "nzdt" =>  +13*3600,  	 # New Zealand Daylight   
+	);
+
+	my @Zone = (
+	    "gmt"	=>   0,  	 # Greenwich Mean
+	    "ut"        =>   0,  	 # Universal (Coordinated)
+	    "utc"       =>   0,
+	    "wet"       =>   0,  	 # Western European
+	    "wat"       =>  -1*3600,	 # West Africa
+	    "at"        =>  -2*3600,	 # Azores
+	# For completeness.  BST is also British Summer, and GST is also Guam Standard.
+	#   "bst"       =>  -3*3600,	 # Brazil Standard
+	#   "gst"       =>  -3*3600,	 # Greenland Standard
+	#   "nft"       =>  -3*3600-1800,# Newfoundland
+	#   "nst"       =>  -3*3600-1800,# Newfoundland Standard
+	    "ewt"       =>  -4*3600,	 # U.S. Eastern War Time
+	    "ast"       =>  -4*3600,	 # Atlantic Standard
+	    "est"       =>  -5*3600,	 # Eastern Standard
+	    "cst"       =>  -6*3600,	 # Central Standard
+	    "mst"       =>  -7*3600,	 # Mountain Standard
+	    "pst"       =>  -8*3600,	 # Pacific Standard
+	    "yst"	=>  -9*3600,	 # Yukon Standard
+	    "hst"	=> -10*3600,	 # Hawaii Standard
+	    "cat"	=> -10*3600,	 # Central Alaska
+	    "ahst"	=> -10*3600,	 # Alaska-Hawaii Standard
+	    "nt"	=> -11*3600,	 # Nome
+	    "idlw"	=> -12*3600,	 # International Date Line West
+	    "cet"	=>  +1*3600, 	 # Central European
+	    "mez"	=>  +1*3600, 	 # Central European (German)
+	    "ect"	=>  +1*3600, 	 # Central European (French)
+	    "met"	=>  +1*3600, 	 # Middle European
+	    "mewt"	=>  +1*3600, 	 # Middle European Winter
+	    "swt"	=>  +1*3600, 	 # Swedish Winter
+	    "set"	=>  +1*3600, 	 # Seychelles
+	    "fwt"	=>  +1*3600, 	 # French Winter
+	    "eet"	=>  +2*3600, 	 # Eastern Europe, USSR Zone 1
+	    "ukr"	=>  +2*3600, 	 # Ukraine
+	    "bt"	=>  +3*3600, 	 # Baghdad, USSR Zone 2
+	#   "it"	=>  +3*3600+1800,# Iran
+	    "zp4"	=>  +4*3600, 	 # USSR Zone 3
+	    "zp5"	=>  +5*3600, 	 # USSR Zone 4
+	#   "ist"	=>  +5*3600+1800,# Indian Standard
+	    "zp6"	=>  +6*3600, 	 # USSR Zone 5
+	# For completeness.  NST is also Newfoundland Stanard, and SST is also Swedish Summer.
+	#   "nst"	=>  +6*3600+1800,# North Sumatra
+	#   "sst"	=>  +7*3600, 	 # South Sumatra, USSR Zone 6
+	#   "jt"	=>  +7*3600+1800,# Java (3pm in Cronusland!)
+	    "wst"	=>  +8*3600, 	 # West Australian Standard
+	    "hkt"	=>  +8*3600, 	 # Hong Kong
+	    "cct"	=>  +8*3600, 	 # China Coast, USSR Zone 7
+	    "jst"	=>  +9*3600,	 # Japan Standard, USSR Zone 8
+	    "kst"	=>  +9*3600,	 # Korean Standard
+	#   "cast"	=>  +9*3600+1800,# Central Australian Standard
+	    "east"	=> +10*3600,	 # Eastern Australian Standard
+	    "gst"	=> +10*3600,	 # Guam Standard, USSR Zone 9
+	    "nzt"	=> +12*3600,	 # New Zealand
+	    "nzst"	=> +12*3600,	 # New Zealand Standard
+	    "idle"	=> +12*3600,	 # International Date Line East
+	);
+
+	%Zone = @Zone;
+	%dstZone = @dstZone;
+	%zoneOff = reverse(@Zone);
+	%dstZoneOff = reverse(@dstZone);
+
+}
+
+sub tz_offset (;$$)
+{
+	my ($zone, $time) = @_;
+
+	return &tz_local_offset($time) unless($zone);
+
+	$time = time() unless $time;
+	my(@l) = localtime($time);
+	my $dst = $l[8];
+
+	$zone = lc $zone;
+
+	if($zone =~ /^(([\-\+])\d\d?)(\d\d)$/) {
+		my $v = $2 . $3;
+		return $1 * 3600 + $v * 60;
+	} elsif (exists $dstZone{$zone} && ($dst || !exists $Zone{$zone})) {
+		return $dstZone{$zone};
+	} elsif(exists $Zone{$zone}) {
+		return $Zone{$zone};
+	}
+	undef;
+}
+
+sub tz_name (;$$)
+{
+	my ($off, $dst) = @_;
+
+	$off = tz_offset()
+		unless(defined $off);
+
+	$dst = (localtime(time))[8]
+		unless(defined $dst);
+
+	if (exists $dstZoneOff{$off} && ($dst || !exists $zoneOff{$off})) {
+		return $dstZoneOff{$off};
+	} elsif (exists $zoneOff{$off}) {
+		return $zoneOff{$off};
+	}
+	sprintf("%+05d", int($off / 60) * 100 + $off % 60);
+}
+
+1;

Added: trunk/orca/packages/TimeDate-1.10/MANIFEST
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/MANIFEST	(original)
+++ trunk/orca/packages/TimeDate-1.10/MANIFEST	Sat Jul 13 21:27:20 2002
@@ -0,0 +1,21 @@
+ChangeLog
+MANIFEST
+Makefile.PL
+README
+TimeDate.ppd
+lib/Date/Format.pm
+lib/Date/Language.pm
+lib/Date/Language/Austrian.pm
+lib/Date/Language/Czech.pm
+lib/Date/Language/Dutch.pm
+lib/Date/Language/English.pm
+lib/Date/Language/French.pm
+lib/Date/Language/German.pm
+lib/Date/Language/Italian.pm
+lib/Date/Language/Norwegian.pm
+lib/Date/Parse.pm
+lib/Time/Zone.pm
+t/date.t
+t/format.t
+t/getdate.t
+t/lang.t

Added: trunk/orca/packages/TimeDate-1.10/ChangeLog
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/ChangeLog	(original)
+++ trunk/orca/packages/TimeDate-1.10/ChangeLog	Sat Jul 13 21:27:21 2002
@@ -0,0 +1,157 @@
+Change 579 on 2000/09/04 by <gbarr at pobox.com> (Graham Barr)
+
+	Date::Parse
+	- Support for more date formats
+	
+	Time::Zone
+	- Added more zones
+
+Change 539 on 2000/06/14 by <gbarr at pobox.com> (Graham Barr)
+
+	Documentation updates
+
+Change 536 on 2000/06/06 by <gbarr at pobox.com> (Graham Barr)
+
+	Fix VERSION numbers
+
+Change 535 on 2000/06/06 by <gbarr at pobox.com> (Graham Barr)
+
+	Date::Format
+	- Added support for %O* to support output of roman numerals
+
+Change 443 on 2000/03/29 by <gbarr at pobox.com> (Graham Barr)
+
+	Release 1.09
+
+Change 442 on 2000/03/29 by <gbarr at pobox.com> (Graham Barr)
+
+	Added PPD stuff to Makefile.PL
+
+Change 441 on 2000/03/29 by <gbarr at pobox.com> (Graham Barr)
+
+	Date::Parse
+	- Allow "s after the timezone
+
+Change 440 on 2000/03/29 by <gbarr at pobox.com> (Graham Barr)
+
+	Date::Format
+	- Fix doc for %c and %C
+
+Change 409 on 2000/03/28 by <gbarr at pobox.com> (Graham Barr)
+
+	Moved .pm files into lib directory
+
+Change 408 on 2000/03/28 by <gbarr at pobox.com> (Graham Barr)
+
+	str2time returns undef on error bit Time::Local returns
+	-1. Check if the -1 is real or an error
+
+Change 407 on 2000/03/28 by <gbarr at pobox.com> (Graham Barr)
+
+	Added Eastern European Summer Time EEST
+
+Change 268 on 1999/03/18 by <gbarr at pobox.com> (Graham Barr)
+
+	Date::Format, Time::Zone
+	- Fix problem with %z and %Z as suggested by
+	  Jason A Smith <smithj4 at rpi.edu>
+
+Change 267 on 1999/03/18 by <gbarr at pobox.com> (Graham Barr)
+
+	- Make t/getdate.t more portable as suggested by
+	  Paul Schinder <schinder at pobox.com>
+
+Change 250 on 1999/02/06 by <gbarr at pobox.com> (Graham Barr)
+
+	Date::Format
+	- Correct docs for %d and %e
+
+Change 249 on 1999/02/06 by <gbarr at pobox.com> (Graham Barr)
+
+	Added Date::Language::Czech
+
+Change 180 on 1998/08/05 by <gbarr at pobox.com> (Graham Barr)
+
+	Date::Language
+	- Added Date::Language::French contributed by
+	  Emmanuel Bataille (bem at residents.frmug.org)
+	- Split out the languages into .pm's
+	
+	Date::Parse
+	- Added patch from Alan Burlison to Date::Parse to allow zone
+	  offests +7, +10 and +700
+	- Parse now supports GMT+0100
+
+*** Release 1.08
+
+Fri Jan  2 1998 <gbarr at pobox.com> (Graham Barr)
+
+	Date::Format, Time::Zone
+	- Fix for formatting %z and %Z
+	
+	all
+	- Update Email address and year
+
+Tue Feb 17 1998 <gbarr at pobox.com> (Graham Barr)
+
+	Date::Language
+	- Added format_o to German
+
+Fri Sep 12 1997 <gbarr at pobox.com> (Graham Barr)
+
+        Date::Parse
+        - Added 'DST' to parser, it adjusts $zone by 3600 (but that may not
+          be right in all cases)
+	- Added a check to str2time to ensure valid
+	  values are passed to Time::Local, to avoid croak-ing
+	- Fixed to treat AM and PM correctly when the hour is 12. (I hope :-)
+
+	Time::Zone
+	- Modified for Western Australia
+
+Tue 07 Jan 1996
+
+	o Release 1.07
+	o Fixed a problem in Time::Zone (had @l[8] instead of $l[8], doh! )
+
+Thu 02 Jan 1996
+
+	o Release 1.06
+	o Fixed t/getdate.t
+	o Date::Parse can now parse the date-format 960913, which apparently
+	  is fairly common in sweden.
+
+Wed 31 Jul 1996 <bodg at tiuk.ti.com>
+
+	o Release 1.05
+	o Modified Date::Format not to use single letter sub names,
+	  all format sub names are nore prefixed with format_
+	o Cleaned up Date/Format.pm so that AUTOLOAD is not required
+	o Patched Date/Language.pm to add Norwegian. Thanks to
+	  Gisle Aas <aas at bergen.sn.no> for the patch
+
+Thu 27 Jun 1996 <bodg at tiuk.ti.com>
+
+	o Added %z to Date::Format to output timezone in +/-0000 format
+	o Added multi-language support via Date::Language,.
+
+Tue 25 Jun 1996 <bodg at tiuk.ti.com>
+
+        o Some code tidying up
+        o added a new test, copied from Date::GetDate
+        o improved performance
+
+Wed 22 May 1996 <bodg at tiuk.ti.com>
+
+	o Fixed a bug in the parser for dates in a default (local) timezone
+	  but a different dst
+
+Wed 15 May 1996 <bodg at tiuk.ti.com>
+
+    	o Added support for mainframe type dates
+
+Fri  3 May 1996 <bodg at tiuk.ti.com>
+
+	o Added %s to date formatting at request of Josh Osborne
+	  <stripes at va.pubnix.com>.
+

Added: trunk/orca/packages/TimeDate-1.10/Makefile.PL
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/Makefile.PL	(original)
+++ trunk/orca/packages/TimeDate-1.10/Makefile.PL	Sat Jul 13 21:27:21 2002
@@ -0,0 +1,41 @@
+# This -*- perl -*- script makes the Makefile
+# $Id: //depot/TimeDate/Makefile.PL#4 $
+
+#--- Distribution section ---
+
+$DISTNAME = 'TimeDate';
+$VERSION  = "1.10";
+
+#--- Write the Makefile
+
+BEGIN { require 5.002 }
+
+use ExtUtils::MakeMaker;
+
+my @ppd;
+
+if ($] >= 5.00503) {
+  @ppd = (
+    AUTHOR    => 'Graham Barr <gbarr at pobox.com>',
+    ABSTRACT  => 'Formatting and Parsing of Time and Date'
+  );
+}
+
+sub MY::postamble {
+
+  return '' unless $] >= 5.00503;
+
+<<'ESQ';
+
+dist : ppd
+
+ESQ
+}
+
+WriteMakefile(
+	VERSION   => $VERSION,
+	NAME      => $DISTNAME,
+	@ppd
+);
+
+

Added: trunk/orca/packages/TimeDate-1.10/README
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/README	(original)
+++ trunk/orca/packages/TimeDate-1.10/README	Sat Jul 13 21:27:22 2002
@@ -0,0 +1,28 @@
+This is the perl5 TimeDate distribution. It requires perl version 5.003
+or later
+
+This distribution replaces my earlier GetDate distribution, which was
+only a date parser. The date parser contained in this distribution is
+far superior to the yacc based parser, and a *lot* fatser.
+
+The parser contained here will only parse absolute dates, if you want a
+date parser that can parse relative dates then take a look at the Time
+modules by David Muir on CPAN.
+
+You install the library by running these commands:
+
+   perl Makefile.PL
+   make
+   make test
+   make install
+
+Please report any bugs/suggestions to <gbarr at pobox.com>
+
+Copyright 1996-2000 Graham Barr. All rights reserved.
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+Share and Enjoy!
+Graham <gbarr at pobox.com>
+

Added: trunk/orca/packages/TimeDate-1.10/TimeDate.ppd
==============================================================================
--- trunk/orca/packages/TimeDate-1.10/TimeDate.ppd	(original)
+++ trunk/orca/packages/TimeDate-1.10/TimeDate.ppd	Sat Jul 13 21:27:22 2002
@@ -0,0 +1,10 @@
+<SOFTPKG NAME="TimeDate" VERSION="1,10,0,0">
+	<TITLE>TimeDate</TITLE>
+	<ABSTRACT>Formatting and Parsing of Time and Date</ABSTRACT>
+	<AUTHOR>Graham Barr &lt;gbarr at pobox.com&gt;</AUTHOR>
+	<IMPLEMENTATION>
+		<OS NAME="linux" />
+		<ARCHITECTURE NAME="i586-linux" />
+		<CODEBASE HREF="" />
+	</IMPLEMENTATION>
+</SOFTPKG>




More information about the Orca-checkins mailing list