This is Info file pm.info, produced by Makeinfo version 1.68 from the
input file bigpm.texi.


File: pm.info,  Node: CfgTie/Cfgfile,  Next: CfgTie/TieAliases,  Prev: CfgTie/CfgArgs,  Up: Module List

An object to help interface to configuration files
**************************************************

NAME
====

   `CfgTie::Cfgfile' - An object to help interface to configuration files

SYNOPSIS
========

   Helps interface to the text based configuration files commonly used in
Unix

DESCRIPTION
===========

   This is a fairly generic interface to allow many configuration files to
be used as hash ties.  *Note: This is not intended to be called by user
programs, but by modules wishing to reuse a template structure!*

     package mytie;
     require CfgTie::Cfgfile;

     @ISA = qw(CfgTie::Cfgfile);

   The major methods:

   new(*$filepath*, *@Extra stuff*)

   or

   new(*$RCS-Object*, *@Extra stuff*)

filepath
     If defined, this is the path to the configuration file to be opened.

RCS-Object
     If defined, this is an RCS object (or similar) that will control how
     to check in and check out the configuration file.  See RCS Perl
     module for more details on how to create this object (do not use the
     same instance for each configuration file!).  Files will be checked
     back in when the END routine is called.  If a filepath is specified,
     it will override the one previously set with the RCS object.  If no
     filepath is specified, but the RCS has one specified, it will be used
     instead.

The derived object
------------------

   Your derived object may need to provide the following methods:

scan
     This is called when the file is first tied in.  It should scan the
     file, placing the associated contents into the `{Contents}' key.

format(key,*contents*)
     This formats a single entry to be stored in a file.  This is used for
     when a value can be stored simply.

`cfg_begin'
     If this method is defined, it is called just before the configuration
     file will be modified.

`cfg_end'
     If this method is defined, it is called after the configuration file
     has changed.  It can be used, for instances, to rebuild a binary
     database, restart a service, or email Martians.

`makerewrites'
     This is called just before the configuration file will be rewritten.
     It should return a reference to a function that is used to transform
     the current control file into the new one.  This transforming
     function is called for each line in the configuration file while it
     is being rewritten.

Object methods you can use
--------------------------

   `Comment_Add' This appends the string to the list of comments that will
be logged for this revision (assuming that a Revision Control object was
used).

   `Queue_Store($key,$val)' This queues (for later) the transaction that
key should be associated with val.  The queue is employed to synchronize
all of the settings with the stored settings on disk.

   `Queue_Delete($key)' This queues (for later) the transaction that any
value associated with key should be removed.

   `RENAME(\%rules)' This method will move through the whole table and
make a series of changes.  It may:

Remove some entries, based upon their keys
Rename the keys from some entries
Change the contents of the keys, possibly removing portions
   `\%rules' is the set of rules that governs will be changed in name and
what will be removed.  It is an associative array (hash) of a form like:

     {
         PATTERN1 => "",
         PATTERN2 => REWRITE,
     }

   `PATTERN1 = ' Two things will happen with a rule like this:

Every key in the table that matches the pattern will be removed
Any element (of an entry) that matches the pattern will be removed
   `PATTERN2 = REWRITE' In this case the rewrite indicates what should
replace the pattern:

   * Every key that matches the pattern will be rewritten and replace with
     a new key.

   * Any element (of an entry) that matches the pattern will be modified to
     match the rewrite rule.

See Also
========

   *Note CfgTie/TieAliases: CfgTie/TieAliases,,   *Note CfgTie/TieGeneric:
CfgTie/TieGeneric,, *Note CfgTie/TieGroup: CfgTie/TieGroup, *Note
CfgTie/TieHost: CfgTie/TieHost,,      *Note CfgTie/TieMTab:
CfgTie/TieMTab,,    *Note CfgTie/TieNamed: CfgTie/TieNamed,, *Note
CfgTie/TieNet: CfgTie/TieNet,,       *Note CfgTie/TiePh: CfgTie/TiePh,,
 *Note CfgTie/TieProto: CfgTie/TieProto,, *Note CfgTie/TieRCService:
CfgTie/TieRCService,, *Note CfgTie/TieRsrc: CfgTie/TieRsrc,,    *Note
CfgTie/TieServ: CfgTie/TieServ,, *Note CfgTie/TieShadow:
CfgTie/TieShadow,,    *Note CfgTie/TieUser: CfgTie/TieUser,

Caveats
=======

   Additions that do not change any previously established values are
reflected immediately (and `newaliases' is run as appropriate).  Anything
which changes a previously established value, regardless of whether or not
it has been committed, are queue'd for later.  This queue is used to
rewrite the file when END is executed.

Author
======

   Randall Maas (`mailto:randym@acm.org' in this node, `http:' in this
node)


File: pm.info,  Node: CfgTie/TieAliases,  Next: CfgTie/TieGeneric,  Prev: CfgTie/Cfgfile,  Up: Module List

an associative array of mail aliases to targets
***********************************************

NAME
====

   CfgTie::TieAliases - an associative array of mail aliases to targets

