Home | History | Annotate | Line # | Download | only in dist
postfix-install revision 1.4
      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 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 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 destination directory for the Postfix sample configuration files.
    145 #	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 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 USAGE="Usage: $0 [name=value] [option]
    178     -non-interactive        Do not ask for installation parameters.
    179     -package                Build a ready-to-install package.
    180     name=value              Specify an installation parameter".
    181 
    182 # Process command-line options and parameter settings. Work around
    183 # brain damaged shells. "IFS=value command" should not make the
    184 # IFS=value setting permanent. But some broken standard allows it.
    185 
    186 for arg
    187 do
    188     case $arg in
    189       *=*) IFS= eval $arg; IFS="$BACKUP_IFS";;
    190 -non-int*) non_interactive=1;;
    191  -package) need_install_root=install_root;;
    192         *) echo "$0: Error: $USAGE" 1>&2; exit 1;;
    193     esac
    194     shift
    195 done
    196 
    197 # Sanity checks.
    198 
    199 test -z "$non_interactive" -a ! -t 0 && {
    200     echo $0: Error: for non-interactive use, run: \"$0 -non-interactive\" 1>&2
    201     exit 1
    202 }
    203 
    204 test -x bin/postconf || {
    205     echo $0: Error: no bin/postconf file. Did you forget to run \"make\"? 1>&2
    206     exit 1
    207 }
    208 
    209 case `uname -s` in
    210 HP-UX*) FMT=cat;;
    211      *) FMT=fmt;;
    212 esac
    213 
    214 # Disclaimer.
    215 
    216 test -z "$non_interactive" && cat <<EOF | ${FMT}
    217 
    218     Warning: if you use this script to install Postfix locally,
    219     this script will replace existing sendmail or Postfix programs.
    220     Make backups if you want to be able to recover.
    221 
    222     Before installing files, this script prompts you for some
    223     definitions.  Most definitions will be remembered, so you have
    224     to specify them only once. All definitions should have a
    225     reasonable default value.
    226 EOF
    227 
    228 # The following shell functions replace files/symlinks while minimizing
    229 # the time that a file does not exist, and avoid copying over files
    230 # in order to not disturb running programs. That is certainly desirable
    231 # when upgrading Postfix on a live machine. It also avoids surprises
    232 # when building a Postfix package for distribution to other systems.
    233 
    234 compare_or_replace() {
    235     mode=$1
    236     owner=$2
    237     group=$3
    238     src=$4
    239     dst=$5
    240     (cmp $src $dst >/dev/null 2>&1 && echo Skipping $dst...) || {
    241 	echo Updating $dst...
    242 	rm -f $tempdir/junk || exit 1
    243 	cp $src $tempdir/junk || exit 1
    244 	mv -f $tempdir/junk $dst || exit 1
    245 	test -z "$owner" || chown $owner $dst || exit 1
    246 	test -z "$group" || chgrp $group $dst || exit 1
    247 	chmod $mode $dst || exit 1
    248     }
    249 }
    250 
    251 compare_or_symlink() {
    252     (cmp $1 $2 >/dev/null 2>&1 && echo Skipping $2...) || {
    253 	echo Updating $2...
    254 	rm -f $tempdir/junk || exit 1
    255 	dest=`echo $1 | sed '
    256 	    s;^'$install_root';;
    257 	    s;/\./;/;g
    258 	    s;//*;/;g
    259 	    s;^/;;
    260 	'`
    261 	link=`echo $2 | sed '
    262 	    s;^'$install_root';;
    263 	    s;/\./;/;g
    264 	    s;//*;/;g
    265 	    s;^/;;
    266 	    s;/[^/]*$;/;
    267 	    s;[^/]*/;../;g
    268 	    s;$;'$dest';
    269 	'`
    270 	ln -s $link $tempdir/junk || exit 1
    271 	mv -f $tempdir/junk $2 || {
    272 	    echo $0: Error: your mv command has trouble renaming symlinks. 1>&2
    273 	    echo If you run Linux, upgrade to GNU fileutils-4.0 or better, 1>&2
    274 	    echo or choose a tempdir that is in the same file system as $2. 1>&2
    275 	    echo If you run FreeBSD, upgrade to version 5 or better. 1>&2
    276 	    exit 1
    277 	}
    278     }
    279 }
    280 
    281 compare_or_hardlink() {
    282     (cmp $1 $2 >/dev/null 2>&1 && echo Skipping $2...) || {
    283 	echo Updating $2...
    284 	rm -f $2 || exit 1
    285 	ln $1 $2 || exit 1
    286     }
    287 }
    288 
    289 check_parent() {
    290     for path
    291     do
    292 	dir=`echo $path|sed -e 's/[/][/]*[^/]*$//' -e 's/^$/\//'`
    293 	test -d $dir || mkdir -p $dir || exit 1
    294     done
    295 }
    296 
    297 # How to supress newlines in echo.
    298 
    299 case `echo -n` in
    300 "") n=-n; c=;;
    301  *) n=; c='\c';;
    302 esac
    303 
    304 # Prompts.
    305 
    306 install_root_prompt="the prefix for installed file names. Specify
    307 this ONLY if you are building ready-to-install packages for
    308 distribution to OTHER machines. See PACKAGE_README for instructions."
    309 
    310 tempdir_prompt="a directory for scratch files while installing
    311 Postfix.  You must have write permission in this directory."
    312 
    313 config_directory_prompt="the final destination directory for
    314 installed Postfix configuration files."
    315 
    316 data_directory_prompt="the final destination directory for
    317 Postfix-writable data files such as caches or random numbers.  This
    318 directory should not be shared with non-Postfix software."
    319 
    320 daemon_directory_prompt="the final destination directory for
    321 installed Postfix daemon programs.  This directory should not be
    322 in the command search path of any users."
    323 
    324 command_directory_prompt="the final destination directory for
    325 installed Postfix administrative commands.  This directory should
    326 be in the command search path of adminstrative users."
    327 
    328 queue_directory_prompt="the final destination directory for Postfix
    329 queues."
    330 
    331 sendmail_path_prompt="the final destination pathname for the
    332 installed Postfix sendmail command. This is the Sendmail-compatible
    333 mail posting interface."
    334 
    335 newaliases_path_prompt="the final destination pathname for the
    336 installed Postfix newaliases command.  This is the Sendmail-compatible
    337 command to build alias databases for the Postfix local delivery
    338 agent."
    339 
    340 mailq_path_prompt="the final destination pathname for the installed
    341 Postfix mailq command.  This is the Sendmail-compatible mail queue
    342 listing command."
    343 
    344 mail_owner_prompt="the owner of the Postfix queue. Specify an
    345 account with numerical user ID and group ID values that are not
    346 used by any other accounts on the system."
    347 
    348 setgid_group_prompt="the group for mail submission and for queue
    349 management commands.  Specify a group name with a numerical group
    350 ID that is not shared with other accounts, not even with the Postfix
    351 mail_owner account. You can no longer specify \"no\" here."
    352 
    353 manpage_directory_prompt="the destination directory for the Postfix on-line
    354 manual pages. You can no longer specify \"no\" here."
    355 
    356 readme_directory_prompt="the destination directory for the Postfix
    357 README files. Specify \"no\" if you do not want to install these files."
    358 
    359 html_directory_prompt="the destination directory for the Postfix
    360 HTML files. Specify \"no\" if you do not want to install these files."
    361 
    362 # Default settings, just to get started.
    363 
    364 : ${install_root=/}
    365 : ${tempdir=`pwd`}
    366 : ${config_directory=`bin/postconf -c conf -h -d config_directory`}
    367 
    368 # Find out the location of installed configuration files.
    369 
    370 test -z "$non_interactive" && for name in install_root tempdir config_directory
    371 do
    372     while :
    373     do
    374 	echo
    375 	eval echo Please specify \$${name}_prompt | ${FMT}
    376 	eval echo \$n "$name: [\$$name]\  \$c"
    377 	read ans
    378 	case $ans in
    379 	"") break;;
    380 	 *) case $ans in
    381 	    /*) eval $name=$ans; break;;
    382 	     *) echo; echo $0: Error: $name should be an absolute path name. 1>&2;;
    383 	    esac;;
    384 	esac
    385     done
    386 done
    387 
    388 # In case some systems special-case pathnames beginning with //.
    389 
    390 case $install_root in
    391 /) install_root=
    392 esac
    393 
    394 test -z "$need_install_root" || test -n "$install_root" || {
    395     echo $0: Error: invalid package root directory: \"install_root=/\" 1>&2
    396     exit 1
    397 }
    398 
    399 CONFIG_DIRECTORY=$install_root$config_directory
    400 
    401 # If a parameter is not set via the command line or environment,
    402 # try to use settings from installed configuration files.
    403 
    404 # Extract parameter settings from the obsolete install.cf file, as
    405 # a transitional aid.
    406 
    407 grep setgid_group $CONFIG_DIRECTORY/main.cf >/dev/null 2>&1 || {
    408     test -f $CONFIG_DIRECTORY/install.cf && {
    409 	for name in sendmail_path newaliases_path mailq_path setgid manpages
    410 	do
    411 	    eval junk=\$$name
    412 	    case "$junk" in
    413 	    "") eval unset $name;;
    414 	    esac
    415 	    eval : \${$name="\`. $CONFIG_DIRECTORY/install.cf; echo \$$name\`"} \
    416 		|| exit 1
    417 	done
    418 	: ${setgid_group=$setgid}
    419 	: ${manpage_directory=$manpages}
    420     }
    421 }
    422 
    423 CONFIG_PARAMS="command_directory daemon_directory data_directory \
    424 html_directory mail_owner mailq_path  manpage_directory newaliases_path \
    425 queue_directory readme_directory sendmail_path setgid_group"
    426 
    427 # Extract parameter settings from the installed main.cf file.
    428 
    429 test -f $CONFIG_DIRECTORY/main.cf && {
    430     for name in $CONFIG_PARAMS sample_directory
    431     do
    432 	eval junk=\$$name
    433 	case "$junk" in
    434 	"") eval unset $name;;
    435 	esac
    436 	eval : \${$name=\`bin/postconf -c $CONFIG_DIRECTORY -h $name\`} ||
    437 	    exit 1
    438     done
    439 }
    440 
    441 # Use built-in defaults as the final source of parameter settings.
    442 
    443 for name in $CONFIG_PARAMS sample_directory
    444 do
    445     eval junk=\$$name
    446     case "$junk" in
    447     "") eval unset $name;;
    448     esac
    449     eval : \${$name=\`bin/postconf -c conf -d -h $name\`} || exit 1
    450 done
    451 
    452 # Override settings manually.
    453 
    454 test -z "$non_interactive" && for name in $CONFIG_PARAMS
    455 do
    456     while :
    457     do
    458 	echo
    459 	eval echo Please specify \$${name}_prompt | ${FMT}
    460 	eval echo \$n "$name: [\$$name]\  \$c"
    461 	read ans
    462 	case $ans in
    463 	"") break;;
    464 	 *) eval $name=$ans; break;;
    465 	esac
    466     done
    467 done
    468 
    469 # Sanity checks
    470 
    471 case "$setgid_group" in
    472  no) (echo $0: Error: the setgid_group parameter no longer accepts 
    473      echo \"no\" values. Try again with \"setgid_group=groupname\" on the 
    474      echo command line or execute \"make install\" and specify setgid_group
    475      echo interactively.) | ${FMT} 1>&2
    476      exit 1;;
    477 esac
    478 
    479 case "$manpage_directory" in
    480  no) (echo $0: Error: the manpage_directory parameter no longer accepts 
    481      echo \"no\" values.  Try again with \"manpage_directory=/path/name\" 
    482      echo on the command line or execute \"make install\" and specify
    483      echo manpage_directory interactively.) | ${FMT} 1>&2
    484      exit 1;;
    485 esac
    486 
    487 for path in "$html_directory" "$readme_directory"
    488 do
    489    case "$path" in
    490    /*) ;;
    491    no) ;;
    492     *) echo $0: Error: \"$path\" should be \"no\" or an absolute path name. 1>&2
    493        exit 1;;
    494    esac
    495 done
    496 
    497 for path in "$daemon_directory" "$data_directory" "$command_directory" "$queue_directory" \
    498     "$sendmail_path" "$newaliases_path" "$mailq_path" "$manpage_directory"
    499 do
    500    case "$path" in
    501    /*) ;;
    502     *) echo $0: Error: \"$path\" should be an absolute path name. 1>&2; exit 1;;
    503    esac
    504 done
    505 
    506 for path in mailq_path newaliases_path sendmail_path
    507 do
    508     eval test -d $install_root\$$path && {
    509 	echo $0: Error: \"$path\" specifies a directory. 1>&2
    510 	exit 1
    511     }
    512 done
    513 
    514 for path in command_directory config_directory daemon_directory data_directory \
    515     manpage_directory queue_directory html_directory readme_directory
    516 do
    517     eval test -f $install_root\$$path && {
    518 	echo $0: Error: \"$path\" specifies a regular file. 1>&2
    519 	exit 1
    520     }
    521 done
    522 
    523 test -d $tempdir || mkdir -p $tempdir || exit 1
    524 
    525 trap "rm -f $tempdir/junk" 0 1 2 3 15
    526 
    527 ( rm -f $tempdir/junk && touch $tempdir/junk ) || {
    528     echo $0: Error: you have no write permission to $tempdir. 1>&2
    529     echo Specify an alternative directory for scratch files. 1>&2
    530     exit 1
    531 }
    532 
    533 test -z "$install_root" && {
    534 
    535     chown root $tempdir/junk >/dev/null 2>&1 || {
    536 	echo Error: you have no permission to change file ownership. 1>&2
    537 	exit 1
    538     }
    539 
    540     chown "$mail_owner" $tempdir/junk >/dev/null 2>&1 || {
    541 	echo $0: Error: \"$mail_owner\" needs an entry in the passwd file. 1>&2
    542 	echo Remember, \"$mail_owner\" needs a dedicated user and group id. 1>&2
    543 	exit 1
    544     }
    545 
    546     chgrp "$setgid_group" $tempdir/junk >/dev/null 2>&1 || {
    547 	echo $0: Error: \"$setgid_group\" needs an entry in the group file. 1>&2
    548 	echo Remember, \"$setgid_group\" needs a dedicated group id. 1>&2
    549 	exit 1
    550     }
    551 
    552 }
    553 
    554 rm -f $tempdir/junk || exit 1
    555 
    556 trap 0 1 2 3 15
    557 
    558 # Avoid clumsiness.
    559 
    560 DAEMON_DIRECTORY=$install_root$daemon_directory
    561 COMMAND_DIRECTORY=$install_root$command_directory
    562 QUEUE_DIRECTORY=$install_root$queue_directory
    563 SENDMAIL_PATH=$install_root$sendmail_path
    564 HTML_DIRECTORY=$install_root$html_directory
    565 MANPAGE_DIRECTORY=$install_root$manpage_directory
    566 README_DIRECTORY=$install_root$readme_directory
    567 
    568 # Avoid repeated tests for existence of these; default permissions suffice.
    569 
    570 test -d $DAEMON_DIRECTORY || mkdir -p $DAEMON_DIRECTORY || exit 1
    571 test -d $COMMAND_DIRECTORY || mkdir -p $COMMAND_DIRECTORY || exit 1
    572 test -d $COMMAND_DIRECTORY || mkdir -p $COMMAND_DIRECTORY || exit 1
    573 test "$html_directory" = "no" -o -d $HTML_DIRECTORY || 
    574 	mkdir -p $HTML_DIRECTORY || exit 1
    575 test "$readme_directory" = "no" -o -d $README_DIRECTORY || 
    576 	mkdir -p $README_DIRECTORY || exit 1
    577 
    578 # Upgrade or first-time installation?
    579 
    580 if [ -f $CONFIG_DIRECTORY/main.cf ]
    581 then
    582     post_install_options="upgrade-source"
    583 else
    584     post_install_options="first-install"
    585 fi
    586 
    587 # Install files, using information from the postfix-files file.
    588 
    589 exec < libexec/postfix-files || exit 1
    590 while IFS=: read path type owner group mode flags junk
    591 do
    592     IFS="$BACKUP_IFS"
    593 
    594     # Skip comments.
    595 
    596     case $path in
    597     [$]*) ;;
    598        *) continue;;
    599     esac
    600 
    601     # Skip over files that ought to be removed.
    602     # Leave it up to post-install to report them to the user.
    603 
    604     case $flags in
    605     *o*) continue
    606     esac
    607 
    608     # Skip over files that must be preserved.
    609 
    610     case $flags in
    611     *p*) eval test -f $install_root$path && {
    612 	    eval echo "Skipping $install_root$path..."
    613 	    continue
    614 	 };;
    615     esac
    616 
    617     # Save source path before it is clobbered.
    618 
    619     case $type in
    620     [hl]) eval source=$owner;;
    621     esac
    622 
    623     # If installing from source code, apply special permissions or ownership.
    624     # If building a package, don't apply special permissions or ownership.
    625 
    626     case $install_root in
    627     "") case $owner in
    628 	[$]*) eval owner=$owner;;
    629 	root) owner=;;
    630 	esac
    631 	case $group in
    632 	[$]*) eval group=$group;;
    633 	   -) group=;;
    634 	esac;;
    635      *) case $mode in
    636 	[1-7]755) mode=755;;
    637 	esac
    638 	owner=
    639 	group=;;
    640     esac
    641 
    642 
    643     case $type in
    644 
    645      # Create/update directory.
    646 
    647      d) eval path=$install_root$path
    648 	test "$path" = "${install_root}no" -o -d $path || {
    649 	    mkdir -p $path || exit 1
    650 	    test -z "$owner" || chown $owner $path || exit 1
    651 	    test -z "$group" || chgrp $group $path || exit 1
    652 	    chmod $mode $path || exit 1
    653 	}
    654 	continue;;
    655 
    656      # Create/update regular file.
    657 
    658      f) echo $path | (IFS=/ read prefix file; IFS="$BACKUP_IFS"
    659 	case $prefix in
    660 	'$daemon_directory')
    661 	    compare_or_replace $mode "$owner" "$group" libexec/$file \
    662 		$DAEMON_DIRECTORY/$file || exit 1;;
    663 	'$command_directory')
    664 	    compare_or_replace $mode "$owner" "$group" bin/$file \
    665 		$COMMAND_DIRECTORY/$file || exit 1;;
    666 	'$config_directory')
    667 	    compare_or_replace $mode "$owner" "$group" conf/$file \
    668 		$CONFIG_DIRECTORY/$file || exit 1;;
    669 	'$sendmail_path')
    670 	    check_parent $SENDMAIL_PATH || exit 1
    671 	    compare_or_replace $mode "$owner" "$group" bin/sendmail \
    672 		$SENDMAIL_PATH || exit 1;;
    673 	'$html_directory')
    674 	    test "$html_directory" = "no" ||
    675 		compare_or_replace $mode "$owner" "$group" html/$file \
    676 		    $HTML_DIRECTORY/$file || exit 1;;
    677 	'$manpage_directory')
    678 	    check_parent $MANPAGE_DIRECTORY/$file || exit 1
    679 	    compare_or_replace $mode "$owner" "$group" man/$file \
    680 		$MANPAGE_DIRECTORY/$file || exit 1;;
    681 	'$readme_directory')
    682 	    test "$readme_directory" = "no" ||
    683 		compare_or_replace $mode "$owner" "$group" README_FILES/$file \
    684 		    $README_DIRECTORY/$file || exit 1;;
    685 	 *) echo $0: Error: unknown entry $path in libexec/postfix-files 1>&2
    686 	    exit 1;;
    687 	esac) || exit 1
    688 	continue;;
    689 
    690      # Hard link. Skip files that are not installed.
    691 
    692      h) eval echo $path | (
    693 	    IFS=/ read prefix file; IFS="$BACKUP_IFS"
    694 	    test "$prefix" = "no" || (
    695 		eval dest_path=$install_root$path
    696 		check_parent $dest_path || exit 1
    697 		eval source_path=$install_root$source
    698 		compare_or_hardlink $source_path $dest_path || exit 1
    699 	    )
    700 	) || exit 1
    701 	continue;;
    702 
    703      # Symbolic link. Skip files that are not installed.
    704 
    705      l) eval echo $path | (
    706 	    IFS=/ read prefix file; IFS="$BACKUP_IFS"
    707 	    test "$prefix" = "no" || (
    708 		eval dest_path=$install_root$path
    709 		check_parent $dest_path || exit 1
    710 		eval source_path=$install_root$source
    711 		compare_or_symlink $source_path $dest_path || exit 1
    712 	    )
    713 	) || exit 1
    714 	continue;;
    715 
    716      *) echo $0: Error: unknown type $type for $path in libexec/postfix-files 1>&2
    717 	exit 1;;
    718     esac
    719 
    720     done
    721 
    722 # Save the installation parameters to main.cf even when they haven't
    723 # changed from their current default. Defaults can change between
    724 # Postfix releases, and software should not suddenly be installed in
    725 # the wrong place when Postfix is being upgraded.
    726 
    727 bin/postconf -c $CONFIG_DIRECTORY -e \
    728     "daemon_directory = $daemon_directory" \
    729     "data_directory = $data_directory" \
    730     "command_directory = $command_directory" \
    731     "queue_directory = $queue_directory" \
    732     "mail_owner = $mail_owner" \
    733     "setgid_group = $setgid_group" \
    734     "sendmail_path = $sendmail_path" \
    735     "mailq_path = $mailq_path" \
    736     "newaliases_path = $newaliases_path" \
    737     "html_directory = $html_directory" \
    738     "manpage_directory = $manpage_directory" \
    739     "sample_directory = $sample_directory" \
    740     "readme_directory = $readme_directory" \
    741 || exit 1
    742 
    743 # If Postfix is being installed locally from source code, do the
    744 # post-install processing now.
    745 
    746 test -n "$install_root" || {
    747     bin/postfix post-install $post_install_options || exit 1
    748 }
    749