# TLB (List Batcher) config file -*- perl -*- 
# This is a list of all variables set by TLB for your use in the config
# file, and all variables which are used by TLB.  You are free to set other
# variables without fear of conflicts with the main program.

# The following variables are set depending on the command line:
# $opt_a, $opt_b, $opt_c: These are flags; they are either undefined, or 1
#  if the flag is specified on the command line.  For instance, if -a is
#  given, $opt_a == 1.
# $opt_x, $opt_y, $opt_z: these are options corresponding to -x, -y, and
#  -z.  They take arguments, and may be used for any purpose you wish.
# $opt_l: if given on the command line, the argument to this option is used
#  to set the variable $list_name for use in the log output and in
#  initializing certain defaults.

# Set this to anything to prevent the sending of any mail just in case you
# forget to specify -d256
# You _MUST_ turn this off (comment out the line) for normal operation.
$send_no_mail = 1;

# The file containing the address list
$address_file = "/path/to/address-list";

# The address list has already been stripped.  If you keep your list of
# address already stripped of comments (see the mungelist command included
# with TLB), you can save the expensive stripping process by setting this
# variable.  If you set this and your addresses are not stripped, things
# will break quite badly.  At the minimum, sorting will not work and every
# unstripped address will bounce with an error from the delivering host, so
# be careful.
#$stripped_address_list = 1;

# The address list is already sorted.  If you keep your list of address
# pre-sorted in reverse-domain order (see the mungelist command included
# with TLB), you can save the possibly expensive sorting process by setting
# this variable.  If you set this and your address list is not sorted,
# domain-based batching methods will not work well for the addresses that
# are out of order.  This has little effect for some batch methods; see the
# nosort tag in the delivery matrix below for more information and
# finer-grained control.
#$sorted_address_list = 1;

# The host we're running on.  The default is the value returned by the perl
# hostfqdn() function.
#$local_hostname = "big.host.com";

# The value of the envelope sender.  This is the address that will appear
# in the UNIX From_ header, and the address to which comforming mail
# transfer agents will send bounces to.
# Remember to quote the `@' symbol.
# The default is owner-$address_file@$local_hostname
#$sender = "owner-list\@big.host.com";

# The program (with arguments) to call to make LOCAL deliveries.  See the
# delivery matrix below.
$mailer = "/usr/sbin/sendmail -bs";

# Should we talk ESMTP to the local mailer?
#$local_ESMTP = 1;

# The directory where we store our temp files.  Defaults to "/tmp".
#$tempdir = "/tmp";

# The level of system logging tat will be done.  Higher numbers will log
# more trivial information.  This defaults to 6.
#$log_level = 6;

# Should we log routines as they are entered, or only as they exit?  Useful for debugging.
#$log_entries = 1;

# The delivery matrix:
#
# This is somewhat complicated if you aren't familiar with complex perl
# data structures.  Pay attention; there will be a quiz at the end.
#
# The delivery matrix maps addresses to destinations.  The basic structure
# is a list of hashes.  Each hash in the list (called a destination)
# consists of a regular expression which matches the addresses that are
# bound for this destination (the default is all addresses), and a series of
# optional parameters.  The parameters are:
#
# hosts:       a list of host definitions (see below)
# minseparate: the minimum number of addresses in the same domain that must
#              be present before those addresses are placed in a separate
#              batch.
# maxdomains:  the maximum number of domains allowed in a single batch
# maxaddrs:    the maximum number of addresses allowed in a single batch
# numbatches:  the number of batches that will be created
# nosort:      the address list for this destination will not be sorted
#              prior to batching.
# fail:        attempts to connect to this host will fail immediately if
#              the proper debuging flag is used (for testing)
#

# If minseparate is present, domains are given separate batches if they
# appear in enough addresses.  Other addresses are batched in batches of
# maxdomains domains; if maxdomains is not specified, the default is 10.
#
# Only one of (maxdomains, maxaddrs, numbatches) is effective; they take
# precedence in the order listed.
#
# If neither of (minseparate, maxdomains, maxaddrs, numbatches) is
# specified, a single batch is assumed.
#
# Currently numbatches splits the address list up evenly across the number
# of batches you desire; it does not take into account multiple addresses
# in the same domain and thus is not as efficient as possible.  If this is
# a problem, let me know and I'll fix it.

