5 kx #!/bin/sh
5 kx
5 kx # To view the formatted manual page of this file, type:
5 kx # POSTFIXSOURCE/mantools/srctoman - postfix-install | nroff -man
5 kx
5 kx #++
5 kx # NAME
5 kx # postfix-install 1
5 kx # SUMMARY
5 kx # Postfix installation procedure
5 kx # SYNOPSIS
5 kx # sh postfix-install [options] [name=value] ...
5 kx # DESCRIPTION
5 kx # The postfix-install script is to be run from the top-level
5 kx # Postfix source directory. It implements the following operations:
5 kx # .IP o
5 kx # Install or upgrade Postfix from source code. This requires
5 kx # super-user privileges.
5 kx # .IP o
5 kx # Build a package that can be distributed to other systems, in order
5 kx # to install or upgrade Postfix elsewhere. This requires no super-user
5 kx # privileges. To complete the installation after unpacking the
5 kx # package, execute as super-user the post-install script in the Postfix
5 kx # configuration directory.
5 kx # .PP
5 kx # The postfix-install script is controlled by installation parameters.
5 kx # Specific parameters are described at the end of this document.
5 kx #
5 kx # By default, postfix-install asks the user for installation
5 kx # parameter settings. Most settings are stored in the installed
5 kx # main.cf file. Stored settings are used as site-specific defaults
5 kx # when the postfix-install script is run later.
5 kx #
5 kx # The names of Postfix files and directories, as well as their
5 kx # ownerships and permissions, are stored in the postfix-files file
5 kx # in the Postfix configuration directory. This information is used
5 kx # by the post-install script (also in the configuration directory)
5 kx # for creating missing queue directories when Postfix is started,
5 kx # and for setting correct ownership and permissions when Postfix
5 kx # is installed from a pre-built package or from source code.
5 kx #
5 kx # Arguments
5 kx # .IP -keep-build-mtime
5 kx # When installing files preserve new file's mtime timestamps.
5 kx # Otherwise, mtimes will be set to the time that postfix-install
5 kx # is run.
5 kx # .IP -non-interactive
5 kx # Do not ask the user for parameter settings. Installation parameters
5 kx # are specified via one of the non-interactive methods described
5 kx # below.
5 kx # .IP -package
5 kx # Build a ready-to-install package. This requires that a
5 kx # non-default install_root parameter is specified.
5 kx # INSTALLATION PARAMETER INPUT METHODS
5 kx # .ad
5 kx # .fi
5 kx # Parameter settings can be specified through a variety of
5 kx # mechanisms. In order of decreasing precedence these are:
5 kx # .IP "interactive mode"
5 kx # By default, postfix-install will ask the user for installation
5 kx # parameter settings. These settings have the highest precedence.
5 kx # .IP "command line"
5 kx # Parameter settings can be given as name=value arguments on
5 kx # the postfix-install command line. This mode will replace
5 kx # the string MAIL_VERSION at the end of a configuration
5 kx # parameter value with the Postfix release version (Postfix
5 kx # 3.0 and later).
5 kx # .IP "process environment"
5 kx # Parameter settings can be given as name=value environment
5 kx # variables. Environment parameters can also be specified on
5 kx # the make(1) command line as "make install name=value ...".
5 kx # This mode will replace the string MAIL_VERSION at the end
5 kx # of a configuration parameter value with the Postfix release
5 kx # version (Postfix 3.0 and later).
5 kx # .IP "installed configuration files"
5 kx # If a parameter is not specified via the command line or via the
5 kx # process environment, postfix-install will attempt to extract its
5 kx # value from an already installed Postfix main.cf configuration file.
5 kx # .IP "built-in defaults"
5 kx # These settings have the lowest precedence.
5 kx # INSTALLATION PARAMETER DESCRIPTION
5 kx # .ad
5 kx # .fi
5 kx # The description of installation parameters and their built-in
5 kx # default settings is as follows:
5 kx # .IP install_root
5 kx # Prefix that is prepended to the pathnames of installed files.
5 kx # Specify this ONLY when creating pre-built packages for distribution to
5 kx # other systems. The built-in default is "/", the local root directory.
5 kx # This parameter setting is not recorded in the installed main.cf file.
5 kx # .IP tempdir
5 kx # Directory for scratch files while installing Postfix.
5 kx # You must have write permission in this directory.
5 kx # The built-in default directory name is the current directory.
5 kx # This parameter setting is not recorded in the installed main.cf file.
5 kx # .IP config_directory
5 kx # The final destination directory for Postfix configuration files.
5 kx # The built-in default directory name is /etc/postfix.
5 kx # This parameter setting is not recorded in the installed main.cf file
5 kx # and can be changed only by recompiling Postfix.
5 kx # .IP data_directory
5 kx # The final destination directory for Postfix-writable data files such
5 kx # as caches. This directory should not be shared with non-Postfix
5 kx # software. The built-in default directory name is /var/lib/postfix.
5 kx # This parameter setting is recorded in the installed main.cf file.
5 kx # .IP daemon_directory
5 kx # The final destination directory for Postfix daemon programs. This
5 kx # directory should not be in the command search path of any users.
5 kx # The built-in default directory name is /usr/libexec/postfix.
5 kx # This parameter setting is recorded in the installed main.cf file.
5 kx # .IP command_directory
5 kx # The final destination directory for Postfix administrative commands.
5 kx # This directory should be in the command search path of adminstrative
5 kx # users. The built-in default directory name is system dependent.
5 kx # This parameter setting is recorded in the installed main.cf file.
5 kx # .IP html_directory
5 kx # The final destination directory for the Postfix HTML files.
5 kx # This parameter setting is recorded in the installed main.cf file.
5 kx # .IP queue_directory
5 kx # The final destination directory for Postfix queues.
5 kx # The built-in default directory name is /var/spool/postfix.
5 kx # This parameter setting is recorded in the installed main.cf file.
5 kx # .IP sendmail_path
5 kx # The final destination pathname for the Postfix sendmail command.
5 kx # This is the Sendmail-compatible mail posting interface.
5 kx # The built-in default pathname is system dependent.
5 kx # This parameter setting is recorded in the installed main.cf file.
5 kx # .IP newaliases_path
5 kx # The final destination pathname for the Postfix newaliases command.
5 kx # This is the Sendmail-compatible command to build alias databases
5 kx # for the Postfix local delivery agent.
5 kx # The built-in default pathname is system dependent.
5 kx # This parameter setting is recorded in the installed main.cf file.
5 kx # .IP mailq_path
5 kx # The final destination pathname for the Postfix mailq command.
5 kx # This is the Sendmail-compatible command to list the mail queue.
5 kx # The built-in default pathname is system dependent.
5 kx # This parameter setting is recorded in the installed main.cf file.
5 kx # .IP mail_owner
5 kx # The owner of the Postfix queue. Its numerical user ID and group ID
5 kx # must not be used by any other accounts on the system.
5 kx # The built-in default account name is postfix.
5 kx # This parameter setting is recorded in the installed main.cf file.
5 kx # .IP setgid_group
5 kx # The group for mail submission and for queue management commands.
5 kx # Its numerical group ID must not be used by any other accounts on the
5 kx # system, not even by the mail_owner account.
5 kx # The built-in default group name is postdrop.
5 kx # This parameter setting is recorded in the installed main.cf file.
5 kx # .IP manpage_directory
5 kx # The final destination directory for the Postfix on-line manual pages.
5 kx # This parameter setting is recorded in the installed main.cf file.
5 kx # .IP sample_directory
5 kx # The final destination directory for the Postfix sample configuration
5 kx # files. This parameter is obsolete as of Postfix version 2.1.
5 kx # This parameter setting is recorded in the installed main.cf file.
5 kx # .IP meta_directory
5 kx # The final destination directory for non-executable files
5 kx # that are shared among multiple Postfix instances, such
5 kx # as postfix-files, dynamicmaps.cf, as well as the multi-instance
5 kx # template files main.cf.proto and master.cf.proto. This
5 kx # directory should contain only Postfix-related files.
5 kx # .IP readme_directory
5 kx # The final destination directory for the Postfix README files.
5 kx # This parameter setting is recorded in the installed main.cf file.
5 kx # .IP shlib_directory
5 kx # The final destination directory for Postfix shared-library
5 kx # files, and the default directory for Postfix database plugin
5 kx # files with a relative pathname in the file dynamicmaps.cf.
5 kx # This directory should contain only Postfix-related files.
5 kx # The shlib_directory parameter built-in default value is
5 kx # specified at compile time. If you change this at installation
5 kx # time, then additional configuration will be required with
5 kx # ldconfig(1) or equivalent.
5 kx # SEE ALSO
5 kx # post-install(1) post-installation procedure
5 kx # FILES
5 kx # $config_directory/main.cf, Postfix installation configuration.
5 kx # $meta_directory/postfix-files, installation control file.
5 kx # $config_directory/install.cf, obsolete configuration file.
5 kx # LICENSE
5 kx # .ad
5 kx # .fi
5 kx # The Secure Mailer license must be distributed with this software.
5 kx # AUTHOR(S)
5 kx # Wietse Venema
5 kx # IBM T.J. Watson Research
5 kx # P.O. Box 704
5 kx # Yorktown Heights, NY 10598, USA
5 kx #
5 kx # Wietse Venema
5 kx # Google, Inc.
5 kx # 111 8th Avenue
5 kx # New York, NY 10011, USA
5 kx #--
5 kx
5 kx # Initialize.
5 kx # By now, shells must have functions. Ultrix users must use sh5 or lose.
5 kx
5 kx umask 022
5 kx PATH=/bin:/usr/bin:/usr/sbin:/usr/etc:/sbin:/etc:/usr/contrib/bin:/usr/gnu/bin:/usr/ucb:/usr/bsd
5 kx SHELL=/bin/sh
5 kx IFS="
5 kx "
5 kx BACKUP_IFS="$IFS"
5 kx
5 kx # This script uses outputs from Postfix and non-Postfix commands.
5 kx # Override all LC_* settings and LANG for robustness.
5 kx LC_ALL=C; export LC_ALL
5 kx
5 kx if [ -n "$SHLIB_ENV_VAR" ]; then
5 kx junk="${SHLIB_ENV_VAL}"
5 kx eval export "$SHLIB_ENV_VAR=\$junk"
5 kx fi
5 kx
5 kx USAGE="Usage: $0 [name=value] [option]
5 kx -keep-build-mtime Preserve build-time file mtime timestamps.
5 kx -non-interactive Do not ask for installation parameters.
5 kx -package Build a ready-to-install package.
5 kx name=value Specify an installation parameter".
5 kx
5 kx # Process command-line options and parameter settings. Work around
5 kx # brain damaged shells. "IFS=value command" should not make the
5 kx # IFS=value setting permanent. But some broken standard allows it.
5 kx
5 kx for arg
5 kx do
5 kx case $arg in
5 kx *[" "]*) echo "$0: Error: argument contains whitespace: '$arg'"; exit 1;;
5 kx *=*) IFS= eval $arg; IFS="$BACKUP_IFS";;
5 kx -non-int*) non_interactive=1;;
5 kx -package) need_install_root=install_root;;
5 kx -keep-build-mtime)
5 kx keep_build_mtime=1;;
5 kx *) echo "$0: Error: $USAGE" 1>&2; exit 1;;
5 kx esac
5 kx shift
5 kx done
5 kx
5 kx # Sanity checks.
5 kx
5 kx test -z "$non_interactive" -a ! -t 0 && {
5 kx echo $0: Error: for non-interactive use, run: \"$0 -non-interactive\" 1>&2
5 kx exit 1
5 kx }
5 kx
5 kx test -x bin/postconf || {
5 kx echo $0: Error: no bin/postconf file. Did you forget to run \"make\"? 1>&2
5 kx exit 1
5 kx }
5 kx
5 kx CONFIG_PARAMS="command_directory daemon_directory data_directory \
5 kx html_directory mail_owner mailq_path manpage_directory newaliases_path \
5 kx queue_directory readme_directory sendmail_path setgid_group shlib_directory \
5 kx meta_directory"
5 kx
5 kx # Expand the string MAIL_VERSION at the end of "make install" etc.
5 kx # name=value command-line arguments (and consequently, in environment
5 kx # settings), for consistency with "make makefiles".
5 kx
5 kx # Note that MAIL_VERSION) does not anchor the match at the end.
5 kx
5 kx for name in $CONFIG_PARAMS sample_directory install_root tempdir
5 kx do
5 kx eval junk=\$$name
5 kx case "$junk" in
5 kx *MAIL_VERSION*)
5 kx case "$mail_version" in
5 kx "") mail_version="`bin/postconf -dhx mail_version`" || exit 1
5 kx esac
5 kx val=`echo "$junk" | sed 's/MAIL_VERSION$/'"$mail_version/g"` || exit 1
5 kx case "$val" in
5 kx *MAIL_VERSION*)
5 kx echo "MAIL_VERSION not at end of parameter value: $junk" 1>&2; exit 1
5 kx esac
5 kx eval ${name}='"$val"'
5 kx esac
5 kx done
5 kx
5 kx case `uname -s` in
5 kx HP-UX*) FMT=cat;;
5 kx *) FMT=fmt;;
5 kx esac
5 kx
5 kx # Disclaimer.
5 kx
5 kx test -z "$non_interactive" && cat <<EOF | ${FMT}
5 kx
5 kx Warning: if you use this script to install Postfix locally,
5 kx this script will replace existing sendmail or Postfix programs.
5 kx Make backups if you want to be able to recover.
5 kx
5 kx Before installing files, this script prompts you for some
5 kx definitions. Most definitions will be remembered, so you have
5 kx to specify them only once. All definitions should have a
5 kx reasonable default value.
5 kx EOF
5 kx
5 kx # The following shell functions replace files/symlinks while minimizing
5 kx # the time that a file does not exist, and avoid copying over files
5 kx # in order to not disturb running programs. That is certainly desirable
5 kx # when upgrading Postfix on a live machine. It also avoids surprises
5 kx # when building a Postfix package for distribution to other systems.
5 kx
5 kx compare_or_replace() {
5 kx mode=$1
5 kx owner=$2
5 kx group=$3
5 kx src=$4
5 kx dst=$5
5 kx (cmp $src $dst >/dev/null 2>&1 && echo Skipping $dst...) || {
5 kx echo Updating $dst...
5 kx rm -f $tempdir/junk || exit 1
5 kx # Not: "cp -p" which preserves ownership.
5 kx cp $src $tempdir/junk || exit 1
5 kx test -z "$keep_build_mtime" || touch -r $src $tempdir/junk || exit 1
5 kx mv -f $tempdir/junk $dst || exit 1
5 kx test -z "$owner" || chown $owner $dst || exit 1
5 kx test -z "$group" || chgrp $group $dst || exit 1
5 kx chmod $mode $dst || exit 1
5 kx }
5 kx }
5 kx
5 kx myreadlink() {
5 kx ls -ld -- "$@" 2>/dev/null | awk '
5 kx /->/ { print $NF; next }
5 kx { exit(1) }
5 kx '
5 kx }
5 kx
5 kx compare_or_symlink() {
5 kx case $1 in
5 kx /*) dest=`echo $1 | sed '
5 kx s;^'$install_root';;
5 kx s;/\./;/;g
5 kx s;//*;/;g
5 kx s;^/;;
5 kx '`
5 kx link=`echo $2 | sed '
5 kx s;^'$install_root';;
5 kx s;/\./;/;g
5 kx s;//*;/;g
5 kx s;^/;;
5 kx s;/[^/]*$;/;
5 kx s;[^/]*/;../;g
5 kx s;$;'$dest';
5 kx '`
5 kx ;;
5 kx *) link=$1
5 kx ;;
5 kx esac
5 kx (test $link = "`myreadlink $2`" >/dev/null 2>&1 && echo Skipping $2...) || {
5 kx echo Updating $2...
5 kx # We create the symlink in place instead of using mv because:
5 kx # 1) some systems cannot move symlinks between file systems;
5 kx # 2) we cannot use mv to replace a symlink-to-directory;
5 kx # 3) "ln -n" is not in POSIX, therefore it's not portable.
5 kx # rm+ln is less atomic but this affects compatibility symlinks only.
5 kx rm -f $2 && ln -sf $link $2 || exit 1
5 kx }
5 kx }
5 kx
5 kx compare_or_hardlink() {
5 kx (cmp $1 $2 >/dev/null 2>&1 && echo Skipping $2...) || {
5 kx echo Updating $2...
5 kx rm -f $2 || exit 1
5 kx ln $1 $2 || exit 1
5 kx }
5 kx }
5 kx
5 kx check_parent() {
5 kx for path
5 kx do
5 kx dir=`echo $path|sed -e 's/[/][/]*[^/]*$//' -e 's/^$/\//'`
5 kx test -d $dir || mkdir -p $dir || exit 1
5 kx done
5 kx }
5 kx
5 kx # How to suppress newlines in echo.
5 kx
5 kx case `echo -n` in
5 kx "") n=-n; c=;;
5 kx *) n=; c='\c';;
5 kx esac
5 kx
5 kx # Prompts.
5 kx
5 kx install_root_prompt="the prefix for installed file names. Specify
5 kx this ONLY if you are building ready-to-install packages for
5 kx distribution to OTHER machines. See PACKAGE_README for instructions."
5 kx
5 kx tempdir_prompt="a directory for scratch files while installing
5 kx Postfix. You must have write permission in this directory."
5 kx
5 kx config_directory_prompt="the final destination directory for
5 kx installed Postfix configuration files."
5 kx
5 kx data_directory_prompt="the final destination directory for
5 kx Postfix-writable data files such as caches or random numbers. This
5 kx directory should not be shared with non-Postfix software."
5 kx
5 kx daemon_directory_prompt="the final destination directory for
5 kx installed Postfix daemon programs. This directory should not be
5 kx in the command search path of any users."
5 kx
5 kx command_directory_prompt="the final destination directory for
5 kx installed Postfix administrative commands. This directory should
5 kx be in the command search path of adminstrative users."
5 kx
5 kx queue_directory_prompt="the final destination directory for Postfix
5 kx queues."
5 kx
5 kx sendmail_path_prompt="the final destination pathname for the
5 kx installed Postfix sendmail command. This is the Sendmail-compatible
5 kx mail posting interface."
5 kx
5 kx newaliases_path_prompt="the final destination pathname for the
5 kx installed Postfix newaliases command. This is the Sendmail-compatible
5 kx command to build alias databases for the Postfix local delivery
5 kx agent."
5 kx
5 kx mailq_path_prompt="the final destination pathname for the installed
5 kx Postfix mailq command. This is the Sendmail-compatible mail queue
5 kx listing command."
5 kx
5 kx mail_owner_prompt="the owner of the Postfix queue. Specify an
5 kx account with numerical user ID and group ID values that are not
5 kx used by any other accounts on the system."
5 kx
5 kx setgid_group_prompt="the group for mail submission and for queue
5 kx management commands. Specify a group name with a numerical group
5 kx ID that is not shared with other accounts, not even with the Postfix
5 kx mail_owner account. You can no longer specify \"no\" here."
5 kx
5 kx manpage_directory_prompt="the final destination directory for the
5 kx Postfix on-line manual pages. You can no longer specify \"no\"
5 kx here."
5 kx
5 kx readme_directory_prompt="the final destination directory for the Postfix
5 kx README files. Specify \"no\" if you do not want to install these files."
5 kx
5 kx html_directory_prompt="the final destination directory for the Postfix
5 kx HTML files. Specify \"no\" if you do not want to install these files."
5 kx
5 kx shlib_directory_prompt="the final destination directory for Postfix
5 kx shared-library files."
5 kx
5 kx meta_directory_prompt="the final destination directory for
5 kx non-executable files that are shared among multiple Postfix instances,
5 kx such as postfix-files, dynamicmaps.cf, as well as the multi-instance
5 kx template files main.cf.proto and master.cf.proto."
5 kx
5 kx # Default settings, just to get started.
5 kx
5 kx : ${install_root=/}
5 kx : ${tempdir=`pwd`}
5 kx : ${config_directory=`@HOST_TOOLS_PREFIX@bin/postconf -c conf -h -d config_directory`}
5 kx
5 kx # Find out the location of installed configuration files.
5 kx
5 kx test -z "$non_interactive" && for name in install_root tempdir config_directory
5 kx do
5 kx while :
5 kx do
5 kx echo
5 kx eval echo Please specify \$${name}_prompt | ${FMT}
5 kx eval echo \$n "$name: [\$$name]\ \$c"
5 kx read ans
5 kx case $ans in
5 kx "") break;;
5 kx *) case $ans in
5 kx /*) eval $name=$ans; break;;
5 kx *) echo; echo $0: Error: $name should be an absolute path name. 1>&2;;
5 kx esac;;
5 kx esac
5 kx done
5 kx done
5 kx
5 kx # In case some systems special-case pathnames beginning with //.
5 kx
5 kx case $install_root in
5 kx /) install_root=
5 kx esac
5 kx
5 kx test -z "$need_install_root" || test -n "$install_root" || {
5 kx echo $0: Error: invalid package root directory: \"install_root=/\" 1>&2
5 kx exit 1
5 kx }
5 kx
5 kx CONFIG_DIRECTORY=$install_root$config_directory
5 kx
5 kx # If a parameter is not set via the command line or environment,
5 kx # try to use settings from installed configuration files.
5 kx
5 kx # Extract parameter settings from the obsolete install.cf file, as
5 kx # a transitional aid.
5 kx
5 kx grep setgid_group $CONFIG_DIRECTORY/main.cf >/dev/null 2>&1 || {
5 kx test -f $CONFIG_DIRECTORY/install.cf && {
5 kx for name in sendmail_path newaliases_path mailq_path setgid manpages
5 kx do
5 kx eval junk=\$$name
5 kx case "$junk" in
5 kx "") eval unset $name;;
5 kx esac
5 kx eval : \${$name="\`. $CONFIG_DIRECTORY/install.cf; echo \$$name\`"} \
5 kx || exit 1
5 kx done
5 kx : ${setgid_group=$setgid}
5 kx : ${manpage_directory=$manpages}
5 kx }
5 kx }
5 kx
5 kx # Extract parameter settings from the installed main.cf file.
5 kx
5 kx test -f $CONFIG_DIRECTORY/main.cf && {
5 kx for name in $CONFIG_PARAMS sample_directory
5 kx do
5 kx eval junk=\$$name
5 kx case "$junk" in
5 kx "") eval unset $name;;
5 kx esac
5 kx eval : \${$name=\`bin/postconf -c $CONFIG_DIRECTORY -hx $name\`} ||
5 kx exit 1
5 kx done
5 kx }
5 kx
5 kx # Use built-in defaults as the final source of parameter settings.
5 kx
5 kx for name in $CONFIG_PARAMS sample_directory
5 kx do
5 kx eval junk=\$$name
5 kx case "$junk" in
5 kx "") eval unset $name;;
5 kx esac
5 kx eval : \${$name=\`@HOST_TOOLS_PREFIX@bin/postconf -c conf -d -hx $name\`} || exit 1
5 kx done
5 kx
5 kx # Override settings manually.
5 kx
5 kx test -z "$non_interactive" && for name in $CONFIG_PARAMS
5 kx do
5 kx while :
5 kx do
5 kx echo
5 kx eval echo Please specify \$${name}_prompt | ${FMT}
5 kx eval echo \$n "$name: [\$$name]\ \$c"
5 kx read ans
5 kx case $ans in
5 kx "") break;;
5 kx *) eval $name=$ans; break;;
5 kx esac
5 kx done
5 kx done
5 kx
5 kx # Sanity checks
5 kx
5 kx case "$setgid_group" in
5 kx no) (echo $0: Error: the setgid_group parameter no longer accepts
5 kx echo \"no\" values. Try again with \"setgid_group=groupname\" on the
5 kx echo command line or execute \"make install\" and specify setgid_group
5 kx echo interactively.) | ${FMT} 1>&2
5 kx exit 1;;
5 kx esac
5 kx
5 kx case "$manpage_directory" in
5 kx no) (echo $0: Error: the manpage_directory parameter no longer accepts
5 kx echo \"no\" values. Try again with \"manpage_directory=/path/name\"
5 kx echo on the command line or execute \"make install\" and specify
5 kx echo manpage_directory interactively.) | ${FMT} 1>&2
5 kx exit 1;;
5 kx esac
5 kx
5 kx for path in "$html_directory" "$readme_directory" "$shlib_directory"
5 kx do
5 kx case "$path" in
5 kx /*) ;;
5 kx no) ;;
5 kx *) echo $0: Error: \"$path\" should be \"no\" or an absolute path name. 1>&2
5 kx exit 1;;
5 kx esac
5 kx done
5 kx
5 kx for path in "$daemon_directory" "$data_directory" "$command_directory" "$queue_directory" \
5 kx "$sendmail_path" "$newaliases_path" "$mailq_path" "$manpage_directory" \
5 kx "$meta_directory"
5 kx do
5 kx case "$path" in
5 kx /*) ;;
5 kx *) echo $0: Error: \"$path\" should be an absolute path name. 1>&2; exit 1;;
5 kx esac
5 kx done
5 kx
5 kx for path in mailq_path newaliases_path sendmail_path
5 kx do
5 kx eval test -d $install_root\$$path && {
5 kx echo $0: Error: \"$path\" specifies a directory. 1>&2
5 kx exit 1
5 kx }
5 kx done
5 kx
5 kx for path in command_directory config_directory daemon_directory data_directory \
5 kx manpage_directory queue_directory shlib_directory html_directory \
5 kx readme_directory meta_directory
5 kx do
5 kx case "$path" in
5 kx no) ;;
5 kx *) eval test -f $install_root\$$path && {
5 kx echo $0: Error: \"$path\" specifies a regular file. 1>&2
5 kx exit 1
5 kx };;
5 kx esac
5 kx done
5 kx
5 kx # Don't allow space or tab in parameter settings.
5 kx
5 kx for name in $CONFIG_PARAMS sample_directory
5 kx do
5 kx eval junk=\$$name
5 kx case "$junk" in
5 kx *"[ ]"*) echo "$0: Error: $name value contains whitespace: '$junk'" 1>&2
5 kx exit 1;;
5 kx esac
5 kx done
5 kx
5 kx test -d $tempdir || mkdir -p $tempdir || exit 1
5 kx
5 kx trap "rm -f $tempdir/junk" 0 1 2 3 15
5 kx
5 kx ( rm -f $tempdir/junk && touch $tempdir/junk ) || {
5 kx echo $0: Error: you have no write permission to $tempdir. 1>&2
5 kx echo Specify an alternative directory for scratch files. 1>&2
5 kx exit 1
5 kx }
5 kx
5 kx test -z "$install_root" && {
5 kx
5 kx chown root $tempdir/junk >/dev/null 2>&1 || {
5 kx echo Error: you have no permission to change file ownership. 1>&2
5 kx exit 1
5 kx }
5 kx
5 kx chown "$mail_owner" $tempdir/junk >/dev/null 2>&1 || {
5 kx echo $0: Error: \"$mail_owner\" needs an entry in the passwd file. 1>&2
5 kx echo Remember, \"$mail_owner\" needs a dedicated user and group id. 1>&2
5 kx exit 1
5 kx }
5 kx
5 kx chgrp "$setgid_group" $tempdir/junk >/dev/null 2>&1 || {
5 kx echo $0: Error: \"$setgid_group\" needs an entry in the group file. 1>&2
5 kx echo Remember, \"$setgid_group\" needs a dedicated group id. 1>&2
5 kx exit 1
5 kx }
5 kx
5 kx }
5 kx
5 kx rm -f $tempdir/junk || exit 1
5 kx
5 kx trap 0 1 2 3 15
5 kx
5 kx # Avoid clumsiness.
5 kx
5 kx DAEMON_DIRECTORY=$install_root$daemon_directory
5 kx COMMAND_DIRECTORY=$install_root$command_directory
5 kx QUEUE_DIRECTORY=$install_root$queue_directory
5 kx SENDMAIL_PATH=$install_root$sendmail_path
5 kx HTML_DIRECTORY=$install_root$html_directory
5 kx MANPAGE_DIRECTORY=$install_root$manpage_directory
5 kx README_DIRECTORY=$install_root$readme_directory
5 kx SHLIB_DIRECTORY=$install_root$shlib_directory
5 kx META_DIRECTORY=$install_root$meta_directory
5 kx
5 kx # Avoid repeated tests for existence of these; default permissions suffice.
5 kx
5 kx test -d $DAEMON_DIRECTORY || mkdir -p $DAEMON_DIRECTORY || exit 1
5 kx test -d $COMMAND_DIRECTORY || mkdir -p $COMMAND_DIRECTORY || exit 1
5 kx test -d $QUEUE_DIRECTORY || mkdir -p $QUEUE_DIRECTORY || exit 1
5 kx test "$shlib_directory" = "no" -o -d $SHLIB_DIRECTORY ||
5 kx mkdir -p $SHLIB_DIRECTORY || exit 1
5 kx test "$html_directory" = "no" -o -d $HTML_DIRECTORY ||
5 kx mkdir -p $HTML_DIRECTORY || exit 1
5 kx test "$readme_directory" = "no" -o -d $README_DIRECTORY ||
5 kx mkdir -p $README_DIRECTORY || exit 1
5 kx test -d $META_DIRECTORY || mkdir -p $META_DIRECTORY || exit 1
5 kx
5 kx # Upgrade or first-time installation?
5 kx
5 kx if [ -f $CONFIG_DIRECTORY/main.cf ]
5 kx then
5 kx post_install_options="upgrade-source"
5 kx else
5 kx post_install_options="first-install"
5 kx fi
5 kx
5 kx # Install files, using information from the postfix-files file.
5 kx
5 kx exec < meta/postfix-files || exit 1
5 kx while IFS=: read path type owner group mode flags junk
5 kx do
5 kx IFS="$BACKUP_IFS"
5 kx
5 kx # Skip comments.
5 kx
5 kx case $path in
5 kx [$]*) ;;
5 kx *) continue;;
5 kx esac
5 kx
5 kx # Skip over files that ought to be removed.
5 kx # Leave it up to post-install to report them to the user.
5 kx
5 kx case $flags in
5 kx *o*) continue
5 kx esac
5 kx
5 kx # Skip over files that must be preserved.
5 kx
5 kx case $flags in
5 kx *p*) eval test -f $install_root$path && {
5 kx eval echo "Skipping $install_root$path..."
5 kx continue
5 kx };;
5 kx esac
5 kx
5 kx # Save source path before it is clobbered.
5 kx
5 kx case $type in
5 kx [hl]) eval source=$owner;;
5 kx esac
5 kx
5 kx # If installing from source code, apply special permissions or ownership.
5 kx # If building a package, don't apply special permissions or ownership.
5 kx
5 kx case $install_root in
5 kx "") case $owner in
5 kx [$]*) eval owner=$owner;;
5 kx root) owner=;;
5 kx esac
5 kx case $group in
5 kx [$]*) eval group=$group;;
5 kx -) group=;;
5 kx esac;;
5 kx *) case $mode in
5 kx [1-7]755) mode=755;;
5 kx esac
5 kx owner=
5 kx group=;;
5 kx esac
5 kx
5 kx
5 kx case $type in
5 kx
5 kx # Create/update directory.
5 kx
5 kx d) eval path=$install_root$path
5 kx test "$path" = "${install_root}no" -o -d $path || {
5 kx mkdir -p $path || exit 1
5 kx test -z "$owner" || chown $owner $path || exit 1
5 kx test -z "$group" || chgrp $group $path || exit 1
5 kx chmod $mode $path || exit 1
5 kx }
5 kx continue;;
5 kx
5 kx # Create/update regular file.
5 kx
5 kx f) echo $path | (IFS=/ read prefix file; IFS="$BACKUP_IFS"
5 kx case $prefix in
5 kx '$shlib_directory')
5 kx compare_or_replace $mode "$owner" "$group" lib/$file \
5 kx $SHLIB_DIRECTORY/$file || exit 1;;
5 kx '$meta_directory')
5 kx compare_or_replace $mode "$owner" "$group" meta/$file \
5 kx $META_DIRECTORY/$file || exit 1;;
5 kx '$daemon_directory')
5 kx compare_or_replace $mode "$owner" "$group" libexec/$file \
5 kx $DAEMON_DIRECTORY/$file || exit 1;;
5 kx '$command_directory')
5 kx compare_or_replace $mode "$owner" "$group" bin/$file \
5 kx $COMMAND_DIRECTORY/$file || exit 1;;
5 kx '$config_directory')
5 kx compare_or_replace $mode "$owner" "$group" conf/$file \
5 kx $CONFIG_DIRECTORY/$file || exit 1;;
5 kx '$sendmail_path')
5 kx check_parent $SENDMAIL_PATH || exit 1
5 kx compare_or_replace $mode "$owner" "$group" bin/sendmail \
5 kx $SENDMAIL_PATH || exit 1;;
5 kx '$html_directory')
5 kx test "$html_directory" = "no" ||
5 kx compare_or_replace $mode "$owner" "$group" html/$file \
5 kx $HTML_DIRECTORY/$file || exit 1;;
5 kx '$manpage_directory')
5 kx check_parent $MANPAGE_DIRECTORY/$file || exit 1
5 kx compare_or_replace $mode "$owner" "$group" man/$file \
5 kx $MANPAGE_DIRECTORY/$file || exit 1;;
5 kx '$readme_directory')
5 kx test "$readme_directory" = "no" ||
5 kx compare_or_replace $mode "$owner" "$group" README_FILES/$file \
5 kx $README_DIRECTORY/$file || exit 1;;
5 kx *) echo $0: Error: unknown entry $path in meta/postfix-files 1>&2
5 kx exit 1;;
5 kx esac) || exit 1
5 kx continue;;
5 kx
5 kx # Hard link. Skip files that are not installed.
5 kx
5 kx h) eval echo $path | (
5 kx IFS=/ read prefix file; IFS="$BACKUP_IFS"
5 kx test "$prefix" = "no" || (
5 kx eval dest_path=$install_root$path
5 kx check_parent $dest_path || exit 1
5 kx eval source_path=$install_root$source
5 kx compare_or_hardlink $source_path $dest_path || exit 1
5 kx )
5 kx ) || exit 1
5 kx continue;;
5 kx
5 kx # Symbolic link. Skip files that are not installed.
5 kx
5 kx l) eval echo $path | (
5 kx IFS=/ read prefix file; IFS="$BACKUP_IFS"
5 kx test "$prefix" = "no" || (
5 kx eval dest_path=$install_root$path
5 kx check_parent $dest_path || exit 1
5 kx eval source_path=$install_root$source
5 kx compare_or_symlink $source_path $dest_path || exit 1
5 kx )
5 kx ) || exit 1
5 kx continue;;
5 kx
5 kx *) echo $0: Error: unknown type $type for $path in meta/postfix-files 1>&2
5 kx exit 1;;
5 kx esac
5 kx
5 kx done
5 kx # More (solaris9) shell brain damage!
5 kx IFS="$BACKUP_IFS"
5 kx
5 kx # Save the installation parameters to main.cf even when they haven't
5 kx # changed from their current default. Defaults can change between
5 kx # Postfix releases, and software should not suddenly be installed in
5 kx # the wrong place when Postfix is being upgraded.
5 kx
5 kx case "$mail_version" in
5 kx "") mail_version="`@HOST_TOOLS_PREFIX@bin/postconf -dhx mail_version`" || exit 1
5 kx esac
5 kx
5 kx # Undo MAIL_VERSION expansion at the end of a parameter value. If
5 kx # someone really wants the expanded mail version in main.cf, then
5 kx # we're sorry.
5 kx
5 kx for name in $CONFIG_PARAMS sample_directory
5 kx do
5 kx eval junk=\$$name
5 kx case "$junk" in
5 kx *"$mail_version"*)
5 kx case "$pattern" in
5 kx "") pattern=`echo "$mail_version" | sed 's/\./\\\\./g'` || exit 1
5 kx esac
5 kx val=`echo "$junk" | sed "s/$pattern"'$/${mail_version}/g'` || exit 1
5 kx eval ${name}='"$val"'
5 kx esac
5 kx done
5 kx
5 kx @HOST_TOOLS_PREFIX@bin/postconf -c $CONFIG_DIRECTORY -e \
5 kx "daemon_directory = $daemon_directory" \
5 kx "data_directory = $data_directory" \
5 kx "command_directory = $command_directory" \
5 kx "queue_directory = $queue_directory" \
5 kx "mail_owner = $mail_owner" \
5 kx "setgid_group = $setgid_group" \
5 kx "sendmail_path = $sendmail_path" \
5 kx "mailq_path = $mailq_path" \
5 kx "newaliases_path = $newaliases_path" \
5 kx "html_directory = $html_directory" \
5 kx "manpage_directory = $manpage_directory" \
5 kx "sample_directory = $sample_directory" \
5 kx "readme_directory = $readme_directory" \
5 kx "shlib_directory = $shlib_directory" \
5 kx "meta_directory = $meta_directory" \
5 kx || exit 1
5 kx
5 kx # If Postfix is being installed locally from source code, do the
5 kx # post-install processing now.
5 kx
5 kx # The unexpansion above may have side effects on exported variables.
5 kx # It does not matter because bin/postfix below will override them.
5 kx
5 kx test -n "$install_root" || {
5 kx bin/postfix post-install $post_install_options || exit 1
5 kx }