#!/bin/sh

#++
# NAME
#	postfix-wrapper 1
# SUMMARY
#	trivial but useful multi-instance manager
# SYNOPSIS
#	postfix command
# DESCRIPTION
#	Postfix versions 2.6 and later provide support for multiple
#	Postfix instances. Instances share executable files and
#	documentation, but have their own directories for configuration,
#	queue and data files. In many cases different instances
#	have different myhostname and inet_interfaces settings,
#	though this is not always necessary.
#
#	This command implements a trivial Postfix multi-instance
#	manager. It simply applies commands such as "postfix start"
#	to all the applicable Postfix instances.
# MANAGING MULTIPLE INSTANCES
# .ad
# .fi
#	To hook the postfix-wrapper multi-instance manager into
#	Postfix, see the POSTFIX-WRAPPER INITIALIZATION section
#	below.  To create a new Postfix instance, see the CREATING
#	A NEW POSTFIX INSTANCE section below.
#
#	To start, stop, get status, etc., with multiple Postfix
#	instances, use:
#
# .nf
#	    # postfix command
# .fi
#
#	For example, to find out what Postfix instances are configured:
#
# .nf
#	    # postfix status
# .fi
#
#	The postfix(1) command invokes the postfix-wrapper command.
#	This in turn applies the postfix(1) command to the default
#	Postfix instance, and to each instance specified with the
#	default main.cf file's multi_instance_directories parameter
#	value.
#
#	The postfix-wrapper command will start, stop, reload, etc.,
#	only Postfix instances that have "multi_instance_enable =
#	yes" in their main.cf files.  When an instance is disabled,
#	postfix-wrapper replaces "start" commands by "check" so
#	that problems will still be reported.
#
#	The startup order is taken from the multi_instance_directories
#	parameter; the default instance is prepended to the list.
#	The startup order is used for all postfix(1) commands,
#	except for commands that stop Postfix instances. In those
#	cases the order is reversed.
# MANAGING INDIVIDUAL INSTANCES
# .ad
# .fi
#	To manage an individual Postfix instance, use:
#
# .nf
#	    # postfix -c /path/to/config_directory command
# .fi
#
#	This is also needed to manage the default Postfix instance,
#	after you turn on multi-instance support.
#
#	To use the Postfix sendmail command with a non-default
#	Postfix instance, use:
#
# .nf
#	    # sendmail -C /path/to/config_directory ...
# .fi
#
#	Note 1: that's capital C, not lower-case c.
#
#	Note 2: only the default Postfix instance will check or
#	update the shared Postfix files, including the executable
#	files and documentation.
# POSTFIX-WRAPPER INITIALIZATION
# .ad
# .fi
#	To hook this program into Postfix, execute the command
#	shown below.
#
#	This command should be entered as one line.
#
#	In the example, replace /etc/postfix with the default Postfix
#	configuration directory, and replace /usr/libexec/postfix
#	with the daemon directory pathname of the default Postfix
#	instance.
#
# .nf
#	    # postconf -c /etc/postfix -e
#		"multi_instance_enable=yes"
#		"multi_instance_wrapper=/usr/libexec/postfix/postfix-wrapper"
# .fi
# CREATING A NEW POSTFIX INSTANCE
# .ad
# .fi
#	To create a Postfix instance called "postfix-test", start
#	with generic main.cf and master.cf files and customize the
#	locations of the queue and data directories with the commands
#	shown below.  The last command updates main.cf and creates
#	any directories that Postfix will need.
#
#	Each command below should be entered as one line.
#
#	In the example, replace /etc/postfix with the default Postfix
#	configuration directory, and replace /usr/libexec/postfix
#	with the daemon directory pathname of the default Postfix
#	instance.
#
# .nf
#	    # mkdir /etc/postfix-test
#	    # cp /usr/libexec/postfix/main.cf /etc/postfix-test
#	    # cp /usr/libexec/postfix/master.cf /etc/postfix-test
#	    # postconf -c /etc/postfix-test -e 
#		"multi_instance_name=postfix-test"
#	    # postfix -c /etc/postfix post-install
#		"config_directory=/etc/postfix-test"
#		"queue_directory=/var/spool/postfix-test"
#		"data_directory=/var/lib/postfix-test"
#		create-missing
# .fi
#
#	Register this Postfix instance with the default instance.
#	This command should be entered as one line.
#
# .nf
#	    # postconf -e "multi_instance_directories=`postconf
#		-h multi_instance_directories` /etc/postfix-test"
# .fi
#
#	Edit the myhostname and inet_interfaces main.cf parameters,
#	so that they will not conflict with the default Postfix
#	instance, and change whatever else needs to be changed.
#
#	Test the instance with:
#
# .nf
#	    # postfix -c /etc/postfix-test start
#	    # postfix -c /etc/postfix-test status
#	    [ other tests ... ]
# .fi
#
#	When everything is working satisfactorily, enable start/stop/etc.
#	by the multi-instance manager:
#
# .nf
#	    # postconf -c /etc/postfix-test -e multi_instance_enable=yes
# DIAGNOSTICS
# .ad
# .fi
#	When an operation fails, the affected Postfix instance logs
#	a message, and the multi-instance manager skips to the next
#	instance.
# BUGS
#	Support for the multi_instance_group feature is not implemented.
# SEE ALSO
#	postfix(1) Postfix control program
#	postfix-wrapper(5) multi-instance manager API
#	postmulti(1) full-blown multi-instance manager
# LICENSE
# .ad
# .fi
#	The Secure Mailer license must be distributed with this software.
# AUTHOR(S)
#	Wietse Venema
#	IBM T.J. Watson Research
#	P.O. Box 704
#	Yorktown Heights, NY 10598, USA
#--

# Sanity checks.

: ${command_directory?"do not invoke this command directly"}
: ${daemon_directory?"do not invoke this command directly"}

# Readability.

POSTCONF=$command_directory/postconf
POSTFIX=$command_directory/postfix

# Canonicalize the instance directory list. The list is specified
# in startup order.

instance_dirs=`$POSTCONF -h multi_instance_directories | sed 's/,/ /'` ||
    exit 1

case "$1" in
  stop|quick-stop|abort|drain)
	all_dirs=
	for dir in $config_directory $instance_dirs
	do
	    all_dirs="$dir $all_dirs"
	done;;
     *) all_dirs="$config_directory $instance_dirs";;
esac

# Execute the command on all applicable instances. When a Postfix
# instance is disabled, replace "postfix start" by "postfix check"
# so that problems will still be reported.

err=0
for dir in $all_dirs
do
    case "$1" in
    start)
	test "`$POSTCONF -c $dir -h multi_instance_enable`" = yes || {
	    $POSTFIX -c $dir check || err=$?
	    continue
	};;
    stop|abort|drain|flush|reload)
	test "`$POSTCONF -c $dir -h multi_instance_enable`" = yes ||
	    continue;;
    esac
    $POSTFIX -c $dir "$@" || err=$?
done

exit $err