# Note that nosort will render maxdomains and minseparate relatively
# useless unless the address list was presorted.  For large address lists,
# presorting should save some time (though this has yet to be measured).
#
# Destinations are matched in order, so if a destination with a blank
# regexp (which defaults to matchine everything) is encountered it will
# consume all addresses and no further destinations will accumulate any
# addresses.  There is an implicit destination specified with
# 'numbatches' => 1 and a host list consisting only of the LOCAL host (see
# below) which will catch any unmatched addresses.  This permits some means
# of backwards compatibility; an empty @destination_matrix will deliver one
# batch of addresses to the default mailer which results in the the same
# system load and list performance as the normal Majordomo behavior.
#
# A host definition is a hash containing the hostname (or IP address,
# command line, or the string 'LOCAL') and the following optional
# parameters:
#
# port:     the SMTP port on this system
# timeout:  the connection timeout; if the host does not accept a connection
#           within this number of seconds it is marked down
# ESMTP:    a flag; does the host speak ESMTP?
# ONEX:     a flag; should we send ONEX to prevent server forking?  (This is
#           Sendmail specific.)
# backup:   a flag; this is a backup host, batches will not be sent to it
#            unless another host in the list is not responding.
#
# Note: if the hostname is set to 'LOCAL', the default mailer program will
# be run on the local host instead of an SMTP connection being opened.  If
# the hostname is set to a string beginning with `/', that string will be
# passed to exec, thus running an alternate command for mail delivery.  The
# command must process SMTP on standard input as Sendmail does.  You can
# use this to specify special Sendmail paramaters like alternate queuing
# directories, or run a completely different program to handle the
# delivery.
#
# To save typing, I recommend that the hosts be defined elsewhere and
# included in the hosts array for each destination as hash references (see
# the example).  This has the advantage that when a host is marked down it
# is considered to be down in all destinations.
#
# If there are multiple batches to be delivered to a hostlist that contains
# more than one non-backup host, the batches will be split evenly between
# the hosts.  This allows not only parallelism in delivery on a single
# host, but parallelism across multiple hosts.
#
# If a host fails to respond or the LOCAL host encounters an error, that
# host will be marked down and all backup hosts for that destination will
# become active.  In this case, batches will be split evenly among all
# responding hosts in the hostlist (backups and otherwise).  The hosts
# marked down will not be consulted again for the duration of the program
# run.

# Here's a host that supports ESMTP and ONEX; it's usually pretty fast so
# we timeout after 20 seconds.
%host1 = (
	  'hostname' => 'host1.corp.com',
	  'port'     => 'smtp',
	  'timeout'  => 20,
	  'ESMTP'    => 1,
	  'ONEX'     => 1,
	 );

# Here's host1 again, but this time it's a backup.  We'll use this in case
# a remote exploder fails to come up.
%backup1 = (
	    'hostname' => 'host1.corp.com',
	    'port'     => 'smtp',
	    'timeout'  => 20,
	    'ESMTP'    => 1,
	    'ONEX'     => 1,
	    'backup'   => 1,
	   );

# Here's a generic host; we take all of the defaults.
%host2 = (
	  'hostname' => 'host2.corp.com',
	 );

# Another host; we use it as a backup.
%host3 = (
	  'hostname' => 'host3.corp.com',
	  'backup'   => 1,
	 );

# Here's a host across the globe; we'll use it to deliver some far-away
# addresses.
%downunder = ('hostname' => 'g.day.mate.au',
	      'ESMTP'    => 1,
	     );

# And another for our Scandinavian friends
%nordland = ('hostname' => 'arctic.air.no');


# Now the big business.  We direct remote addresses off to the special
# destinations and distribute the load between our local hosts for those
# left over.
@delivery_matrix = ( {
		      'regexp'      => 'au$',
		      'hosts'       => [ \%downunder, \%backup1, ],
		      'maxdomains'  => 15,
		     },
		     {
		      'regexp'      => '(no|se|fi)$',
		      # Backups don't have to come at the end
		      'hosts'       => [ \%backup1, \%nordland, ],
		      'numbatches'  => 10, # They prefer that we limit the
                                          # load to ten simultaneous
                                          # processes
		     },
		     {
		      # Here's the default
		      'hosts'       => [ \%host1, \%host2, \%host3, ],
		      'minseparate' => 5,
		      'maxdomains'  => 10,
		     },
		   );