SYNOPSIS
========

   Makes it easy to manage the mail aliases (`/etc/aliases') table as a
hash.

     tie %mtie,'CfgTie::TieAliases'

     #Redirect mail for foo-man to root
     $mtie{'foo-man'}=['root'];

DESCRIPTION
===========

   This Perl module ties to the `/etc/aliases' file so that things can be
updated on the fly.  When you tie the hash, you are allowed an optional
parameter to specify what file to tie it to.

     tie %mtie,'CfgTie::TieAliases'

   or

     tie %mtie,'CfgTie::TieAliases',I<aliases-like-file>

   or

     tie %mtie,'CfgTie::TieAliases',I<revision-control-object>

Methods
-------

   `ImpGroups' will import the various groups from /etc/group using
`CfgTie::TieGroup'.  It allows an optional code reference to select which
groups get imported.  This code is passed a reference to each group and
needs to return nonzero if it is to be imported, or zero if it not to be
imported.  For example:

     (tied  %mtie)->ImpGroups
     	{
     	   my $T=shift;
     	   if ($T->{'id} < 100) {return 0;}
     	   return 1;
     	}

Format of the `/etc/aliases' file
---------------------------------

   The format of the `/etc/aliases' file is poorly documented.  The format
that `CfgTie::TieAliases' understands is documented as follows:

`#'comments
     Anything after a hash mark (`#') to the end of the line is treated as
     a comment, and ignored.

text:
     The letters, digits, dashes, and underscores before a colon are
     treated as the name of an alias.  The alias will be expanded to
     whatever is on the line after the colon.  (Each of those is in turn
     expanded).

`:include:'file
     Any element of the alias list that includes `:include:' indicates
     that the specified file should be read from.  The file may only
     specify user names or email addresses.  Several include directives
     may used in the aliase.  It is not clear which of these files is the
     preferred file to modify.

Continuation lines
     Any line that starts with a space is a continuation of the previous
     line.

Caveats
=======

   Not all changes to are immediately reflected to the specified file.
See the *Note CfgTie/Cfgfile: CfgTie/Cfgfile, module for more information

FILES
=====

   `/etc/aliases'

See Also
========

   *Note CfgTie/Cfgfile: CfgTie/Cfgfile,,    *Note CfgTie/TieRCService:
CfgTie/TieRCService,, *Note CfgTie/TieGeneric: CfgTie/TieGeneric,, *Note
CfgTie/TieGroup: CfgTie/TieGroup,, *Note CfgTie/TieHost: CfgTie/TieHost,,
*Note CfgTie/TieNamed: CfgTie/TieNamed,,   *Note CfgTie/TieNet:
CfgTie/TieNet,, *Note CfgTie/TiePh: CfgTie/TiePh,, *Note CfgTie/TieProto:
CfgTie/TieProto,,   *Note CfgTie/TieServ: CfgTie/TieServ,,  *Note
CfgTie/TieShadow: CfgTie/TieShadow,, *Note CfgTie/TieUser: CfgTie/TieUser,

   `aliases(5)' in this node `newaliases(1)' in this node

Author
======

   Randall Maas (`randym@acm.org' in this node, `http:' in this node)


File: pm.info,  Node: CfgTie/TieGeneric,  Next: CfgTie/TieGroup,  Prev: CfgTie/TieAliases,  Up: Module List

A generic hash that automatically binds others
**********************************************

NAME
====

   CfgTie::TieGeneric - A generic hash that automatically binds others

SYNOPSIS
========

   This is an associative array that automatially ties other configuration
hashes

DESCRIPTION
===========

   This is a tie to bring other ties together automatically so you, the
busy programmer and/or system administrator, don't have to.  The related
Perl module is not loaded unless it is needed at runtime.

     my %gen;
     tie %gen, 'CfgTie::TieGeneric';

Primary, or well-known, keys
----------------------------

env
     This refers directly to the ENV hash.

group
mail
     This is a special key.  It forms a hash, with subkeys.  See below for
     more information

`net'
     This is a special key.  It forms a hash with additional subkeys. See
     below for more details.

user
     This is a link to the `TieUser' module (*Note CfgTie/TieUser:
     CfgTie/TieUser,).

Composite
     Composite primary keys are just like absolute file paths.  For
     example, if you wanted to do something like this:

          my %lusers = $gen{'user'};
          my $Favorite_User = $lusers{'mygirl'};

     You could just do:

          my $Favorite_User = $gen{'/users/mygirl'};

others...
     These are the things automatically included in.  This will be
     described below.

Subkeys for mail
----------------

aliases
     *Note CfgTie/TieAliases: CfgTie/TieAliases,

Subkeys for `net'
-----------------

host
     *Note CfgTie/TieHost: CfgTie/TieHost,

service
     *Note CfgTie/TieServ: CfgTie/TieServ,

protocol
     *Note CfgTie/TieProto: CfgTie/TieProto,

`addr'
     *Note CfgTie/TieNet: CfgTie/TieNet,

How other ties are automatically bound
--------------------------------------

   Other keys are automatically (if it all possible) brought in using the
following procedure:

  1. If it is something already linked to it, that thingy is automatically
     returned (of course).

  2. If the key is simple, like `AABot', we will try to `use AABot;' If
     that works we will tie it and return the results.

  3. If the key is more complex, like `/OS3/Config', we will try to see if
     `OS3' is already tied (and try to tie it, like above, if not).  If
     that works, we will just look up Config in that hash.  If it does not
     work, we will try to use and tie `OS3::Config', `OS3::TieConfig', and
     `OS3::ConfigTie'.  If any of those work, we return the results.

  4. Otherwise, undef will be returned.

See Also
========

   *Note CfgTie/TieAliases: CfgTie/TieAliases,, *Note CfgTie/TieGroup:
CfgTie/TieGroup,, *Note CfgTie/TieHost: CfgTie/TieHost,, *Note
CfgTie/TieMTab: CfgTie/TieMTab,,    *Note CfgTie/TieNamed:
CfgTie/TieNamed,, *Note CfgTie/TieNet: CfgTie/TieNet,, *Note CfgTie/TiePh:
CfgTie/TiePh,,      *Note CfgTie/TieProto: CfgTie/TieProto,, *Note
CfgTie/TieRCService: CfgTie/TieRCService,, *Note CfgTie/TieRsrc:
CfgTie/TieRsrc,,    *Note CfgTie/TieServ: CfgTie/TieServ,,  *Note
CfgTie/TieShadow: CfgTie/TieShadow,, *Note CfgTie/TieUser: CfgTie/TieUser,

Author
======

   Randall Maas (`mailto:randym@acm.org' in this node, `http:' in this
node)


File: pm.info,  Node: CfgTie/TieGroup,  Next: CfgTie/TieHost,  Prev: CfgTie/TieGeneric,  Up: Module List

an associative array of group names and ids to information
**********************************************************

NAME
====

   CfgTie::TieGroup - an associative array of group names and ids to
information

SYNOPSIS
========

   Makes the groups database available as regular hash

     tie %group,'CfgTie::TieGroup'
     $group{'myfriends'}=['jonj', @{$group{'myfriends'}];

   or

     tie %group,'CfgTie::TieGroup', 'mygroupfile'

DESCRIPTION
===========

   This is a straight forward hash tie that allows us to access the user
group database sanely.

   It cross ties with the user package and the mail packages

Ties
----

   There are two ties available for programmers:

`tie %group,'CfgTie::TieGroup''
     `$group{$name}' will return a hash reference of the named group
     information.

`tie %group_id,'CfgTie::Group_id''
     `$group_id{$id}' will return a HASH reference for the specified group.

Structure of hash
-----------------

   Any given group entry has the following information assoicated with it:

name
id
members
     A list reference to all of the users that are part of this group.

`_members'
     A list reference to all of the users that are explicitly listed in the
     /etc/group file.

   Plus an (probably) obsolete fields:

Password
     This is the encrypted password, but will probably be obsolete.

   Each of these entries can be modified (even deleted), and they will be
reflected in the overall system.  Additionally, the programmer can set any
other associated key, but this information will only be available to a
running Perl script.

Additional Routines
-------------------

`(tied %MyHash)-'files()>
     Returns a list of files employed.

`&CfgTie::TieGroup'status()'
`&CfgTie::TieGroup_id'status()'
     Will return stat information on the group database.

Miscellaneous
-------------

   `$CfgTie::TieGroup_rec'groupmod' contains the path to the program
`groupmod'.  This can be modified as required.

   `$CfgTie::TieGroup_rec'groupadd' contains the path to the program
`groupadd'.  This can be modified as required.

   `$CfgTie::TieGroup_rec'groupdel' contains the path to the program
`groupdel'.  This can be modified as required.

Files
=====

   `/etc/passwd' /etc/group `/etc/gshadow' `/etc/shadow'

See Also
========

   *Note CfgTie/Cfgfile: CfgTie/Cfgfile,,      *Note CfgTie/TieAliases:
CfgTie/TieAliases,, *Note CfgTie/TieGeneric: CfgTie/TieGeneric,, *Note
CfgTie/TieHost: CfgTie/TieHost,,      *Note CfgTie/TieMTab:
CfgTie/TieMTab,,    *Note CfgTie/TieNamed: CfgTie/TieNamed,, *Note
CfgTie/TieNet: CfgTie/TieNet,,       *Note CfgTie/TiePh: CfgTie/TiePh,,
 *Note CfgTie/TieProto: CfgTie/TieProto,, *Note CfgTie/TieRCService:
CfgTie/TieRCService,, *Note CfgTie/TieRsrc: CfgTie/TieRsrc,,    *Note
CfgTie/TieServ: CfgTie/TieServ,, *Note CfgTie/TieShadow:
CfgTie/TieShadow,,    *Note CfgTie/TieUser: CfgTie/TieUser,

   `group(5)' in this node, `passwd(5)' in this node, `shadow(5)' in this
node, `groupmod(8)' in this node, `groupadd(8)' in this node,
`groupdel(8)' in this node

Caveats
=======

   The current version does cache some group information.

Author
======

   Randall Maas (`mailto:randym@acm.org' in this node, `http:' in this
node)


File: pm.info,  Node: CfgTie/TieHost,  Next: CfgTie/TieMTab,  Prev: CfgTie/TieGroup,  Up: Module List

This accesses the hosts tables.
*******************************

NAME
====

   `CfgTie::TieHost' - This accesses the hosts tables.

SYNOPSIS
========

   This is an associative array that allows the hosts tables to be
configured easily.

     tie %host,'CfgTie::TieHost';

DESCRIPTION
===========

   This is a straightforward hash tie that allows us to access the host
database sanely.

Ties
----

   There are two ties available for programmers:

`tie %host,'CfgTie::TieHost''
     `$host{$name}' will return a hash reference of the named host
     information.

`tie %host_addr,'CfgTie::TieHost_addr''
     `$host_addr{$addr}' will return a hash reference for the specified
     host.

Structure of hash
-----------------

   Any given host entry has the following information assoicated with it:

Name
     Host name

Aliases
     Other names for this host

`AddrType'
     The type of address

Length
`Addrs'
     A list reference of addresses.  You will need something like

          ($a,$b,$c,$d) = unpack('C4',$Addr);

     to get the address out sanely.

   Additionally, the programmer can set any other associated key, but this
information will only be available to a running Perl script.

See Also
========

   *Note CfgTie/TieAliases: CfgTie/TieAliases,, *Note CfgTie/TieGeneric:
CfgTie/TieGeneric,, *Note CfgTie/TieGroup: CfgTie/TieGroup,, *Note
CfgTie/TieMTab: CfgTie/TieMTab,,    *Note CfgTie/TieNamed:
CfgTie/TieNamed,,   *Note CfgTie/TieNet: CfgTie/TieNet,, *Note
CfgTie/TiePh: CfgTie/TiePh,,      *Note CfgTie/TieProto: CfgTie/TieProto,,
 *Note CfgTie/TieRCService: CfgTie/TieRCService,, *Note CfgTie/TieRsrc:
CfgTie/TieRsrc,,    *Note CfgTie/TieServ: CfgTie/TieServ,,    *Note
CfgTie/TieShadow: CfgTie/TieShadow,, *Note CfgTie/TieUser: CfgTie/TieUser,

   `host(5)' in this node

Caveats
=======

   The current version does cache some host information.

Author
======

   Randall Maas (`mailto:randym@acm.org' in this node, `http:' in this
node)


File: pm.info,  Node: CfgTie/TieMTab,  Next: CfgTie/TieNamed,  Prev: CfgTie/TieHost,  Up: Module List

an associative array of mount entries
*************************************

NAME
====

   `CfgTie::TieMTab' - an associative array of mount entries

SYNOPSIS
========

   makes the mount table available as a regular hash:

     tie %MTab, 'CfgTie::TieMTab';
     tie %MTab, 'CfgTie::TieMTab_dev';

DESCRIPTION
===========

   The keys are path and devices.

   The values are always list references.  The lists are one of two forms.
For local path, the list is of the form:

     [$device, $path, $type, $options]

   Other paths not in the mount table are of the form

     [$device]

   The form of device varies from system to system.  It is usually the
device specified in the mount table.  NFS and other network mounts are of
the form *host:path*.  `amd' devices are different, and (at the time of
this writing) their form isn't known.

Caveats
=======

   This requires Quota to work.  You can get it from CPAN.

Files
=====

`/etc/mtab'
     (on many machines)

`/proc/mounts'
     (on Linux machines)

See Also
========

   `Quota::' in this node

Author
======

   Randall Maas (`mailto:randym@acm.org' in this node, `http:' in this
node)


File: pm.info,  Node: CfgTie/TieNamed,  Next: CfgTie/TieNet,  Prev: CfgTie/TieMTab,  Up: Module List

A tool to help configure the name daemon (BIND DNS server)
**********************************************************

NAME
====

   `CfgTie::TieNamed' - A tool to help configure the name daemon (BIND DNS
server)

SYNOPSIS
========

   This is a PERL module to help make it easy to configure the DNS name
server

DESCRIPTION
===========

   This is a tie hash to the NAMED configuration files.  You use it as
follows:

     tie %named, 'CfgTie::TieNamed','/path/to/named.boot';
     $named = CfgTie::TieNamed->new('/path/to/named.boot');

   These will set up a hash (*named*) to the named configuration files.
It will used the specified `named.boot' file.

     tie %named, 'CfgTie::TieNamed';
     $named = CfgTie::TieNamed->new();

   These will set up a hash (*named*) to the named configuration files.
The files will be automatically determined from the system startup scripts.

Examples
--------

   Lets say you would like to name a bunch of machines (like modems) with
a base name and a number.  The number part needs to be the same as the
same as the last number in the IP address.  You know these go in a domain
like, "wikstrom.pilec.rm.net" which is a zone for your name server:

     tie %DNS, 'CfgTie::TieNamed';
     my $Tbl = $DNS->{'primary'}->{'wikstrom.pilec.rm.net'};
     my $N=10; #Ten modems;
     my $prefix="usr2-port";
     my $ip_start=11;
     for (my $i = 0; $i < $N; $i++)
     {
        #Insert the address record in the table
        $Tbl->{$prefix.$i}->{'A'} = "127.221.19.".($i+$ip_start);
     }

     #Finally make sure that the reverse name space is up to date
     (tied %DNS)->RevXRef('wikstrom.pilec.rm.net','19.221.127.in-addr.arpa');

   Even the address to name mapping will be kept up to date.

The basic structure of the named configuration table
----------------------------------------------------

`bogusns'
     A list of name server addresses to ignore.

cache
     See `named(8)' in this node for a description

`check-names'
directory
     This specifies the working directory of the `named' server, and is
     used in determining the location of the associated files.

`forwarders'
     A list of other servers' addresses on the site that can be used for
     recursive look up.

limit
     Controls operational parameters of the `named' server.  See below.

options
     The list of options the `named' server should adhere to.

`primary'
     This maps to a an associative array of name spaces we are primary
     for.  See below for more details on this is handled.

`secondary'
     This maps to a an associative array of name spaces we are secondary
     for.

`sortlist'
     See `named(8)' in this node for a description

`xfrnets'
     The list of networks which are allowed to request zone transfers.  If
     not present, all hosts on all networks are.

   Others may be set as well, but they are for backwards compatibility and
should be changed to the more appopriate form.  See `named(8)' in this
node for more information.

Extra methods for the configuration table
-----------------------------------------

   These are various methods you can use.  Of course, you will need an
object reference you can use for the remaining methods.  Note that if you
tied the variable, you will want to use code sorta like: `my $Obj = tied
%CfgTie::TieNamed;'

   `RevSpaces' Is the list of the reverses addresses spaces that the
server is primary for (except loopback)

   `FwdSpaces' Is the list of name spaces the server is primary for
(except the loopback and reverse name spaces)

   `RevXRef($'*fwd*`,$'rev) This will check that reverse look up is up to
date with the primary look up.  It will add reverse entries as appropriate
(if there is one missing, or the value is correct).  It will not change a
reverse entry if there are multiple names with the same address entry.
rev is optional, but this method will return (with a 0) if it is not
specified and there is more than one reverse name space.  *fwd* is
optional, but this method will return (with a 0) if it is not specified
and there is more than one primary name space.  Returns the number of
entries changed or added.

   Note: This also derives any other methods from the `CfgTie::Cfgfile'
module (*Note CfgTie/Cfgfile: CfgTie/Cfgfile,).

The basic structure of a primary name space table
-------------------------------------------------

   The `$named-'>`{primary}' entry refers to a associative arrays.  The
keys are the domain names that are to be server.  ie,

     my %mydom = $name->{primary}->{'mydomain.com'};

   These associations in turn refer to a table of names and their
respective attributes.  The keys to this table are the machine names.

   The values associated keys are hash references to domain name records.
This in turn refers to another (confused yet?) associative array.  The
keys of this table are the DNS attribute names.  The values associated
with the key are list references, usually a set of possible values for the
given attribute and name pair.  The most common ones are:

A
     This is a list reference to all of the physical addresses the given
     machine name has.

NS
     This is a list reference to all of the servers that can serve as
     domain name servers.

CNAME
     This is a list reference to all of the real names the given machine
     name has.

SOA
     Has a list reference with the following structure `HOSTDATAFROM
     MAILADDR SERIAL REFRESH RETRY EXPIRE MinTTL' The Serial number is
     automatically updated for each table that is changed.  The format is
     guessed (from various date formats include YYYYMMDD, YYYYDDD, and
     others), and properly incremented or set.

PTR
     This is a list reference to the real name of a given machines address.

`TXT'
     Each element of this list refers to a string describing the domain or
     name.

`WKS'
`HINFO'
Extra methods table
-------------------

   `DblLinks' This looks for entries with both a A and a CNAME entry.
*Keep* controls whether to keep the A or the CNAME entry; the default is
to keep the A entry (and delete the CNAME entry).  Returns a count of all
the records that were modified.

   Note: This also derives any other methods from the `CfgTie::Cfgfile'
module (*Note CfgTie/Cfgfile: CfgTie/Cfgfile,).

See Also
========

   *Note CfgTie/Cfgfile: CfgTie/Cfgfile,, *Note CfgTie/TieAliases:
CfgTie/TieAliases,, *Note CfgTie/TieGeneric: CfgTie/TieGeneric,,   *Note
CfgTie/TieGroup: CfgTie/TieGroup,, *Note CfgTie/TieHost: CfgTie/TieHost,,
 *Note CfgTie/TieMTab: CfgTie/TieMTab,,      *Note CfgTie/TieNet:
CfgTie/TieNet,, *Note CfgTie/TiePh: CfgTie/TiePh,, *Note CfgTie/TieProto:
CfgTie/TieProto,,   *Note CfgTie/TieRCService: CfgTie/TieRCService,, *Note
CfgTie/TieRsrc: CfgTie/TieRsrc,< *Note CfgTie/TieServ: CfgTie/TieServ,,
*Note CfgTie/TieShadow: CfgTie/TieShadow,,  *Note CfgTie/TieUser:
CfgTie/TieUser,

Cavaets
=======

   Much of the information is cached and the file is updated at the end.
The `named' process will sent the `SIGHUP' signal to restart and reload the
configuration files.

   The reverse name file can not be automatically created... Only modified.

   The SOA records in the named configuration files are not easy to change.

   Changing the file name or directory currently does not move the files
in the file system

Author
======

   Randall Maas (`randym@acm.org' in this node)


File: pm.info,  Node: CfgTie/TieNet,  Next: CfgTie/TiePh,  Prev: CfgTie/TieNamed,  Up: Module List

A module to tie in the net database
***********************************

NAME
====

   CfgTie::TieNet - A module to tie in the net database

SYNOPSIS
========

     tie %net,'CfgTie::TieNet'

DESCRIPTION
===========

   This is a straightforward hash tie that allows us to access the net
database sanely.

Ties
----

   There are two ties available for programmers:

`tie %net,'CfgTie::TieNet''
     `$net{$name}' will return a hash reference of the named net
     information

`tie %net_addr,'CfgTIe::TieNet_addr''
     `$net_addr{$addr}' will return a hash reference for the specified
     network address.

Structure of hash
-----------------

   Any given net entry has the following information assoicated with it:

Name
     net name

Aliases
     A list reference for other names for this net

`AddrType'
     The type of address

Addr
     The address

   Additionally, the programmer can set any other associated key, but this
information will only available to the running Perl script.

See Also
========

   *Note CfgTie/Cfgfile: CfgTie/Cfgfile,, *Note CfgTie/TieAliases:
CfgTie/TieAliases,, *Note CfgTie/TieGeneric: CfgTie/TieGeneric,, *Note
CfgTie/TieGroup: CfgTie/TieGroup,, *Note CfgTie/TieHost: CfgTie/TieHost,,
 *Note CfgTie/TieNamed: CfgTie/TieNamed,,   *Note CfgTie/TiePh:
CfgTie/TiePh,, *Note CfgTie/TieProto: CfgTie/TieProto,,   *Note
CfgTie/TieServ: CfgTie/TieServ,,    *Note CfgTie/TieShadow:
CfgTie/TieShadow,, *Note CfgTie/TieUser: CfgTie/TieUser,

Caveats
=======

   The current version does cache some net information.

Author
======

   Randall Maas (`randym@acm.org' in this node)


File: pm.info,  Node: CfgTie/TiePh,  Next: CfgTie/TieProto,  Prev: CfgTie/TieNet,  Up: Module List

a ph phonebook server configuration tool
****************************************

NAME
====

   `CfgTie::TiePh' - a ph phonebook server configuration tool

SYNOPSIS
========

   Makes it easy to manage the ph phonebook server configuration files as
a hash.

     tie %myhash, 'ph'

     %myhash{who}->{Person}

DESCRIPTION
===========

   This is a file to help configure the `ph' program.

     tie %myhash, 'ph'

     %myhash{who}->{Person}
     %myhash{who}->{Phone}

Methods
-------

   This inherits any methods from the `CfgTie::Cfgfile' module (*Note
CfgTie/Cfgfile: CfgTie/Cfgfile,)

See Also
========

   *Note CfgTie/Cfgfile: CfgTie/Cfgfile,,   *Note CfgTie/TieAliases:
CfgTie/TieAliases,, *Note CfgTie/TieGeneric: CfgTie/TieGeneric,, *Note
CfgTie/TieGroup: CfgTie/TieGroup,,  *Note CfgTie/TieHost: CfgTie/TieHost,,
  *Note CfgTie/TieMTab: CfgTie/TieMTab,, *Note CfgTie/TieNamed:
CfgTie/TieNamed,,  *Note CfgTie/TieNet: CfgTie/TieNet,,     *Note
CfgTie/TiePh: CfgTie/TiePh,, *Note CfgTie/TieProto: CfgTie/TieProto,,
*Note CfgTie/TieRCService: CfgTie/TieRCService,, *Note CfgTie/TieRsrc:
CfgTie/TieRsrc,, *Note CfgTie/TieServ: CfgTie/TieServ,,   *Note
CfgTie/TieShadow: CfgTie/TieShadow,, *Note CfgTie/TieUser: CfgTie/TieUser,

Author
======

   Randall Maas (`randym@acm.org' in this node, `http:' in this node)


File: pm.info,  Node: CfgTie/TieProto,  Next: CfgTie/TieRCService,  Prev: CfgTie/TiePh,  Up: Module List

Ties the protocol number file to a  PERL hash
*********************************************

NAME
====

   CfgTie::TieProto, CfgTie::TieProto_num - Ties the protocol number file
to a  PERL hash

SYNOPSIS
========

     tie %proto, 'CfgTie::TieProto';
     print $proto{'tcp'};

DESCRIPTION
===========

   This is a straightforward hash tie that allows us to access the protocol
number database sanely.

Ties
----

   There are two ties available for programmers:

`tie %proto,'CfgTie::TieProto''
     `$proto{$name}' will return a hash reference of the named protocol
     information

`tie %proto_num,'CfgTie::TieProto_num''
     `$proto_num{$num}' will return a hash reference for the specified
     protocol number.

Structure of hash
-----------------

   Any given proto entry has the following information assoicated with it:

Name
     proto name

Aliases
     A list reference for other names for this proto

Number
     The protocol number

   Additionally, the programmer can set any other associated key, but this
information will only be available to the running Perl script.

See Also
========

   *Note CfgTie/Cfgfile: CfgTie/Cfgfile,, *Note CfgTie/TieAliases:
CfgTie/TieAliases,, *Note CfgTie/TieGeneric: CfgTie/TieGeneric,, *Note
CfgTie/TieGroup: CfgTie/TieGroup,,   *Note CfgTie/TieHost:
CfgTie/TieHost,, *Note CfgTie/TieNamed: CfgTie/TieNamed,, *Note
CfgTie/TieNet: CfgTie/TieNet,,     *Note CfgTie/TiePh: CfgTie/TiePh,,
*Note CfgTie/TieProto: CfgTie/TieProto,, *Note CfgTie/TieServ:
CfgTie/TieServ,,    *Note CfgTie/TieShadow: CfgTie/TieShadow,,  *Note
CfgTie/TieUser: CfgTie/TieUser,

Caveats
=======

   The current version does cache some proto information.

Author
======

   Randall Maas (`randym@acm.org' in this node)


File: pm.info,  Node: CfgTie/TieRCService,  Next: CfgTie/TieRealm,  Prev: CfgTie/TieProto,  Up: Module List

A module to manage Unix services
********************************

NAME
====

   CfgTie::TieRCService - A module to manage Unix services

SYNOPSIS
========

     my %RC;
     tie %RC, 'CfgTie::TieRCService';

DESCRIPTION
===========

   This is a straightforward interface to the control scripts in
@file{/etc/rc?.d} This package helps manage these system services.  The
tie hash is structured like so:

     {
         $Service_Name => $Service_Ref,
     }

   `$Service_Ref' is a hash reference; the details will be covered in the
next section.  `(tied $Service_Ref)' can also be treated as an object to
control the service.  That is covered in the Service Methods section.

   While fetching from the structure, and deleting services is supported
(and reflected to the system), directly storing new services is not.
Currently the method to do this is:

     (tied %RC)->add('mynewservice');

   This will add the new service (to be managed as well as available) to
the run-levels.  The start and kill scripts will be linked into each
appropriate run-level.  The script should already exist (in the proper
format) in `/etc/rc.d/init.d' or equivalent.

The Service hash reference
--------------------------

     {
        levels   => [],
        defaults => [],
        category => [],
        pid  => $pid,
        path =>,
        description =>,
        start_priority=>,
        stop_priority =>,
     }

   `levels' refers to a list used to determine if the service is present
for a given run-level.  The scope of changes this list is *system-wide*.
It is persistent across boots.  Example:

   my $listref = (tied %{$RC{'atd'}})->levels();

     if ($L < scalar @{$listref} && $listref->[$L])
       {print "present at run level $L\n";}

Service Methods
---------------

   `new($service_name,$path)' path is optional, and may refer either to the
folder containing the relevant control script, or may refer to the control
script itself.

   start  will start the service (if not already started).  The scope of
this action is *system-wide*.  Example: `$Obj-'>start();

   stop will stop the service (if running).  The scope of this action is
*system-wide*.  Example: `$Obj-'>`stop();'

   restart will restart the service, effectively stopping it (if it is
running) and then starting it.  The scope of this action is *system-wide*.
Example: `$Obj-'>`restart();'

   status The scope of this action is limited to a single session.

   reload The scope of this action is *system-wide*.

Caveats
=======

   This can not create a new service start/kill script.  At best this can
only modify an existing one, or link it into the init folders.

BUGS
====

   Requires `/sbin/chkconfig' to work.

Author
======

   Randall Maas (`randym@acm.org' in this node)


File: pm.info,  Node: CfgTie/TieRealm,  Next: CfgTie/TieRsrc,  Prev: CfgTie/TieRCService,  Up: Module List

Ties configuration variables to various HTTP servers
****************************************************

NAME
====

   `CfgTie::TieRealm' - Ties configuration variables to various HTTP
servers

SYNOPSIS
========

   Makes it easy to manage a variety of web servers thru one.

Cavaets
=======

   It is not able to modify the main realms configuration file.

Author
======

   Randall Maas (`randym@acm.org' in this node, `http:' in this node)


File: pm.info,  Node: CfgTie/TieRsrc,  Next: CfgTie/TieServ,  Prev: CfgTie/TieRealm,  Up: Module List

an associative array of resources and their usage limits
********************************************************

NAME
====

   CfgTie::TieRsrc - an associative array of resources and their usage
limits

SYNOPSIS
========

   This module makes the resource limits available as a regular hash

     tie %Resources,'CfgTie::TieRsrc'

DESCRIPTION
===========

   This is a straightforward hash tie that allows us to access the user
database sanely.

   The resource limits for the system.  Note: this requires that
`BSD::Resource' be installed.

   It is a hash reference.  The keys may be any of cpu, data, stack,
`core', rss, `memlock', `nproc', `nofile', `open_max', `as', `vmem',
`nlimits', `infinity'.  The values are always list references of the form:

     [$soft, $hard]

See Also
========

   *Note CfgTie/Cfgfile: CfgTie/Cfgfile,, *Note CfgTie/TieAliases:
CfgTie/TieAliases,,  *Note CfgTie/TieGeneric: CfgTie/TieGeneric,, *Note
CfgTie/TieGroup: CfgTie/TieGroup,,*Note CfgTie/TieHost: CfgTie/TieHost,,
 *Note CfgTie/TieMTab: CfgTie/TieMTab,, *Note CfgTie/TieNamed:
CfgTie/TieNamed,,*Note CfgTie/TieNet: CfgTie/TieNet,,      *Note
CfgTie/TiePh: CfgTie/TiePh,, *Note CfgTie/TieProto: CfgTie/TieProto,,*Note
CfgTie/TieRCService: CfgTie/TieRCService,,*Note CfgTie/TieServ:
CfgTie/TieServ,, *Note CfgTie/TieShadow: CfgTie/TieShadow,

Author
======

   Randall Maas (`randym@acm.org' in this node)


File: pm.info,  Node: CfgTie/TieServ,  Next: CfgTie/TieShadow,  Prev: CfgTie/TieRsrc,  Up: Module List

A HASH tie that allows access the service port database
*******************************************************

NAME
====

   CfgTie::TieServ - A HASH tie that allows access the service port
database

SYNOPSIS
========

     tie %serv,'CfgTie::TieServ';
     print $serv{'smtp'};

DESCRIPTION
===========

   This is a straight forward HASH tie that allows us to access the service
port database sanely.

Ties
----

   There are two ties available for programers:

`tie %serv,'CfgTie::TieServ''
     `$serv{$name}' will return a HASH reference of the named service
     information

`tie %serv_port,'CfgTie::TieServ_port''
     `$serv_port{$port}' will return a HASH reference for the specified
     service port.

Structure of hash
-----------------

   Any given serv entry has the following information assoicated with it:

Name
     Service name

Aliases
     A list reference for other names for this service

Port
     The port number

`Protocol'
     The protocol name

   Additionally, the programmer can set any other associated key, but this
information will only available to running PERL script.

See Also
========

   *Note CfgTie/Cfgfile: CfgTie/Cfgfile,,  *Note CfgTie/TieAliases:
CfgTie/TieAliases,, *Note CfgTie/TieGeneric: CfgTie/TieGeneric,, *Note
CfgTie/TieGroup: CfgTie/TieGroup,, *Note CfgTie/TieHost: CfgTie/TieHost,,
*Note CfgTie/TieNamed: CfgTie/TieNamed,, *Note CfgTie/TieNet:
CfgTie/TieNet,, *Note CfgTie/TiePh: CfgTie/TiePh,,     *Note
CfgTie/TieProto: CfgTie/TieProto,, *Note CfgTie/TieShadow:
CfgTie/TieShadow,, *Note CfgTie/TieUser: CfgTie/TieUser,

Cavaets
=======

   The current version does cache some service information.

Author
======

   Randall Maas (`randym@acm.org' in this node)


File: pm.info,  Node: CfgTie/TieShadow,  Next: CfgTie/TieUser,  Prev: CfgTie/TieServ,  Up: Module List

an associative array of user names to password information
**********************************************************

NAME
====

   CfgTie::TieShadow - an associative array of user names to password
information

SYNOPSIS
========

   This module makes the shadow database available as a regular hash.

DESCRIPTION
===========

   This is a straightforward hash tie that allows us to access the shadow
password database sanely.

Ties
----

   This tie is available for programmers:

   `tie %shadow,'CfgTie::TieShadow''

   `$shadow{$name}' will return a hash reference of the named shadow
information

Structure of hash
-----------------

   Any given shadow entry has the following information associated with it
(the keys are case-insensitive):

Name
     Login name

Password
     The encrypted password

Last
     Last time it was changed

`Min'
     The minimum number of days before a change is allowed

`Max'
     Maximum number of days before a change in passwords is required

`Warn'
     The number of days before expiration that they will receive a warning

`Inactive'
     The number of days before an account is inactive

`Expires'
     The date the account expires on

`Inactive'
     The number of days after a password expires that the account is
     considered inactive and expires

   Each of these entries can be modified (even deleted), and they will be
reflected in the overall system.  Additionally, the programmer can set any
other associated key, but this information will only available to the
running Perl script.

Additional Routines
-------------------

`&CfgTie::TieShadow'status()'
`&CfgTie::TieShadow_id'status()'
     Will return stat information on the shadow database.

Miscellaneous
-------------

   `$CfgTie::Tiehadow_rec'usermod' contains the path to the program
`usermod'.  This can be modified as required.

   `$CfgTie::TieShadow_rec'useradd' contains the path to the program
`useradd'.  This can be modified as required.

   `$CfgTie::TieShadow_rec'userdel' contains the path to the program
`userdel'.  This can be modified as required.

Files
=====

   `/etc/passwd' /etc/group `/etc/shadow'

See Also
========

   *Note CfgTie/Cfgfile: CfgTie/Cfgfile,,  *Note CfgTie/TieAliases:
CfgTie/TieAliases,, *Note CfgTie/TieGeneric: CfgTie/TieGeneric,, *Note
CfgTie/TieGroup: CfgTie/TieGroup,, *Note CfgTie/TieHost: CfgTie/TieHost,,
*Note CfgTie/TieNamed: CfgTie/TieNamed,,  *Note CfgTie/TieNet:
CfgTie/TieNet,, *Note CfgTie/TiePh: CfgTie/TiePh,,    *Note
CfgTie/TieProto: CfgTie/TieProto,,  *Note CfgTie/TieServ: CfgTie/TieServ,,
*Note CfgTie/TieShadow: CfgTie/TieShadow,, *Note CfgTie/TieUser:
CfgTie/TieUser,

   `group(5)' in this node, `passwd(5)' in this node, `shadow(5)' in this
node, `usermod(8)' in this node, `useradd(8)' in this node, `userdel(8)'
in this node

Caveats
=======

   The current version does cache some shadow information.

Author
======

   Randall Maas (`randym@acm.org' in this node)


File: pm.info,  Node: CfgTie/TieUser,  Next: CfgTie/filever,  Prev: CfgTie/TieShadow,  Up: Module List

an associative array of user names and ids to information
*********************************************************

NAME
====

   CfgTie::TieUser - an associative array of user names and ids to
information

SYNOPSIS
========

   makes the user database available as a regular hash.

     tie %user,'CfgTie::TieUser'
     print "randym's full name: ", $user{'randym'}->{gcos}, "\n";

DESCRIPTION
===========

   This is a straightforward hash tie that allows us to access the user
database sanely.

   It cross ties with the groups packages and the mail packages

Ties
----

   There are two ties available for programmers:

`tie %user,'CfgTie::TieUser''
     `$user{$name}' will return a hash reference of the named user
     information.

`tie %user_id,'CfgTie::TieUser_id''
     `$user_id{$id}' will return a hash reference for the specified user.

Structure of hash
-----------------

   Any given user entry has the following information associated with it
(the keys are case-insensitive):

Name
     Login name

`GroupId'
     The principle group the user belongs to.

Id
     The user id number that they have been assigned.  It is possible for
     many different user names to be given the same id.  However, changing
     the id for the user (i.e., setting it to a new one) has one of two
     effects.  If `user'Chg_FS' is set 1, then all the files in the system
     owned by that id will changed to the new id in addition to changing
     the id in the system table.  Otherwise, only the system table will be
     modified.

Comment
`Home'
     The user's home folder

`LOGIN_Last'
     This is the information from the last time the user logged in.  It is
     an array reference to data like:

          [$time, $line, $from_host]

Shell
     The user's shell

`AuthMethod'
     The authentication method if other than the default.  (Note: This can
     be set, but currently can't get fetched.)

`ExpireDate'
     The date the account expires on.  (Note: this can be set, but
     currently can't be fetched.)

`Inactive'
     The number of days after a password expires.  (Note: this can be set,
     but currently can't be fetched.)

`Priority'
     The scheduling priority for that user.  (Note: this requires that
     `BSD::Resource' be installed.)

Quota
`RUsage'
     The process resource consumption by the user.  Note: This requires
     that `BSD::Resource' be installed.

     Returns a list reference of the form:

          [$usertime, $systemtime, $maxrss,  $ixrss,   $idrss,  $isrss,  $minflt,
           $majflt,   $nswap,      $inblock, $oublock, $msgsnd, $msgrcv, $nsignals,
           $nvcsw, $nivcsw]

   Plus two (probably) obsolete fields:

Password
     This is the encrypted password, but will probably be obsolete.

`GCOS'
     *General Electric Comprehensive Operating System* or *General
     Comprehensive Operating System* field

     This is now the user's full name under many Unix's, incl. Linux.

   Each of these entries can be modified (even deleted), and they will be
reflected in the overall system.  Additionally, the programmer can set any
other associated key, but this information will only be available to the
running Perl script.

Configuration Variables
-----------------------

Additional Routines
-------------------

`&CfgTie::TieUser'stat()'
`&CfgTie::TieUser_id'stat()'
     Will return stat-like statistics information on the user database.

Adding or overiding methods for user records
--------------------------------------------

   Lets say you wanted to change the default HTML handling to a different
method.  To do this you need only include code like the following:

     package CfgTie::TieUser_rec;
     sub HTML($)
     {
        my $self=shift;
        "<h1>".$Self->{name}."</h1>\n".
        "<table border=0><tr><th align=right>\n".
          join("</td></tr>\n<tr><th align=right>",
            map {$_."</th><td>".$self->{$_}} (sort keys %{$self})
         </td></tr><lt></table>C<\n>";
     }

   If, instead, you wanted to add your own keys to the user records,
`CfgTie::TieUser::add_scalar('*$Name*,*$Package*) Lets you add scalar keys
to user records.  The Name specifies the key name to be used; it will be
made case-insensitve.  The Package specifies the name of the package to be
used when tie'ing the key to a value.  (The TIESCALAR is passed the user
id as a parameter).

   `CfgTie::TieUser::add_hash('*$Name*,*$Package*) Lets you add hash keys
to user records.  The Name specifies the key name to be used; it will be
made case insensitve.  The Package specifies the name of the package to be
used when tie'ing the key to a value.  (The TIEHASH is passed the user id
as a parameter).

Miscellaneous
-------------

   `$CfgTie::TieUser_rec'usermod' contains the path to the program
`usermod'.  This can be modified as required.

   `$CfgTie::TieUser_rec'useradd' contains the path to the program
`useradd'.  This can be modified as required.

   `$CfgTie::TieUser_rec'userdel' contains the path to the program
`userdel'.  This can be modified as required.

   Not all keys are supported on all systems.

   This may transparently use a shadow tie in the future.

When the changes are reflected to /etc/passwd
---------------------------------------------

Files
=====

   `/etc/passwd' /etc/group `/etc/shadow'

See Also
========

   *Note CfgTie/Cfgfile: CfgTie/Cfgfile,, *Note CfgTie/TieAliases:
CfgTie/TieAliases,,  *Note CfgTie/TieGeneric: CfgTie/TieGeneric,, *Note
CfgTie/TieGroup: CfgTie/TieGroup,,*Note CfgTie/TieHost: CfgTie/TieHost,,
 *Note CfgTie/TieMTab: CfgTie/TieMTab,, *Note CfgTie/TieNamed:
CfgTie/TieNamed,,*Note CfgTie/TieNet: CfgTie/TieNet,,      *Note
CfgTie/TiePh: CfgTie/TiePh,, *Note CfgTie/TieProto: CfgTie/TieProto,,*Note
CfgTie/TieRCService: CfgTie/TieRCService,,*Note CfgTie/TieRsrc:
CfgTie/TieRsrc,, *Note CfgTie/TieServ: CfgTie/TieServ,, *Note
CfgTie/TieShadow: CfgTie/TieShadow,

   `group(5)' in this node, `passwd(5)' in this node, `shadow(5)' in this
node, `usermod(8)' in this node, `useradd(8)' in this node, `userdel(8)'
in this node

Caveats
=======

   The current version does cache some user information.

Author
======

   Randall Maas (`randym@acm.org' in this node)


File: pm.info,  Node: CfgTie/filever,  Next: Chart,  Prev: CfgTie/TieUser,  Up: Module List

a simple module for substituting newer versions into a file system.
*******************************************************************

NAME
====

   CfgTie::filever - a simple module for substituting newer versions into
a file system.

SYNOPSIS
========

   This module allows a newer version of file to be safely placed into the
file system.

DESCRIPTION
===========

   This is a set of utilities for manipulating files.

`File's_Rotate' (*$Old, $New*)
------------------------------

   This is the file space equivalent to the variable exchange or swap.  The
old file will be renamed (with a .old extension) and the new file will be
renamed to old.  This is extremely useful for many semi-critical
functions, where modifying the file directly will cause unpredictable
results.  Instead, the preferred method is to modify old sending the
results to new in the background and then doing a *very* quick switcheroo.

   It preserves the permissions and ownership of the original file.

   If this routine fails, it will make an attempt to restore things to
their original state and return.

   *Return Value*: 0 on success, -1 on error;

`Roll('path,depth,*sep*)
------------------------

   This convert the specified files into a backup file (the original file
is renamed, so you had better have something to put there).

Depth
     (optional) Controlls the number of backup copies

Sep
     (optional) Controlls the seperator between the main name and the
     backup number

   The defaults for depth and *sep* are controlled by following two
variables in the package:

`RollDepth'
     Controlls the number of of older versions that are kept around as
     backup copies.  *[Default: 4]*

`RollSep'
     Controls the separator between the file name and the backup number.
     *[Default: *`~']

`RCS_path ('*RCSObj*,path)
--------------------------

   For the given RCS object, this sets the working directory and the file.

find_by_user
------------

   This function attempts to locate all of the files in the system that
are owned by the specified users.  It takes the following parameters:

Base
     Base can be a string to the base path or a reference to a list of base
     paths to search.

   Return Value:

undef if there was an error
otherwise the list of file that matched
Author
======

   Randall Maas (`randym@acm.org' in this node, `http:' in this node)


File: pm.info,  Node: Chart,  Next: Chart/Graph,  Prev: CfgTie/filever,  Up: Module List

a series of charting modules
****************************

NAME
====

   Chart - a series of charting modules

SYNOPSIS
========

     use Chart::type;

     $obj = Chart::type->new;
     $obj = Chart::type->new ( $gif_width, $gif_height );
     
     $obj->set ( $key_1, $val_1, ... ,$key_n, $val_n );
     $obj->set ( $key_1 => $val_1,
     	        ...
     	        $key_n => $val_n );
     $obj->set ( %hash );

     # GIFgraph.pm-style API
     @data = ( \@x_tick_labels, \@dataset1, ... , \@dataset_n );
     $obj->gif ( "filename", \@data );
     $obj->gif ( $filehandle, \@data );
     $obj->gif ( FILEHANDLE, \@data );
     $obj->cgi_gif ( \@data );

     # Graph.pm-style API
     $obj->add_pt ($label, $val_1, ... , $val_n);
     $obj->add_dataset ($val_1, ... , $val_n);
     $obj->gif ( "filename" );
     $obj->gif ( $filehandle );
     $obj->gif ( FILEHANDLE );
     $obj->cgi_gif ();

     # Retrieve imagemap information
     $obj->set ( 'imagemap' => 'true' );
     $imagemap_ref = $obj->imagemap_dump ();

DESCRIPTION
===========

   This module is an attempt to build a general purpose graphing module
that is easily modified and expanded.  I borrowed most of the API from
Martien Verbruggen's GIFgraph module.  I liked most of GIFgraph, but I
thought it was to difficult to modify, and it was missing a few things
that I needed, most notably legends.  So I decided to write a new module
from scratch, and I've designed it from the bottom up to be easy to
modify.  Like GIFgraph, Chart uses Lincoln Stein's GD module for all of
its graphics primitives calls.

use-ing Chart
-------------

   Okay, so you caught me.  There's really no Chart::type module.  All of
the different chart types (Points, Lines, Bars, LinesPoints, Pie,
Composite, StackedBars, and Pareto so far) are classes by themselves, each
inheriting a bunch of methods from the Chart::Base class.  Simply replace
the word type with the type of chart you want and you're on your way.  For
example,

   use Chart::Lines;

   would invoke the lines module.

Getting an object
-----------------

   The new method can either be called without arguments, in which case it
returns an object with the default image size (400x300 pixels), or you can
specify the width and height of the image.  Just remember to replace type
with the type of graph you want.  For example,

     $obj = Chart::Bars (600,400);

   would return a Chart::Bars object containing a 600x400 pixel image.
New also initializes most of the default variables, which you can
subsequently change with the set method.

Setting different options
-------------------------

   This is where the fun begins.  Set looks for a hash of keys and values.
You can pass it a hash that you've already constructed, like

     %hash = ('title' => 'Foo Bar');
     $obj->set (%hash);
     
     or you can try just constructing the hash inside the set call, like

     $obj->set ('title' => 'Foo Bar');

   The following are all of the currently supported options:

'transparent'
     Makes the background of the image transparent if set to 'true'.
     Useful for making web page images.  Default is 'false'.

'gif_border'
     Sets the number of pixels used as a border between the graph and the
     edges of the gif.  Defaults to 10.

'graph_border'
     Sets the number of pixels used as a border between the title/labels
     and the actual graph within the gif.  Defaults to 10.

'text_space'
     Sets the amount of space left on the sides of text, to make it more
     readable.  Defaults to 2.

'title'
     Tells GD graph what to use for the title of the graph.  If empty, no
     title is drawn.  It recognizes '\n' as a newline, and acts
     accordingly.  Default is empty.

'sub_title'
     Deprecated, left in for backwards-compatibility.  This option will
     probably be taken out of the next release.

'x_label'
     Tells Chart what to use for the x-axis label.  If empty, no label is
     drawn.  Default is empty.

'y_label', 'y_label2'
     Tells Chart what to use for the y-axis labels.  If empty, no label is
     drawn.  Default is empty.

'legend'
     Specifies the placement of the legend.  Valid values are 'left',
     'right', 'top', 'bottom'.  Setting this to 'none' tells chart not to
     draw a legend.  Default is 'right'.

'legend_labels'
     Sets the values for the labels for the different datasets.  Should be
     assigned a reference to an array of labels.  For example,

     @labels = ('foo', 'bar');   $obj->set ('legend_labels' => \@labels);

     Default is empty, in which case 'Dataset 1', 'Dataset 2', etc. are
     used as the labels.

     For a pareto graph, the first value should be the name of the set, and
     the second should be the name of the running sum of the values.

     For a pie graph, this option is ignored, as the values for the legend
     are taken from the array of data point labels.

'tick_len'
     Sets the length of the x- and y-ticks in pixels.  Default is 4.

'x_ticks'
     Specifies how to draw the x-tick labels.  Valid values are 'normal',
     'staggered' (staggers the labels vertically), and 'vertical' (the
     labels are draw upwards).  Default is 'normal'.

'y_ticks'
     Sets the number of y_ticks to draw.  Default is 6.

'max_val'
     Sets the maximum y-value on the graph, overriding the normal
     auto-scaling.  Default is undef.

'min_val'
     Sets the minimum y-value on the graph, overriding the normal
     auto-scaling.  Default is undef.

'pt_size'
     Sets the radius of the points (for Chart::Points, etc.) in pixels.
     Default is 18.

'brush_size'
     Sets the width of the lines (for Chart::Lines, etc.) in pixels.
     Default is 6.

'skip_x_ticks'
     Sets the number of x-ticks and x-tick labels to skip.  (ie.  if
     'skip_x_ticks' was set to 4, Chart would draw every 4th x-tick and
     x-tick label).  Default is undef.

'custom_x_ticks'
     Used in points, lines, linespoints, and bars charts, this option
     allows you to specify exatly which x-ticks and x-tick labels should
     be drawn.  It should be assigned a reference to an array of desired
     ticks.  Just remember that I'm counting from the 0th element of the
     array.  (ie., if 'custom_x_ticks' is assigned [0,3,4], then the 0th,
     3rd, and 4th x-ticks will be displayed)

'colors'
     This option lets you control the colors the chart will use.  It takes
     a reference to a hash.  The hash should contain keys mapped to
     references to arrays of rgb values.  For instance,

          $obj->set('colors' => {'background' => [255,255,255]});

     sets the background color to white (which is the default).  Valid
     keys for this hash are

          'background' (background color for the gif)
          'text' (all the text in the chart)
          'y_label' (color of the first y axis label)
          'y_label2' (color of the second y axis label)
          'grid_lines' (color of the grid lines)
          'x_grid_lines' (color of the x grid lines - for x axis ticks)
          'y_grid_lines' (color of the y grid lines - for to left y axis ticks)
          'y2_grid_lines' (color of the y2 grid lines - for right y axis ticks)
          'dataset0'..'dataset15' (the different datasets)
          'misc' (everything else, ie. ticks, box around the legend)

     NB. For composite charts, there is a limit of 8 datasets per
     component.  The colors for 'dataset8' through 'dataset15' become the
     colors for 'dataset0' through 'dataset7' for the second component
     chart.

'grey_background'
     Puts a nice soft grey background on the actual data plot when set to
     'true'.  Default is 'true'.

'grid_lines'
     Draws grid lines matching up to x and y ticks

'spaced_bars'
     Leaves space between the groups of bars at each data point when set
     to 'true'.  This just makes it easier to read a bar chart.  Default
     is 'true'.

'imagemap'
     Lets Chart know you're going to ask for information about the
     placement of the data for use in creating an image map from the gif.
     This information can be retrieved using the imagemap_dump() method.
     NB. that the imagemap_dump() method cannot be called until after the
     Chart has been generated (ie. using the gif() or cgi_gif() methods).

'sort'
     Tells Chart to sort the data before plotting it.  Can be assigned an
     order ('asc' or 'desc' for ascending and descending, respectively),
     in which case it sorts numerically.  Or it can also be assigned an
     array reference.  The array reference should contain 3 elements:  the
     order in which to search (as above), which dataset to use (remember
     that 0 is the x-tick labels), and the type of sort to do ('alpha' or
     'num' for alphabetical or numerical sorts, respectively).  For
     example,

          $obj->set ('sort' => ['asc', 2, 'num']);

     would sort the data numerically in ascending order, sorting by the
     third dataset (second if you don't count the x-tick labels).  Note
     that

          $obj->set ('sort' => ['asc', 0, 'alpha']);

     will sort the data in ascending alphabetical order by the x-tick
     labels.  Defualts to undef, normally, and 'desc' for pareto.

'nosort'
     Turns off the default sort for pareto graphs.  Default is undef.

'cutoff'
     Only used for pareto charts, this option determines where the cut-off
     point is.  It then lumps everything after the highest 'cutoff' data
     points into an 'Other' entry on the chart.  Default is 5.

'nocutoff'
     Turns off the default 'cutoff' feature of pareto graphs.  Defaut is
     undef.

'composite_info'
     This option is only used for composite charts.  It contains the
     information about which types to use for the two component charts,
     and which datasets belonf to which component chart.  It should be a
     reference to an array of array references, containing information
     like the following

          $obj->set ('composite_info' => [ ['Bars', [1,2]],
          				 ['Lines', [3,4] ]);

     This example would set the two component charts to be a bar chart and
     a line chart.  It would use the first two data sets for the bar chart
     (note that the numbering starts at 1, not zero like most of the other
     numbered things in Chart), and the second two data sets for the line
     chart.  The default is undef.

     NB. Chart::Composite can only do two component charts.

'min_val1', 'min_val2'
     Only for composite charts, these options specify the minimum y-value
     for the first and second components respectively.  Both default to
     undef.

'max_val1', 'max_val2'
     Only for composite charts, these options specify the maximum y-value
     for the first and second components respectively.  Both default to
     undef.

'ylabel2'
     The label for the right y-axis (the second component chart) on a
     composite chart.  Default is undef.

'yticks1', 'y_ticks2'
     The number of y ticks to use on the first and second y-axis on a
     composite chart.  Please note that if you just set the 'y_ticks'
     option, both axes will use that number of y ticks.  Both default to
     undef.

'same_y_axes'
     Forces both component charts in a composite chart to use the same
     maximum and minimum y-values if set to 'true'.  This helps to keep
     the composite charts from being too confusing.  Default is undef.

'no_cache'
     Adds Pragma: no-cache to the http header.  Be careful with this one,
     as Netscape 4.5 is unfriendly with POST using this method.

GIFgraph.pm-style API
---------------------

Sending the image to a file
     Invoking the gif method causes the graph to be plotted and saved to a
     file.  It takes the name of the output file and a reference to the
     data as arguments.  For example,

          $obj->gif ("foo.gif", \@data);

     would plot the data in @data, and the save the image to foo.gif.  Of
     course, this then beggars the question "What should @data look
     like?".  Well, just like GIFgraph, @data should contain references to
     arrays of data, with the first array reference pointing to an array
     of x-tick labels.  For example,

          @data = ( [ 'foo', 'bar', 'junk' ],
          	    [ 30.2,  23.5,  92.1   ] );

     would set up a graph with one dataset, and three data points in that
     set.  In general, the @data array should look something like

          @data = ( \@x_tick_labels, \@dataset1, ... , \@dataset_n );

     And no worries, I make my own internal copy of the data, so that it
     doesn't mess with yours.

CGI and Chart
     Okay, so you're probably thinking, "Do I always have to save these
     images to disk?  What if I want to use Chart to create dynamic images
     for my web site?"  Well, here's the answer to that.

          $obj->cgi_gif ( \@data );

     The cgi_gif method will print the chart, along with the appropriate
     http header, to stdout, allowing you to call chart-generating scripts
     directly from your html pages (ie. with a <img src=image.pl> HTML
     tag).  The @data array should be set up the same way as for the
     normal gif method.

Graph.pm-style API
------------------

   You might ask, "But what if I just want to add a few points to the
graph, and then display it, without all those references to references?".
Well, friend, the solution is simple.  Borrowing the add_pt idea from Matt
Kruse's Graph module, you simply make a few calls to the add_pt method,
like so:

     $obj->add_pt ('foo', 30, 25);
     $obj->add_pt ('bar', 16, 32);

   Or, if you want to be able to add entire datasets, simply use the
add_dataset method:

     $obj->add_dataset ('foo', 'bar');
     $obj->add_dataset (30, 16);
     $obj->add_dataset (25, 32);

   These methods check to make sure that the points and datasets you are
adding are the same size as the ones already there.  So, if you have two
datasets currently stored, and try to add a data point with three
different values, it will carp (per the Carp module) an error message.
Similarly, if you try to add a dataset with 4 data points, and all the
other datasets have 3 data points, it will carp an error message.

   Don't forget, when using this API, that I treat the first dataset as a
series of x-tick labels.  So, in the above examples, the graph would have
two x-ticks, labeled 'foo' and 'bar', each with two data points.

Clearing the data
     A simple call to the clear_data method empties any values that may
     have been entered.

          $obj->clear_data ();

Getting a copy of the data
     If you want a copy of the data that has been added so far, make a call
     to the get_data method like so:

          $dataref = $obj->get_data;

     It returns (you guessed it!) a reference to an array of references to
     datasets.  So the x-tick labels would be stored as

          @x_labels = @{$dataref->[0]};

Sending the image to a file
     If you just want to print this chart to a file, all you have to do is
     pass the name of the file to the gif() method.

          $obj->gif ("foo.gif");

Sending the image to a filehandle
     If you want to do something else with the image, you can also pass a
     filehandle (either a typeglob or a FileHandle object) to gif, and it
     will print directly to that.

          $obj->gif ($filehandle);
          $obj->gif (FILEHANDLE);

CGI and Chart
     Okay, so you're probably thinking (again), "Do I always have to save
     these images to disk?  What if I want to use Chart to create dynamic
     images for my web site?"  Well, here's the answer to that.

          $obj->cgi_gif ();

     The cgi_gif method will print the chart, along with the appropriate
     http header, to stdout, allowing you to call chart-generating scripts
     directly from your html pages (ie. with a <img src=image.pl> HTML
     tag).

Imagemap Support
----------------

   Chart can also return the pixel positioning information so that you can
create image maps from the gifs Chart generates.  Simply set the 'imagemap'
option to 'true' before you generate the gif, then call the imagemap_dump()
method afterwards to retrieve the information.  You will be returned a
data structure almost identical to the @data array described above to pass
the data into Chart.

     $imagemap_data = $obj->imagemap_dump ();

   Instead of single data values, you will be passed references to arrays
of pixel information.  For Bars and StackedBars charts, the arrays will
contain two x-y pairs (specifying the upper left and lower right corner of
the bar), like so

     ( $x1, $y1, $x2, $y2 ) = @{ $imagemap_data->[$dataset][$datapoint] };

   For Lines, Points, and LinesPoints, the arrays will contain a single
x-y pair (specifying the center of the point), like so

     ( $x, $y ) = @{ $imagemap_data->[$dataset][$datapoint] };

   A few caveats apply here.  First of all, GD treats the upper-left corner
of the gif as the (0,0) point, so positive y values are measured from the
top of the gif, not the bottom.  Second, these values will most likely
contain long decimal values.  GD, of course, has to truncate these to
single pixel values.  Since I don't know how GD does it, I can't truncate
it the same way he does.  In a worst-case scenario, this will result in an
error of one pixel on your imagemap.  If this is really an issue, your
only option is to either experiment with it, or to contact Lincoln Stein
and ask him.  Third, please remember that the 0th dataset will be empty,
since that's the place in the @data array for the data point labels.

TO DO
=====

   * Numeric x-axes.

   * Add some 3-D graphs.

BUGS
====

   Probably quite a few, since it's been completely rewritten.  As usual,
please mail me with any bugs, patches, suggestions, comments, flames,
death threats, etc.

AUTHOR
======

   David Bonner (dbonner@cs.bu.edu)

MAINTAINER
==========

   Peter Clark (ninjaz@webexpress.com)

COPYRIGHT
=========

   Copyright(c) 1997-1998 by David Bonner, 1999 by Peter Clark All rights
reserved.  This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.


