Home | History | Annotate | Line # | Download | only in dist
postfix-install revision 1.3.8.2
      1 #!/bin/sh
      2 
      3 # To view the formatted manual page of this file, type:
      4 #	POSTFIXSOURCE/mantools/srctoman - postfix-install | nroff -man
      5 
      6 #++
      7 # NAME
      8 #	postfix-install 1
      9 # SUMMARY
     10 #	Postfix installation procedure
     11 # SYNOPSIS
     12 #	sh postfix-install [options] [name=value] ...
     13 # DESCRIPTION
     14 #	The postfix-install script is to be run from the top-level
     15 #	Postfix source directory. It implements the following operations:
     16 # .IP o
     17 #	Install or upgrade Postfix from source code. This requires
     18 #	super-user privileges.
     19 # .IP o
     20 #	Build a package that can be distributed to other systems, in order
     21 #	to install or upgrade Postfix elsewhere. This requires no super-user
     22 #	privileges. To complete the installation after unpacking the
     23 #	package, execute as super-user the post-install script in the Postfix
     24 #	configuration directory.
     25 # .PP
     26 #	The postfix-install script is controlled by installation parameters.
     27 #	Specific parameters are described at the end of this document.
     28 #
     29 #	By default, postfix-install asks the user for installation
     30 #	parameter settings. Most settings are stored in the installed
     31 #	main.cf file. Stored settings are used as site-specific defaults
     32 #	when the postfix-install script is run later.
     33 #
     34 #	The names of Postfix files and directories, as well as their
     35 #	ownerships and permissions, are stored in the postfix-files file
     36 #	in the Postfix configuration directory. This information is used
     37 #	by the post-install script (also in the configuration directory)
     38 #	for creating missing queue directories when Postfix is started,
     39 #	and for setting correct ownership and permissions when Postfix
     40 #	is installed from a pre-built package or from source code.
     41 #
     42 #	Arguments
     43 # .IP -non-interactive
     44 #	Do not ask the user for parameter settings. Installation parameters
     45 #	are specified via one of the non-interactive methods described
     46 #	below.
     47 # .IP -package
     48 #	Build a ready-to-install package. This requires that a
     49 #	non-default install_root parameter is specified.
     50 # INSTALLATION PARAMETER INPUT METHODS
     51 # .ad
     52 # .fi
     53 #	Parameter settings can be specified through a variety of
     54 #	mechanisms.  In order of decreasing precedence these are:
     55 # .IP "interactive mode"
     56 #	By default, postfix-install will ask the user for installation
     57 #	parameter settings. These settings have the highest precedence.
     58 # .IP "command line"
     59 #	Parameter settings can be given as name=value arguments on
     60 #	the postfix-install command line.
     61 # .IP "process environment"
     62 #	Parameter settings can be given as name=value environment
     63 #	variables. Environment parameters can also be specified on the
     64 #	make(1) command line as "make install name=value ...".
     65 # .IP "installed configuration files"
     66 #	If a parameter is not specified via the command line or via the
     67 #	process environment, postfix-install will attempt to extract its
     68 #	value from an already installed Postfix main.cf configuration file.
     69 # .IP "built-in defaults"
     70 #	These settings have the lowest precedence.
     71 # INSTALLATION PARAMETER DESCRIPTION
     72 # .ad
     73 # .fi
     74 #	The description of installation parameters and their built-in
     75 #	default settings is as follows:
     76 # .IP install_root
     77 #	Prefix that is prepended to the pathnames of installed files.
     78 #	Specify this ONLY when creating pre-built packages for distribution to
     79 #	other systems. The built-in default is "/", the local root directory.
     80 #	This parameter setting is not recorded in the installed main.cf file.
     81 # .IP tempdir
     82 #	Directory for scratch files while installing Postfix.
     83 #	You must have write permission in this directory.
     84 #	The built-in default directory name is the current directory.
     85 #	This parameter setting is not recorded in the installed main.cf file.
     86 # .IP config_directory
     87 #	The final destination directory for Postfix configuration files.
     88 #	The built-in default directory name is /etc/postfix.
     89 #	This parameter setting is not recorded in the installed main.cf file
     90 #	and can be changed only by recompiling Postfix.
     91 # .IP data_directory
     92 #	The final destination directory for Postfix-writable data files such
     93 #	as caches. This directory should not be shared with non-Postfix
     94 #	software. The built-in default directory name is /var/db/postfix.
     95 #	This parameter setting is recorded in the installed main.cf file.
     96 # .IP daemon_directory
     97 #	The final destination directory for Postfix daemon programs. This
     98 #	directory should not be in the command search path of any users.
     99 #	The built-in default directory name is /usr/libexec/postfix.
    100 #	This parameter setting is recorded in the installed main.cf file.
    101 # .IP command_directory
    102 #	The final destination directory for Postfix administrative commands.
    103 #	This directory should be in the command search path of adminstrative
    104 #	users. The built-in default directory name is system dependent.
    105 #	This parameter setting is recorded in the installed main.cf file.
    106 # .IP html_directory
    107 #	The final destination directory for the Postfix HTML files.
    108 #	This parameter setting is recorded in the installed main.cf file.
    109 # .IP queue_directory
    110 #	The final destination directory for Postfix queues.
    111 #	The built-in default directory name is /var/spool/postfix.
    112 #	This parameter setting is recorded in the installed main.cf file.
    113 # .IP sendmail_path
    114 #	The final destination pathname for the Postfix sendmail command.
    115 #	This is the Sendmail-compatible mail posting interface.
    116 #	The built-in default pathname is system dependent.
    117 #	This parameter setting is recorded in the installed main.cf file.
    118 # .IP newaliases_path
    119 #	The final destination pathname for the Postfix newaliases command.
    120 #	This is the Sendmail-compatible command to build alias databases
    121 #	for the Postfix local delivery agent.
    122 #	The built-in default pathname is system dependent.
    123 #	This parameter setting is recorded in the installed main.cf file.
    124 # .IP mailq_path
    125 #	The final destination pathname for the Postfix mailq command.
    126 #	This is the Sendmail-compatible command to list the mail queue.
    127 #	The built-in default pathname is system dependent.
    128 #	This parameter setting is recorded in the installed main.cf file.
    129 # .IP mail_owner
    130 #	The owner of the Postfix queue. Its numerical user ID and group ID
    131 #	must not be used by any other accounts on the system.
    132 #	The built-in default account name is postfix.
    133 #	This parameter setting is recorded in the installed main.cf file.
    134 # .IP setgid_group
    135 #	The group for mail submission and for queue management commands.
    136 #	Its numerical group ID must not be used by any other accounts on the
    137 #	system, not even by the mail_owner account.
    138 #	The built-in default group name is postdrop.
    139 #	This parameter setting is recorded in the installed main.cf file.
    140 # .IP manpage_directory
    141 #	The final destination directory for the Postfix on-line manual pages.
    142 #	This parameter setting is recorded in the installed main.cf file.
    143 # .IP sample_directory
    144 #	The final destination directory for the Postfix sample configuration
    145 #	files. This parameter is obsolete as of Postfix version 2.1.
    146 #	This parameter setting is recorded in the installed main.cf file.
    147 # .IP readme_directory
    148 #	The final destination directory for the Postfix README files.
    149 #	This parameter setting is recorded in the installed main.cf file.
    150 # SEE ALSO
    151 #	post-install(1) post-installation procedure
    152 # FILES
    153 #	$config_directory/main.cf, Postfix installation configuration.
    154 #	$daemon_directory/postfix-files, installation control file.
    155 #	$config_directory/install.cf, obsolete configuration file.
    156 # LICENSE
    157 # .ad
    158 # .fi
    159 #	The Secure Mailer license must be distributed with this software.
    160 # AUTHOR(S)
    161 #	Wietse Venema
    162 #	IBM T.J. Watson Research
    163 #	P.O. Box 704
    164 #	Yorktown Heights, NY 10598, USA
    165 #--
    166 
    167 # Initialize.
    168 # By now, shells must have functions. Ultrix users must use sh5 or lose.
    169 
    170 umask 022
    171 PATH=/bin:/usr/bin:/usr/sbin:/usr/etc:/sbin:/etc:/usr/contrib/bin:/usr/gnu/bin:/usr/ucb:/usr/bsd
    172 SHELL=/bin/sh
    173 IFS=" 	
    174 "
    175 BACKUP_IFS="$IFS"
    176 
    177 # This script uses outputs from Postfix and non-Postfix commands.
    178 # Override all LC_* settings and LANG for robustness.
    179 LC_ALL=C; export LC_ALL
    180 
    181 USAGE="Usage: $0 [name=value] [option]
    182     -non-interactive        Do not ask for installation parameters.
    183     -package                Build a ready-to-install package.
    184     name=value              Specify an installation parameter".
    185 
    186 # Process command-line options and parameter settings. Work around
    187 # brain damaged shells. "IFS=value command" should not make the
    188 # IFS=value setting permanent. But some broken standard allows it.
    189 
    190 for arg
    191 do
    192     case $arg in
    193       *=*) IFS= eval $arg; IFS="$BACKUP_IFS";;
    194 -non-int*) non_interactive=1;;
    195  -package) need_install_root=install_root;;
    196         *) echo "$0: Error: $USAGE" 1>&2; exit 1;;
    197     esac
    198     shift
    199 done
    200 
    201 # Sanity checks.
    202 
    203 test -z "$non_interactive" -a ! -t 0 && {
    204     echo $0: Error: for non-interactive use, run: \"$0 -non-interactive\" 1>&2
    205     exit 1
    206 }
    207 
    208 test -x bin/postconf || {
    209     echo $0: Error: no bin/postconf file. Did you forget to run \"make\"? 1>&2
    210     exit 1
    211 }
    212 
    213 case `uname -s` in
    214 HP-UX*) FMT=cat;;
    215      *) FMT=fmt;;
    216 esac
    217 
    218 # Disclaimer.
    219 
    220 test -z "$non_interactive" && cat <<EOF | ${FMT}
    221 
    222     Warning: if you use this script to install Postfix locally,
    223     this script will replace existing sendmail or Postfix programs.
    224     Make backups if you want to be able to recover.
    225 
    226     Before installing files, this script prompts you for some
    227     definitions.  Most definitions will be remembered, so you have
    228     to specify them only once. All definitions should have a
    229     reasonable default value.
    230 EOF
    231 
    232 # The following shell functions replace files/symlinks while minimizing
    233 # the time that a file does not exist, and avoid copying over files
    234 # in order to not disturb running programs. That is certainly desirable
    235 # when upgrading Postfix on a live machine. It also avoids surprises
    236 # when building a Postfix package for distribution to other systems.
    237 
    238 compare_or_replace() {
    239     mode=$1
    240     owner=$2
    241     group=$3
    242     src=$4
    243     dst=$5
    244     (cmp $src $dst >/dev/null 2>&1 && echo Skipping $dst...) || {
    245 	echo Updating $dst...
    246 	rm -f $tempdir/junk || exit 1
    247 	cp $src $tempdir/junk || exit 1
    248 	mv -f $tempdir/junk $dst || exit 1
    249 	test -z "$owner" || chown $owner $dst || exit 1
    250 	test -z "$group" || chgrp $group $dst || exit 1
    251 	chmod $mode $dst || exit 1
    252     }
    253 }
    254 
    255 compare_or_symlink() {
    256     (cmp $1 $2 >/dev/null 2>&1 && echo Skipping $2...) || {
    257 	echo Updating $2...
    258 	rm -f $tempdir/junk || exit 1
    259 	dest=`echo $1 | sed '
    260 	    s;^'$install_root';;
    261 	    s;/\./;/;g
    262 	    s;//*;/;g
    263 	    s;^/;;
    264 	'`
    265 	link=`echo $2 | sed '
    266 	    s;^'$install_root';;
    267 	    s;/\./;/;g
    268 	    s;//*;/;g
    269 	    s;^/;;
    270 	    s;/[^/]*$;/;
    271 	    s;[^/]*/;../;g
    272 	    s;$;'$dest';
    273 	'`
    274 	ln -s $link $tempdir/junk || exit 1
    275 	mv -f $tempdir/junk $2 || {
    276 	    echo $0: Error: your mv command has trouble renaming symlinks. 1>&2
    277 	    echo If you run Linux, upgrade to GNU fileutils-4.0 or better, 1>&2
    278 	    echo or choose a tempdir that is in the same file system as $2. 1>&2
    279 	    echo If you run FreeBSD, upgrade to version 5 or better. 1>&2
    280 	    exit 1
    281 	}
    282     }
    283 }
    284 
    285 compare_or_hardlink() {
    286     (cmp $1 $2 >/dev/null 2>&1 && echo Skipping $2...) || {
    287 	echo Updating $2...
    288 	rm -f $2 || exit 1
    289 	ln $1 $2 || exit 1
    290     }
    291 }
    292 
    293 check_parent() {
    294     for path
    295     do
    296 	dir=`echo $path|sed -e 's/[/][/]*[^/]*$//' -e 's/^$/\//'`
    297 	test -d $dir || mkdir -p $dir || exit 1
    298     done
    299 }
    300 
    301 # How to supress newlines in echo.
    302 
    303 case `echo -n` in
    304 "") n=-n; c=;;
    305  *) n=; c='\c';;
    306 esac
    307 
    308 # Prompts.
    309 
    310 install_root_prompt="the prefix for installed file names. Specify
    311 this ONLY if you are building ready-to-install packages for
    312 distribution to OTHER machines. See PACKAGE_README for instructions."
    313 
    314 tempdir_prompt="a directory for scratch files while installing
    315 Postfix.  You must have write permission in this directory."
    316 
    317 config_directory_prompt="the final destination directory for
    318 installed Postfix configuration files."
    319 
    320 data_directory_prompt="the final destination directory for
    321 Postfix-writable data files such as caches or random numbers.  This
    322 directory should not be shared with non-Postfix software."
    323 
    324 daemon_directory_prompt="the final destination directory for
    325 installed Postfix daemon programs.  This directory should not be
    326 in the command search path of any users."
    327 
    328 command_directory_prompt="the final destination directory for
    329 installed Postfix administrative commands.  This directory should
    330 be in the command search path of adminstrative users."
    331 
    332 queue_directory_prompt="the final destination directory for Postfix
    333 queues."
    334 
    335 sendmail_path_prompt="the final destination pathname for the
    336 installed Postfix sendmail command. This is the Sendmail-compatible
    337 mail posting interface."
    338 
    339 newaliases_path_prompt="the final destination pathname for the
    340 installed Postfix newaliases command.  This is the Sendmail-compatible
    341 command to build alias databases for the Postfix local delivery
    342 agent."
    343 
    344 mailq_path_prompt="the final destination pathname for the installed
    345 Postfix mailq command.  This is the Sendmail-compatible mail queue
    346 listing command."
    347 
    348 mail_owner_prompt="the owner of the Postfix queue. Specify an
    349 account with numerical user ID and group ID values that are not
    350 used by any other accounts on the system."
    351 
    352 setgid_group_prompt="the group for mail submission and for queue
    353 management commands.  Specify a group name with a numerical group
    354 ID that is not shared with other accounts, not even with the Postfix
    355 mail_owner account. You can no longer specify \"no\" here."
    356 
    357 manpage_directory_prompt="the final destination directory for the
    358 Postfix on-line manual pages. You can no longer specify \"no\"
    359 here."
    360 
    361 readme_directory_prompt="the final destination directory for the Postfix
    362 README files. Specify \"no\" if you do not want to install these files."
    363 
    364 html_directory_prompt="the final destination directory for the Postfix
    365 HTML files. Specify \"no\" if you do not want to install these files."
    366 
    367 # Default settings, just to get started.
    368 
    369 : ${install_root=/}
    370 : ${tempdir=`pwd`}
    371 : ${config_directory=`bin/postconf -c conf -h -d config_directory`}
    372 
    373 # Find out the location of installed configuration files.
    374 
    375 test -z "$non_interactive" && for name in install_root tempdir config_directory
    376 do
    377     while :
    378     do
    379 	echo
    380 	eval echo Please specify \$${name}_prompt | ${FMT}
    381 	eval echo \$n "$name: [\$$name]\  \$c"
    382 	read ans
    383 	case $ans in
    384 	"") break;;
    385 	 *) case $ans in
    386 	    /*) eval $name=$ans; break;;
    387 	     *) echo; echo $0: Error: $name should be an absolute path name. 1>&2;;
    388 	    esac;;
    389 	esac
    390     done
    391 done
    392 
    393 # In case some systems special-case pathnames beginning with //.
    394 
    395 case $install_root in
    396 /) install_root=
    397 esac
    398 
    399 test -z "$need_install_root" || test -n "$install_root" || {
    400     echo $0: Error: invalid package root directory: \"install_root=/\" 1>&2
    401     exit 1
    402 }
    403 
    404 CONFIG_DIRECTORY=$install_root$config_directory
    405 
    406 # If a parameter is not set via the command line or environment,
    407 # try to use settings from installed configuration files.
    408 
    409 # Extract parameter settings from the obsolete install.cf file, as
    410 # a transitional aid.
    411 
    412 grep setgid_group $CONFIG_DIRECTORY/main.cf >/dev/null 2>&1 || {
    413     test -f $CONFIG_DIRECTORY/install.cf && {
    414 	for name in sendmail_path newaliases_path mailq_path setgid manpages
    415 	do
    416 	    eval junk=\$$name
    417 	    case "$junk" in
    418 	    "") eval unset $name;;
    419 	    esac
    420 	    eval : \${$name="\`. $CONFIG_DIRECTORY/install.cf; echo \$$name\`"} \
    421 		|| exit 1
    422 	done
    423 	: ${setgid_group=$setgid}
    424 	: ${manpage_directory=$manpages}
    425     }
    426 }
    427 
    428 CONFIG_PARAMS="command_directory daemon_directory data_directory \
    429 html_directory mail_owner mailq_path  manpage_directory newaliases_path \
    430 queue_directory readme_directory sendmail_path setgid_group"
    431 
    432 # Extract parameter settings from the installed main.cf file.
    433 
    434 test -f $CONFIG_DIRECTORY/main.cf && {
    435     for name in $CONFIG_PARAMS sample_directory
    436     do
    437 	eval junk=\$$name
    438 	case "$junk" in
    439 	"") eval unset $name;;
    440 	esac
    441 	eval : \${$name=\`bin/postconf -c $CONFIG_DIRECTORY -h $name\`} ||
    442 	    exit 1
    443     done
    444 }
    445 
    446 # Use built-in defaults as the final source of parameter settings.
    447 
    448 for name in $CONFIG_PARAMS sample_directory
    449 do
    450     eval junk=\$$name
    451     case "$junk" in
    452     "") eval unset $name;;
    453     esac
    454     eval : \${$name=\`bin/postconf -c conf -d -h $name\`} || exit 1
    455 done
    456 
    457 # Override settings manually.
    458 
    459 test -z "$non_interactive" && for name in $CONFIG_PARAMS
    460 do
    461     while :
    462     do
    463 	echo
    464 	eval echo Please specify \$${name}_prompt | ${FMT}
    465 	eval echo \$n "$name: [\$$name]\  \$c"
    466 	read ans
    467 	case $ans in
    468 	"") break;;
    469 	 *) eval $name=$ans; break;;
    470 	esac
    471     done
    472 done
    473 
    474 # Sanity checks
    475 
    476 case "$setgid_group" in
    477  no) (echo $0: Error: the setgid_group parameter no longer accepts 
    478      echo \"no\" values. Try again with \"setgid_group=groupname\" on the 
    479      echo command line or execute \"make install\" and specify setgid_group
    480      echo interactively.) | ${FMT} 1>&2
    481      exit 1;;
    482 esac
    483 
    484 case "$manpage_directory" in
    485  no) (echo $0: Error: the manpage_directory parameter no longer accepts 
    486      echo \"no\" values.  Try again with \"manpage_directory=/path/name\" 
    487      echo on the command line or execute \"make install\" and specify
    488      echo manpage_directory interactively.) | ${FMT} 1>&2
    489      exit 1;;
    490 esac
    491 
    492 for path in "$html_directory" "$readme_directory"
    493 do
    494    case "$path" in
    495    /*) ;;
    496    no) ;;
    497     *) echo $0: Error: \"$path\" should be \"no\" or an absolute path name. 1>&2
    498        exit 1;;
    499    esac
    500 done
    501 
    502 for path in "$daemon_directory" "$data_directory" "$command_directory" "$queue_directory" \
    503     "$sendmail_path" "$newaliases_path" "$mailq_path" "$manpage_directory"
    504 do
    505    case "$path" in
    506    /*) ;;
    507     *) echo $0: Error: \"$path\" should be an absolute path name. 1>&2; exit 1;;
    508    esac
    509 done
    510 
    511 for path in mailq_path newaliases_path sendmail_path
    512 do
    513     eval test -d $install_root\$$path && {
    514 	echo $0: Error: \"$path\" specifies a directory. 1>&2
    515 	exit 1
    516     }
    517 done
    518 
    519 for path in command_directory config_directory daemon_directory data_directory \
    520     manpage_directory queue_directory html_directory readme_directory
    521 do
    522     eval test -f $install_root\$$path && {
    523 	echo $0: Error: \"$path\" specifies a regular file. 1>&2
    524 	exit 1
    525     }
    526 done
    527 
    528 test -d $tempdir || mkdir -p $tempdir || exit 1
    529 
    530 trap "rm -f $tempdir/junk" 0 1 2 3 15
    531 
    532 ( rm -f $tempdir/junk && touch $tempdir/junk ) || {
    533     echo $0: Error: you have no write permission to $tempdir. 1>&2
    534     echo Specify an alternative directory for scratch files. 1>&2
    535     exit 1
    536 }
    537 
    538 test -z "$install_root" && {
    539 
    540     chown root $tempdir/junk >/dev/null 2>&1 || {
    541 	echo Error: you have no permission to change file ownership. 1>&2
    542 	exit 1
    543     }
    544 
    545     chown "$mail_owner" $tempdir/junk >/dev/null 2>&1 || {
    546 	echo $0: Error: \"$mail_owner\" needs an entry in the passwd file. 1>&2
    547 	echo Remember, \"$mail_owner\" needs a dedicated user and group id. 1>&2
    548 	exit 1
    549     }
    550 
    551     chgrp "$setgid_group" $tempdir/junk >/dev/null 2>&1 || {
    552 	echo $0: Error: \"$setgid_group\" needs an entry in the group file. 1>&2
    553 	echo Remember, \"$setgid_group\" needs a dedicated group id. 1>&2
    554 	exit 1
    555     }
    556 
    557 }
    558 
    559 rm -f $tempdir/junk || exit 1
    560 
    561 trap 0 1 2 3 15
    562 
    563 # Avoid clumsiness.
    564 
    565 DAEMON_DIRECTORY=$install_root$daemon_directory
    566 COMMAND_DIRECTORY=$install_root$command_directory
    567 QUEUE_DIRECTORY=$install_root$queue_directory
    568 SENDMAIL_PATH=$install_root$sendmail_path
    569 HTML_DIRECTORY=$install_root$html_directory
    570 MANPAGE_DIRECTORY=$install_root$manpage_directory
    571 README_DIRECTORY=$install_root$readme_directory
    572 
    573 # Avoid repeated tests for existence of these; default permissions suffice.
    574 
    575 test -d $DAEMON_DIRECTORY || mkdir -p $DAEMON_DIRECTORY || exit 1
    576 test -d $COMMAND_DIRECTORY || mkdir -p $COMMAND_DIRECTORY || exit 1
    577 test -d $COMMAND_DIRECTORY || mkdir -p $COMMAND_DIRECTORY || exit 1
    578 test "$html_directory" = "no" -o -d $HTML_DIRECTORY || 
    579 	mkdir -p $HTML_DIRECTORY || exit 1
    580 test "$readme_directory" = "no" -o -d $README_DIRECTORY || 
    581 	mkdir -p $README_DIRECTORY || exit 1
    582 
    583 # Upgrade or first-time installation?
    584 
    585 if [ -f $CONFIG_DIRECTORY/main.cf ]
    586 then
    587     post_install_options="upgrade-source"
    588 else
    589     post_install_options="first-install"
    590 fi
    591 
    592 # Install files, using information from the postfix-files file.
    593 
    594 exec < libexec/postfix-files || exit 1
    595 while IFS=: read path type owner group mode flags junk
    596 do
    597     IFS="$BACKUP_IFS"
    598 
    599     # Skip comments.
    600 
    601     case $path in
    602     [$]*) ;;
    603        *) continue;;
    604     esac
    605 
    606     # Skip over files that ought to be removed.
    607     # Leave it up to post-install to report them to the user.
    608 
    609     case $flags in
    610     *o*) continue
    611     esac
    612 
    613     # Skip over files that must be preserved.
    614 
    615     case $flags in
    616     *p*) eval test -f $install_root$path && {
    617 	    eval echo "Skipping $install_root$path..."
    618 	    continue
    619 	 };;
    620     esac
    621 
    622     # Save source path before it is clobbered.
    623 
    624     case $type in
    625     [hl]) eval source=$owner;;
    626     esac
    627 
    628     # If installing from source code, apply special permissions or ownership.
    629     # If building a package, don't apply special permissions or ownership.
    630 
    631     case $install_root in
    632     "") case $owner in
    633 	[$]*) eval owner=$owner;;
    634 	root) owner=;;
    635 	esac
    636 	case $group in
    637 	[$]*) eval group=$group;;
    638 	   -) group=;;
    639 	esac;;
    640      *) case $mode in
    641 	[1-7]755) mode=755;;
    642 	esac
    643 	owner=
    644 	group=;;
    645     esac
    646 
    647 
    648     case $type in
    649 
    650      # Create/update directory.
    651 
    652      d) eval path=$install_root$path
    653 	test "$path" = "${install_root}no" -o -d $path || {
    654 	    mkdir -p $path || exit 1
    655 	    test -z "$owner" || chown $owner $path || exit 1
    656 	    test -z "$group" || chgrp $group $path || exit 1
    657 	    chmod $mode $path || exit 1
    658 	}
    659 	continue;;
    660 
    661      # Create/update regular file.
    662 
    663      f) echo $path | (IFS=/ read prefix file; IFS="$BACKUP_IFS"
    664 	case $prefix in
    665 	'$daemon_directory')
    666 	    compare_or_replace $mode "$owner" "$group" libexec/$file \
    667 		$DAEMON_DIRECTORY/$file || exit 1;;
    668 	'$command_directory')
    669 	    compare_or_replace $mode "$owner" "$group" bin/$file \
    670 		$COMMAND_DIRECTORY/$file || exit 1;;
    671 	'$config_directory')
    672 	    compare_or_replace $mode "$owner" "$group" conf/$file \
    673 		$CONFIG_DIRECTORY/$file || exit 1;;
    674 	'$sendmail_path')
    675 	    check_parent $SENDMAIL_PATH || exit 1
    676 	    compare_or_replace $mode "$owner" "$group" bin/sendmail \
    677 		$SENDMAIL_PATH || exit 1;;
    678 	'$html_directory')
    679 	    test "$html_directory" = "no" ||
    680 		compare_or_replace $mode "$owner" "$group" html/$file \
    681 		    $HTML_DIRECTORY/$file || exit 1;;
    682 	'$manpage_directory')
    683 	    check_parent $MANPAGE_DIRECTORY/$file || exit 1
    684 	    compare_or_replace $mode "$owner" "$group" man/$file \
    685 		$MANPAGE_DIRECTORY/$file || exit 1;;
    686 	'$readme_directory')
    687 	    test "$readme_directory" = "no" ||
    688 		compare_or_replace $mode "$owner" "$group" README_FILES/$file \
    689 		    $README_DIRECTORY/$file || exit 1;;
    690 	 *) echo $0: Error: unknown entry $path in libexec/postfix-files 1>&2
    691 	    exit 1;;
    692 	esac) || exit 1
    693 	continue;;
    694 
    695      # Hard link. Skip files that are not installed.
    696 
    697      h) eval echo $path | (
    698 	    IFS=/ read prefix file; IFS="$BACKUP_IFS"
    699 	    test "$prefix" = "no" || (
    700 		eval dest_path=$install_root$path
    701 		check_parent $dest_path || exit 1
    702 		eval source_path=$install_root$source
    703 		compare_or_hardlink $source_path $dest_path || exit 1
    704 	    )
    705 	) || exit 1
    706 	continue;;
    707 
    708      # Symbolic link. Skip files that are not installed.
    709 
    710      l) eval echo $path | (
    711 	    IFS=/ read prefix file; IFS="$BACKUP_IFS"
    712 	    test "$prefix" = "no" || (
    713 		eval dest_path=$install_root$path
    714 		check_parent $dest_path || exit 1
    715 		eval source_path=$install_root$source
    716 		compare_or_symlink $source_path $dest_path || exit 1
    717 	    )
    718 	) || exit 1
    719 	continue;;
    720 
    721      *) echo $0: Error: unknown type $type for $path in libexec/postfix-files 1>&2
    722 	exit 1;;
    723     esac
    724 
    725     done
    726 
    727 # Save the installation parameters to main.cf even when they haven't
    728 # changed from their current default. Defaults can change between
    729 # Postfix releases, and software should not suddenly be installed in
    730 # the wrong place when Postfix is being upgraded.
    731 
    732 bin/postconf -c $CONFIG_DIRECTORY -e \
    733     "daemon_directory = $daemon_directory" \
    734     "data_directory = $data_directory" \
    735     "command_directory = $command_directory" \
    736     "queue_directory = $queue_directory" \
    737     "mail_owner = $mail_owner" \
    738     "setgid_group = $setgid_group" \
    739     "sendmail_path = $sendmail_path" \
    740     "mailq_path = $mailq_path" \
    741     "newaliases_path = $newaliases_path" \
    742     "html_directory = $html_directory" \
    743     "manpage_directory = $manpage_directory" \
    744     "sample_directory = $sample_directory" \
    745     "readme_directory = $readme_directory" \
    746 || exit 1
    747 
    748 # If Postfix is being installed locally from source code, do the
    749 # post-install processing now.
    750 
    751 test -n "$install_root" || {
    752     bin/postfix post-install $post_install_options || exit 1
    753 }
    754