# That's it.  Running TLB with this matrix will: split off the Australian
# addresses and send them in batches of fifteen domains to an exploder in
# Australia, split the Scandanavian addresses into ten total batches and
# send those to a host in Norway, and split the remaining addresses evenly
# between host1 and host2 with domains appearing 5 or more times in
# separate batches and other domains batched in groups of ten.  (Whew.)
# Backup hosts will be used if any of the other hosts do not respond.  If
# the backup hosts do not respond, the LOCAL host, defined by the $mailer
# variable, will be executed and used for delivery.  XXX If that fails,
# currently bad things happen, but we have no other choice.

# External programs:
# 
# TLB can send the message to a set of external programs.  This takes the
# place of the extra items often present in outgoing aliases to do message
# archiving and such.
#
# The insructions telling TLB which commands to run are stored in (again) a
# list of hashes, one hash per external program.  Each has consists of a
# number of parameters:
#
# commandline: the command line that will be exec'd.
# pipemessage: the message will be provided to the command in standard
#              input.  TLB automatically prepends a blank line, as Sendmail
#              does.
# needsfrom: the From_ line, or UNIX mbox separator, will be prepended to
#            the message.  If one was not supplied to TLB when it was
#            invoked, one will be supplied based on the current time and
#            value of the $sender configuration variable.
#
# In addition, the commandline can contain tags which are expanded before
# the program is executed.  These tags are:
#
# =FILE=: the name of the file that contains the message text.  Note that
#         this file will _not_ have the UNIX mbox separator (or From_
#         line) prepended.
#
# Sorry, that's currently all.  If other tags are required I will be happy
# to consider adding them.  Note that the programs are executed with the
# same permissions that TLB was invoked with; this will usually be an
# account without permissions if called from the mailer, or will be the
# majordomo user if called from the Majordomo wrapper or directly from
# resend.

# External programs are disabled by default.
$send_to_externals = 1;

# Pipe the message, with From_ line, to the majordomo archive program, and
# send a copy into a temporary log file.
@external_programs = ( {
			'commandline' => '/usr/local/majordomo/archive2 -a -m
                                          -f /usr/local/archive/list/list',
			'pipemessage' => 1,
			'needsfrom'   => 1,
		       },
		       {
			'commandline' => 'cat __FILE__ >> /tmp/tlblog'
		       }
		     );

#
# Running TLB:
#
# TLB normally takes a single argument, the name of the appropriate config
# file.  In addition to this, two other options can be specified:
#
# -t address 
#   This sends several test messages to address, but uses each host in the
#   matrix (plus the LOCAL host) do deliver them.  This acts as a test the
#   matrix and the ability of each host to deliver non-local mail for you.
#
# -d number
#   Turns on one or more special debugging functions.  The following
#   functions are supported; simply add the ones you want and place the
#   result after the -d flag:
#      1    - address lists before sorting
#      2    - address lists after sorting
#      4    - batches that will be sent to each host, and batch info
#      8    - delivery verbosity (important things, errors))
#      16   - delivery verbosity (less important things, informationals)
#      32   - SMTP transactions excluding the message test
#      64   - The escaped mesage text
#      128  - Open connections, but do not actually send or receive any
#             data.
#      256  - Do not open sockets, and send no data
#      512  - Pay attention to 'fail' tags in hosts descriptions.
#      1024 - Fail all envelope opens (except to LOCAL) with 50%
#             probability
#
# Note that 256 implies 128, that flags 1, 2, and 4 do nothing in the
# presence of -t (the address list is never read), and the $send_no_mail
# variable effectively turns on 256 (and thus 128).  512 and 1024 are for
# internal testing of TLB fallback mechanisms and aren't really useful for
# normal testing (unless you're curious).
#
# Send questions, comments, additions, etc. to tibbs@hpc.uh.edu.

