Home | History | Annotate | Line # | Download | only in dist
      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 -keep-build-mtime
     44 #	When installing files preserve new file's mtime timestamps.
     45 #	Otherwise, mtimes will be set to the time that postfix-install
     46 #	is run.
     47 # .IP -non-interactive
     48 #	Do not ask the user for parameter settings. Installation parameters
     49 #	are specified via one of the non-interactive methods described
     50 #	below.
     51 # .IP -package
     52 #	Build a ready-to-install package. This requires that a
     53 #	non-default install_root parameter is specified.
     54 # INSTALLATION PARAMETER INPUT METHODS
     55 # .ad
     56 # .fi
     57 #	Parameter settings can be specified through a variety of
     58 #	mechanisms.  In order of decreasing precedence these are:
     59 # .IP "interactive mode"
     60 #	By default, postfix-install will ask the user for installation
     61 #	parameter settings. These settings have the highest precedence.
     62 # .IP "command line"
     63 #	Parameter settings can be given as name=value arguments on
     64 #	the postfix-install command line. This mode will replace
     65 #	the string MAIL_VERSION at the end of a configuration
     66 #	parameter value with the Postfix release version (Postfix
     67 #	3.0 and later).
     68 # .IP "process environment"
     69 #	Parameter settings can be given as name=value environment
     70 #	variables. Environment parameters can also be specified on
     71 #	the make(1) command line as "make install name=value ...".
     72 #	This mode will replace the string MAIL_VERSION at the end
     73 #	of a configuration parameter value with the Postfix release
     74 #	version (Postfix 3.0 and later).
     75 # .IP "installed configuration files"
     76 #	If a parameter is not specified via the command line or via the
     77 #	process environment, postfix-install will attempt to extract its
     78 #	value from an already installed Postfix main.cf configuration file.
     79 # .IP "built-in defaults"
     80 #	These settings have the lowest precedence.
     81 # INSTALLATION PARAMETER DESCRIPTION
     82 # .ad
     83 # .fi
     84 #	The description of installation parameters and their built-in
     85 #	default settings is as follows:
     86 # .IP install_root
     87 #	Prefix that is prepended to the pathnames of installed files.
     88 #	Specify this ONLY when creating pre-built packages for distribution to
     89 #	other systems. The built-in default is "/", the local root directory.
     90 #	This parameter setting is not recorded in the installed main.cf file.
     91 # .IP tempdir
     92 #	Directory for scratch files while installing Postfix.
     93 #	You must have write permission in this directory.
     94 #	The built-in default directory name is the current directory.
     95 #	This parameter setting is not recorded in the installed main.cf file.
     96 # .IP config_directory
     97 #	The final destination directory for Postfix configuration files.
     98 #	The built-in default directory name is /etc/postfix.
     99 #	This parameter setting is not recorded in the installed main.cf file
    100 #	and can be changed only by recompiling Postfix.
    101 # .IP data_directory
    102 #	The final destination directory for Postfix-writable data files such
    103 #	as caches. This directory should not be shared with non-Postfix
    104 #	software. The built-in default directory name is /var/db/postfix.
    105 #	This parameter setting is recorded in the installed main.cf file.
    106 # .IP daemon_directory
    107 #	The final destination directory for Postfix daemon programs. This
    108 #	directory should not be in the command search path of any users.
    109 #	The built-in default directory name is /usr/libexec/postfix.
    110 #	This parameter setting is recorded in the installed main.cf file.
    111 # .IP command_directory
    112 #	The final destination directory for Postfix administrative commands.
    113 #	This directory should be in the command search path of administrative
    114 #	users. The built-in default directory name is system dependent.
    115 #	This parameter setting is recorded in the installed main.cf file.
    116 # .IP html_directory
    117 #	The final destination directory for the Postfix HTML files.
    118 #	This parameter setting is recorded in the installed main.cf file.
    119 # .IP queue_directory
    120 #	The final destination directory for Postfix queues.
    121 #	The built-in default directory name is /var/spool/postfix.
    122 #	This parameter setting is recorded in the installed main.cf file.
    123 # .IP sendmail_path
    124 #	The final destination pathname for the Postfix sendmail command.
    125 #	This is the Sendmail-compatible mail posting interface.
    126 #	The built-in default pathname is system dependent.
    127 #	This parameter setting is recorded in the installed main.cf file.
    128 # .IP newaliases_path
    129 #	The final destination pathname for the Postfix newaliases command.
    130 #	This is the Sendmail-compatible command to build alias databases
    131 #	for the Postfix local delivery agent.
    132 #	The built-in default pathname is system dependent.
    133 #	This parameter setting is recorded in the installed main.cf file.
    134 # .IP mailq_path
    135 #	The final destination pathname for the Postfix mailq command.
    136 #	This is the Sendmail-compatible command to list the mail queue.
    137 #	The built-in default pathname is system dependent.
    138 #	This parameter setting is recorded in the installed main.cf file.
    139 # .IP mail_owner
    140 #	The owner of the Postfix queue. Its numerical user ID and group ID
    141 #	must not be used by any other accounts on the system.
    142 #	The built-in default account name is postfix.
    143 #	This parameter setting is recorded in the installed main.cf file.
    144 # .IP setgid_group
    145 #	The group for mail submission and for queue management commands.
    146 #	Its numerical group ID must not be used by any other accounts on the
    147 #	system, not even by the mail_owner account.
    148 #	The built-in default group name is postdrop.
    149 #	This parameter setting is recorded in the installed main.cf file.
    150 # .IP manpage_directory
    151 #	The final destination directory for the Postfix on-line manual pages.
    152 #	This parameter setting is recorded in the installed main.cf file.
    153 # .IP sample_directory
    154 #	The final destination directory for the Postfix sample configuration
    155 #	files. This parameter is obsolete as of Postfix version 2.1.
    156 #	This parameter setting is recorded in the installed main.cf file.
    157 # .IP meta_directory
    158 #	The final destination directory for non-executable files
    159 #	that are shared among multiple Postfix instances, such
    160 #	as postfix-files, dynamicmaps.cf, as well as the multi-instance
    161 #	template files main.cf.proto and master.cf.proto. This
    162 #	directory should contain only Postfix-related files.
    163 # .IP readme_directory
    164 #	The final destination directory for the Postfix README files.
    165 #	This parameter setting is recorded in the installed main.cf file.
    166 # .IP shlib_directory
    167 #	The final destination directory for Postfix shared-library
    168 #	files, and the default directory for Postfix database plugin
    169 #	files with a relative pathname in the file dynamicmaps.cf.
    170 #	This directory should contain only Postfix-related files.
    171 #	The shlib_directory parameter built-in default value is
    172 #	specified at compile time.  If you change this at installation
    173 #	time, then additional configuration will be required with
    174 #	ldconfig(1) or equivalent.
    175 # SEE ALSO
    176 #	post-install(1) post-installation procedure
    177 # FILES
    178 #	$config_directory/main.cf, Postfix installation configuration.
    179 #	$config_directory/makedefs.out, Postfix 'make makefiles' options.
    180 #	$meta_directory/postfix-files, installation control file.
    181 #	$config_directory/install.cf, obsolete configuration file.
    182 # LICENSE
    183 # .ad
    184 # .fi
    185 #	The Secure Mailer license must be distributed with this software.
    186 # AUTHOR(S)
    187 #	Wietse Venema
    188 #	IBM T.J. Watson Research
    189 #	P.O. Box 704
    190 #	Yorktown Heights, NY 10598, USA
    191 #
    192 #	Wietse Venema
    193 #	Google, Inc.
    194 #	111 8th Avenue
    195 #	New York, NY 10011, USA
    196 #
    197 #	Wietse Venema
    198 #	porcupine.org
    199 #	Amawalk, NY 10501, USA
    200 #--
    201 
    202 # Initialize.
    203 # By now, shells must have functions. Ultrix users must use sh5 or lose.
    204 
    205 umask 022
    206 PATH=/bin:/usr/bin:/usr/sbin:/usr/etc:/sbin:/etc:/usr/contrib/bin:/usr/gnu/bin:/usr/ucb:/usr/bsd
    207 SHELL=/bin/sh
    208 IFS=" 	
    209 "
    210 BACKUP_IFS="$IFS"
    211 
    212 # This script uses outputs from Postfix and non-Postfix commands.
    213 # Override all LC_* settings and LANG for robustness.
    214 LC_ALL=C; export LC_ALL
    215 
    216 if [ -n "$SHLIB_ENV_VAR" ]; then
    217     junk="${SHLIB_ENV_VAL}"
    218     eval export "$SHLIB_ENV_VAR=\$junk"
    219 fi
    220 
    221 USAGE="Usage: $0 [name=value] [option]
    222     -keep-build-mtime       Preserve build-time file mtime timestamps.
    223     -non-interactive        Do not ask for installation parameters.
    224     -package                Build a ready-to-install package.
    225     name=value              Specify an installation parameter".
    226 
    227 # Process command-line options and parameter settings. Work around
    228 # brain damaged shells. "IFS=value command" should not make the
    229 # IFS=value setting permanent. But some broken standard allows it.
    230 
    231 for arg
    232 do
    233     case $arg in
    234 *[" 	"]*) echo "$0: Error: argument contains whitespace: '$arg'"; exit 1;;
    235 	*=*) IFS= eval $arg; IFS="$BACKUP_IFS";;
    236   -non-int*) non_interactive=1;;
    237    -package) need_install_root=install_root;;
    238 -keep-build-mtime)
    239              keep_build_mtime=1;;
    240 	  *) echo "$0: Error: $USAGE" 1>&2; exit 1;;
    241     esac
    242     shift
    243 done
    244 
    245 # Sanity checks.
    246 
    247 test -z "$non_interactive" -a ! -t 0 && {
    248     echo $0: Error: for non-interactive use, run: \"$0 -non-interactive\" 1>&2
    249     exit 1
    250 }
    251 
    252 test -x bin/postconf || {
    253     echo $0: Error: no bin/postconf file. Did you forget to run \"make\"? 1>&2
    254     exit 1
    255 }
    256 
    257 CONFIG_PARAMS="command_directory daemon_directory data_directory \
    258 html_directory mail_owner mailq_path manpage_directory newaliases_path \
    259 queue_directory readme_directory sendmail_path setgid_group shlib_directory \
    260 meta_directory"
    261 
    262 # Expand the string MAIL_VERSION at the end of "make install" etc.
    263 # name=value command-line arguments (and consequently, in environment
    264 # settings), for consistency with "make makefiles".
    265 
    266 # Note that MAIL_VERSION) does not anchor the match at the end.
    267 
    268 for name in $CONFIG_PARAMS sample_directory install_root tempdir
    269 do
    270     eval junk=\$$name
    271     case "$junk" in
    272     *MAIL_VERSION*) 
    273 	case "$mail_version" in
    274 	"") mail_version="`bin/postconf -dhx mail_version`" || exit 1
    275 	esac
    276 	val=`echo "$junk" | sed 's/MAIL_VERSION$/'"$mail_version/g"` || exit 1
    277 	case "$val" in
    278 	*MAIL_VERSION*)
    279 	   echo "MAIL_VERSION not at end of parameter value: $junk" 1>&2; exit 1
    280 	esac
    281 	eval ${name}='"$val"'
    282     esac
    283 done
    284 
    285 case `uname -s` in
    286 HP-UX*) FMT=cat;;
    287      *) FMT=fmt;;
    288 esac
    289 
    290 # Disclaimer.
    291 
    292 test -z "$non_interactive" && cat <<EOF | ${FMT}
    293 
    294     Warning: if you use this script to install Postfix locally,
    295     this script will replace existing sendmail or Postfix programs.
    296     Make backups if you want to be able to recover.
    297 
    298     Before installing files, this script prompts you for some
    299     definitions.  Most definitions will be remembered, so you have
    300     to specify them only once. All definitions should have a
    301     reasonable default value.
    302 EOF
    303 
    304 # The following shell functions replace files/symlinks while minimizing
    305 # the time that a file does not exist, and avoid copying over files
    306 # in order to not disturb running programs. That is certainly desirable
    307 # when upgrading Postfix on a live machine. It also avoids surprises
    308 # when building a Postfix package for distribution to other systems.
    309 
    310 compare_or_replace() {
    311     mode=$1
    312     owner=$2
    313     group=$3
    314     src=$4
    315     dst=$5
    316     (cmp $src $dst >/dev/null 2>&1 && echo Skipping $dst...) || {
    317 	echo Updating $dst...
    318 	rm -f $tempdir/junk || exit 1
    319 	# Not: "cp -p" which preserves ownership.
    320 	cp $src $tempdir/junk || exit 1
    321 	test -z "$keep_build_mtime" || touch -r $src $tempdir/junk || exit 1
    322 	mv -f $tempdir/junk $dst || exit 1
    323 	test -z "$owner" || chown $owner $dst || exit 1
    324 	test -z "$group" || chgrp $group $dst || exit 1
    325 	chmod $mode $dst || exit 1
    326     }
    327 }
    328 
    329 myreadlink() {
    330     ls -ld -- "$@" 2>/dev/null | awk '
    331 	/->/ { print $NF; next } 
    332 	{ exit(1) }  
    333     '
    334 }
    335 
    336 compare_or_symlink() {
    337     case $1 in
    338     /*) dest=`echo $1 | sed '
    339 	    s;^'$install_root';;
    340 	    s;/\./;/;g
    341 	    s;//*;/;g
    342 	    s;^/;;
    343 	'`
    344 	link=`echo $2 | sed '
    345 	    s;^'$install_root';;
    346 	    s;/\./;/;g
    347 	    s;//*;/;g
    348 	    s;^/;;
    349 	    s;/[^/]*$;/;
    350 	    s;[^/]*/;../;g
    351 	    s;$;'$dest';
    352 	'`
    353 	;;
    354      *) link=$1
    355 	;;
    356     esac
    357     (test $link = "`myreadlink $2`" >/dev/null 2>&1 && echo Skipping $2...) || {
    358 	echo Updating $2...
    359 	# We create the symlink in place instead of using mv because:
    360 	# 1) some systems cannot move symlinks between file systems;
    361 	# 2) we cannot use mv to replace a symlink-to-directory;
    362 	# 3) "ln -n" is not in POSIX, therefore it's not portable.
    363 	# rm+ln is less atomic but this affects compatibility symlinks only.
    364 	rm -f $2 && ln -sf $link $2 || exit 1
    365     }
    366 }
    367 
    368 compare_or_hardlink() {
    369     (cmp $1 $2 >/dev/null 2>&1 && echo Skipping $2...) || {
    370 	echo Updating $2...
    371 	rm -f $2 || exit 1
    372 	ln $1 $2 || exit 1
    373     }
    374 }
    375 
    376 check_parent() {
    377     for path
    378     do
    379 	dir=`echo $path|sed -e 's/[/][/]*[^/]*$//' -e 's/^$/\//'`
    380 	test -d $dir || mkdir -p $dir || exit 1
    381     done
    382 }
    383 
    384 # How to suppress newlines in echo.
    385 
    386 case `echo -n` in
    387 "") n=-n; c=;;
    388  *) n=; c='\c';;
    389 esac
    390 
    391 # Prompts.
    392 
    393 install_root_prompt="the prefix for installed file names. Specify
    394 this ONLY if you are building ready-to-install packages for
    395 distribution to OTHER machines. See PACKAGE_README for instructions."
    396 
    397 tempdir_prompt="a directory for scratch files while installing
    398 Postfix.  You must have write permission in this directory."
    399 
    400 config_directory_prompt="the final destination directory for
    401 installed Postfix configuration files."
    402 
    403 data_directory_prompt="the final destination directory for
    404 Postfix-writable data files such as caches or random numbers.  This
    405 directory should not be shared with non-Postfix software."
    406 
    407 daemon_directory_prompt="the final destination directory for
    408 installed Postfix daemon programs.  This directory should not be
    409 in the command search path of any users."
    410 
    411 command_directory_prompt="the final destination directory for
    412 installed Postfix administrative commands.  This directory should
    413 be in the command search path of administrative users."
    414 
    415 queue_directory_prompt="the final destination directory for Postfix
    416 queues."
    417 
    418 sendmail_path_prompt="the final destination pathname for the
    419 installed Postfix sendmail command. This is the Sendmail-compatible
    420 mail posting interface."
    421 
    422 newaliases_path_prompt="the final destination pathname for the
    423 installed Postfix newaliases command.  This is the Sendmail-compatible
    424 command to build alias databases for the Postfix local delivery
    425 agent."
    426 
    427 mailq_path_prompt="the final destination pathname for the installed
    428 Postfix mailq command.  This is the Sendmail-compatible mail queue
    429 listing command."
    430 
    431 mail_owner_prompt="the owner of the Postfix queue. Specify an
    432 account with numerical user ID and group ID values that are not
    433 used by any other accounts on the system."
    434 
    435 setgid_group_prompt="the group for mail submission and for queue
    436 management commands.  Specify a group name with a numerical group
    437 ID that is not shared with other accounts, not even with the Postfix
    438 mail_owner account. You can no longer specify \"no\" here."
    439 
    440 manpage_directory_prompt="the final destination directory for the
    441 Postfix on-line manual pages. You can no longer specify \"no\"
    442 here."
    443 
    444 readme_directory_prompt="the final destination directory for the Postfix
    445 README files. Specify \"no\" if you do not want to install these files."
    446 
    447 html_directory_prompt="the final destination directory for the Postfix
    448 HTML files. Specify \"no\" if you do not want to install these files."
    449 
    450 shlib_directory_prompt="the final destination directory for Postfix
    451 shared-library files."
    452 
    453 meta_directory_prompt="the final destination directory for
    454 non-executable files that are shared among multiple Postfix instances,
    455 such as postfix-files, dynamicmaps.cf, as well as the multi-instance
    456 template files main.cf.proto and master.cf.proto."
    457 
    458 # Default settings, just to get started.
    459 
    460 : ${install_root=/}
    461 : ${tempdir=`pwd`}
    462 : ${config_directory=`bin/postconf -c conf -h -d config_directory`}
    463 
    464 # Find out the location of installed configuration files.
    465 
    466 test -z "$non_interactive" && for name in install_root tempdir config_directory
    467 do
    468     while :
    469     do
    470 	echo
    471 	eval echo Please specify \$${name}_prompt | ${FMT}
    472 	eval echo \$n "$name: [\$$name]\  \$c"
    473 	read ans
    474 	case $ans in
    475 	"") break;;
    476 	 *) case $ans in
    477 	    /*) eval $name=$ans; break;;
    478 	     *) echo; echo $0: Error: $name should be an absolute path name. 1>&2;;
    479 	    esac;;
    480 	esac
    481     done
    482 done
    483 
    484 # In case some systems special-case pathnames beginning with //.
    485 
    486 case $install_root in
    487 /) install_root=
    488 esac
    489 
    490 test -z "$need_install_root" || test -n "$install_root" || {
    491     echo $0: Error: invalid package root directory: \"install_root=/\" 1>&2
    492     exit 1
    493 }
    494 
    495 CONFIG_DIRECTORY=$install_root$config_directory
    496 
    497 # If a parameter is not set via the command line or environment,
    498 # try to use settings from installed configuration files.
    499 
    500 # Extract parameter settings from the obsolete install.cf file, as
    501 # a transitional aid.
    502 
    503 grep setgid_group $CONFIG_DIRECTORY/main.cf >/dev/null 2>&1 || {
    504     test -f $CONFIG_DIRECTORY/install.cf && {
    505 	for name in sendmail_path newaliases_path mailq_path setgid manpages
    506 	do
    507 	    eval junk=\$$name
    508 	    case "$junk" in
    509 	    "") eval unset $name;;
    510 	    esac
    511 	    eval : \${$name="\`. $CONFIG_DIRECTORY/install.cf; echo \$$name\`"} \
    512 		|| exit 1
    513 	done
    514 	: ${setgid_group=$setgid}
    515 	: ${manpage_directory=$manpages}
    516     }
    517 }
    518 
    519 # Extract parameter settings from the installed main.cf file.
    520 
    521 test -f $CONFIG_DIRECTORY/main.cf && {
    522     for name in $CONFIG_PARAMS sample_directory
    523     do
    524 	eval junk=\$$name
    525 	case "$junk" in
    526 	"") eval unset $name;;
    527 	esac
    528 	eval : \${$name=\`bin/postconf -qc $CONFIG_DIRECTORY -hx $name\`} ||
    529 	    exit 1
    530     done
    531 }
    532 
    533 # Use built-in defaults as the final source of parameter settings.
    534 
    535 for name in $CONFIG_PARAMS sample_directory
    536 do
    537     eval junk=\$$name
    538     case "$junk" in
    539     "") eval unset $name;;
    540     esac
    541     eval : \${$name=\`bin/postconf -c conf -d -hx $name\`} || exit 1
    542 done
    543 
    544 # Override settings manually.
    545 
    546 test -z "$non_interactive" && for name in $CONFIG_PARAMS
    547 do
    548     while :
    549     do
    550 	echo
    551 	eval echo Please specify \$${name}_prompt | ${FMT}
    552 	eval echo \$n "$name: [\$$name]\  \$c"
    553 	read ans
    554 	case $ans in
    555 	"") break;;
    556 	 *) eval $name=$ans; break;;
    557 	esac
    558     done
    559 done
    560 
    561 # Sanity checks
    562 
    563 case "$setgid_group" in
    564  no) (echo $0: Error: the setgid_group parameter no longer accepts 
    565      echo \"no\" values. Try again with \"setgid_group=groupname\" on the 
    566      echo command line or execute \"make install\" and specify setgid_group
    567      echo interactively.) | ${FMT} 1>&2
    568      exit 1;;
    569 esac
    570 
    571 case "$manpage_directory" in
    572  no) (echo $0: Error: the manpage_directory parameter no longer accepts 
    573      echo \"no\" values.  Try again with \"manpage_directory=/path/name\" 
    574      echo on the command line or execute \"make install\" and specify
    575      echo manpage_directory interactively.) | ${FMT} 1>&2
    576      exit 1;;
    577 esac
    578 
    579 for path in "$html_directory" "$readme_directory" "$shlib_directory"
    580 do
    581    case "$path" in
    582    /*) ;;
    583    no) ;;
    584     *) echo $0: Error: \"$path\" should be \"no\" or an absolute path name. 1>&2
    585        exit 1;;
    586    esac
    587 done
    588 
    589 for path in "$daemon_directory" "$data_directory" "$command_directory" "$queue_directory" \
    590     "$sendmail_path" "$newaliases_path" "$mailq_path" "$manpage_directory" \
    591     "$meta_directory"
    592 do
    593    case "$path" in
    594    /*) ;;
    595     *) echo $0: Error: \"$path\" should be an absolute path name. 1>&2; exit 1;;
    596    esac
    597 done
    598 
    599 for path in mailq_path newaliases_path sendmail_path
    600 do
    601     eval test -d $install_root\$$path && {
    602 	echo $0: Error: \"$path\" specifies a directory. 1>&2
    603 	exit 1
    604     }
    605 done
    606 
    607 for path in command_directory config_directory daemon_directory data_directory \
    608     manpage_directory queue_directory shlib_directory html_directory \
    609     readme_directory meta_directory
    610 do
    611    case "$path" in
    612    no) ;;
    613     *) eval test -f $install_root\$$path && {
    614 	echo $0: Error: \"$path\" specifies a regular file. 1>&2
    615 	exit 1
    616    };;
    617    esac
    618 done
    619 
    620 # Don't allow space or tab in parameter settings.
    621 
    622 for name in $CONFIG_PARAMS sample_directory
    623 do
    624     eval junk=\$$name
    625     case "$junk" in
    626 *"[ 	]"*) echo "$0: Error: $name value contains whitespace: '$junk'" 1>&2
    627 	     exit 1;;
    628     esac
    629 done
    630 
    631 test -d $tempdir || mkdir -p $tempdir || exit 1
    632 
    633 trap "rm -f $tempdir/junk" 0 1 2 3 15
    634 
    635 ( rm -f $tempdir/junk && touch $tempdir/junk ) || {
    636     echo $0: Error: you have no write permission to $tempdir. 1>&2
    637     echo Specify an alternative directory for scratch files. 1>&2
    638     exit 1
    639 }
    640 
    641 test -z "$install_root" && {
    642 
    643     chown root $tempdir/junk >/dev/null 2>&1 || {
    644 	echo Error: you have no permission to change file ownership. 1>&2
    645 	exit 1
    646     }
    647 
    648     chown "$mail_owner" $tempdir/junk >/dev/null 2>&1 || {
    649 	echo $0: Error: \"$mail_owner\" needs an entry in the passwd file. 1>&2
    650 	echo Remember, \"$mail_owner\" needs a dedicated user and group id. 1>&2
    651 	exit 1
    652     }
    653 
    654     chgrp "$setgid_group" $tempdir/junk >/dev/null 2>&1 || {
    655 	echo $0: Error: \"$setgid_group\" needs an entry in the group file. 1>&2
    656 	echo Remember, \"$setgid_group\" needs a dedicated group id. 1>&2
    657 	exit 1
    658     }
    659 
    660 }
    661 
    662 rm -f $tempdir/junk || exit 1
    663 
    664 trap 0 1 2 3 15
    665 
    666 # Avoid clumsiness.
    667 
    668 DAEMON_DIRECTORY=$install_root$daemon_directory
    669 COMMAND_DIRECTORY=$install_root$command_directory
    670 QUEUE_DIRECTORY=$install_root$queue_directory
    671 SENDMAIL_PATH=$install_root$sendmail_path
    672 HTML_DIRECTORY=$install_root$html_directory
    673 MANPAGE_DIRECTORY=$install_root$manpage_directory
    674 README_DIRECTORY=$install_root$readme_directory
    675 SHLIB_DIRECTORY=$install_root$shlib_directory
    676 META_DIRECTORY=$install_root$meta_directory
    677 
    678 # Avoid repeated tests for existence of these; default permissions suffice.
    679 
    680 test -d $DAEMON_DIRECTORY || mkdir -p $DAEMON_DIRECTORY || exit 1
    681 test -d $COMMAND_DIRECTORY || mkdir -p $COMMAND_DIRECTORY || exit 1
    682 test -d $QUEUE_DIRECTORY || mkdir -p $QUEUE_DIRECTORY || exit 1
    683 test "$shlib_directory" = "no" -o -d $SHLIB_DIRECTORY ||
    684 	mkdir -p $SHLIB_DIRECTORY || exit 1
    685 test "$html_directory" = "no" -o -d $HTML_DIRECTORY || 
    686 	mkdir -p $HTML_DIRECTORY || exit 1
    687 test "$readme_directory" = "no" -o -d $README_DIRECTORY || 
    688 	mkdir -p $README_DIRECTORY || exit 1
    689 test -d $META_DIRECTORY || mkdir -p $META_DIRECTORY || exit 1
    690 
    691 # Upgrade or first-time installation?
    692 
    693 if [ -f $CONFIG_DIRECTORY/main.cf ]
    694 then
    695     post_install_options="upgrade-source"
    696 else
    697     post_install_options="first-install"
    698 fi
    699 
    700 # Install files, using information from the postfix-files file.
    701 
    702 exec < meta/postfix-files || exit 1
    703 while IFS=: read path type owner group mode flags junk
    704 do
    705     IFS="$BACKUP_IFS"
    706 
    707     # Skip comments.
    708 
    709     case $path in
    710     [$]*) ;;
    711        *) continue;;
    712     esac
    713 
    714     # Skip over files that ought to be removed.
    715     # Leave it up to post-install to report them to the user.
    716 
    717     case $flags in
    718     *o*) continue
    719     esac
    720 
    721     # Skip over files that must be preserved.
    722 
    723     case $flags in
    724     *p*) eval test -f $install_root$path && {
    725 	    eval echo "Skipping $install_root$path..."
    726 	    continue
    727 	 };;
    728     esac
    729 
    730     # Save source path before it is clobbered.
    731 
    732     case $type in
    733     [hl]) eval source=$owner;;
    734     esac
    735 
    736     # If installing from source code, apply special permissions or ownership.
    737     # If building a package, don't apply special permissions or ownership.
    738 
    739     case $install_root in
    740     "") case $owner in
    741 	[$]*) eval owner=$owner;;
    742 	root) owner=;;
    743 	esac
    744 	case $group in
    745 	[$]*) eval group=$group;;
    746 	   -) group=;;
    747 	esac;;
    748      *) case $mode in
    749 	[1-7]755) mode=755;;
    750 	esac
    751 	owner=
    752 	group=;;
    753     esac
    754 
    755 
    756     case $type in
    757 
    758      # Create/update directory.
    759 
    760      d) eval path=$install_root$path
    761 	test "$path" = "${install_root}no" -o -d $path || {
    762 	    mkdir -p $path || exit 1
    763 	    test -z "$owner" || chown $owner $path || exit 1
    764 	    test -z "$group" || chgrp $group $path || exit 1
    765 	    chmod $mode $path || exit 1
    766 	}
    767 	continue;;
    768 
    769      # Create/update regular file.
    770 
    771      f) echo $path | (IFS=/ read prefix file; IFS="$BACKUP_IFS"
    772 	case $prefix in
    773 	'$shlib_directory')
    774 	    compare_or_replace $mode "$owner" "$group" lib/$file \
    775 		    $SHLIB_DIRECTORY/$file || exit 1;;
    776 	'$meta_directory')
    777 	    compare_or_replace $mode "$owner" "$group" meta/$file \
    778 		$META_DIRECTORY/$file || exit 1;;
    779 	'$daemon_directory')
    780 	    compare_or_replace $mode "$owner" "$group" libexec/$file \
    781 		$DAEMON_DIRECTORY/$file || exit 1;;
    782 	'$command_directory')
    783 	    compare_or_replace $mode "$owner" "$group" bin/$file \
    784 		$COMMAND_DIRECTORY/$file || exit 1;;
    785 	'$config_directory')
    786 	    compare_or_replace $mode "$owner" "$group" conf/$file \
    787 		$CONFIG_DIRECTORY/$file || exit 1;;
    788 	'$sendmail_path')
    789 	    check_parent $SENDMAIL_PATH || exit 1
    790 	    compare_or_replace $mode "$owner" "$group" bin/sendmail \
    791 		$SENDMAIL_PATH || exit 1;;
    792 	'$html_directory')
    793 	    test "$html_directory" = "no" ||
    794 		compare_or_replace $mode "$owner" "$group" html/$file \
    795 		    $HTML_DIRECTORY/$file || exit 1;;
    796 	'$manpage_directory')
    797 	    check_parent $MANPAGE_DIRECTORY/$file || exit 1
    798 	    compare_or_replace $mode "$owner" "$group" man/$file \
    799 		$MANPAGE_DIRECTORY/$file || exit 1;;
    800 	'$readme_directory')
    801 	    test "$readme_directory" = "no" ||
    802 		compare_or_replace $mode "$owner" "$group" README_FILES/$file \
    803 		    $README_DIRECTORY/$file || exit 1;;
    804 	 *) echo $0: Error: unknown entry $path in meta/postfix-files 1>&2
    805 	    exit 1;;
    806 	esac) || exit 1
    807 	continue;;
    808 
    809      # Hard link. Skip files that are not installed.
    810 
    811      h) eval echo $path | (
    812 	    IFS=/ read prefix file; IFS="$BACKUP_IFS"
    813 	    test "$prefix" = "no" || (
    814 		eval dest_path=$install_root$path
    815 		check_parent $dest_path || exit 1
    816 		eval source_path=$install_root$source
    817 		compare_or_hardlink $source_path $dest_path || exit 1
    818 	    )
    819 	) || exit 1
    820 	continue;;
    821 
    822      # Symbolic link. Skip files that are not installed.
    823 
    824      l) eval echo $path | (
    825 	    IFS=/ read prefix file; IFS="$BACKUP_IFS"
    826 	    test "$prefix" = "no" || (
    827 		eval dest_path=$install_root$path
    828 		check_parent $dest_path || exit 1
    829 		eval source_path=$install_root$source
    830 		compare_or_symlink $source_path $dest_path || exit 1
    831 	    )
    832 	) || exit 1
    833 	continue;;
    834 
    835      *) echo $0: Error: unknown type $type for $path in meta/postfix-files 1>&2
    836 	exit 1;;
    837     esac
    838 
    839 done
    840 # More (solaris9) shell brain damage!
    841 IFS="$BACKUP_IFS"
    842 
    843 # Save the installation parameters to main.cf even when they haven't
    844 # changed from their current default. Defaults can change between
    845 # Postfix releases, and software should not suddenly be installed in
    846 # the wrong place when Postfix is being upgraded.
    847 
    848 case "$mail_version" in
    849 "") mail_version="`bin/postconf -dhx mail_version`" || exit 1
    850 esac
    851 
    852 # Undo MAIL_VERSION expansion at the end of a parameter value. If
    853 # someone really wants the expanded mail version in main.cf, then
    854 # we're sorry.
    855 
    856 for name in $CONFIG_PARAMS sample_directory
    857 do
    858     eval junk=\$$name
    859     case "$junk" in
    860     *"$mail_version"*) 
    861 	case "$pattern" in
    862 	"") pattern=`echo "$mail_version" | sed 's/\./\\\\./g'` || exit 1
    863 	esac
    864 	val=`echo "$junk" | sed "s/$pattern"'$/${mail_version}/g'` || exit 1
    865 	eval ${name}='"$val"'
    866     esac
    867 done
    868 
    869 bin/postconf -qc $CONFIG_DIRECTORY -e \
    870     "daemon_directory = $daemon_directory" \
    871     "data_directory = $data_directory" \
    872     "command_directory = $command_directory" \
    873     "queue_directory = $queue_directory" \
    874     "mail_owner = $mail_owner" \
    875     "setgid_group = $setgid_group" \
    876     "sendmail_path = $sendmail_path" \
    877     "mailq_path = $mailq_path" \
    878     "newaliases_path = $newaliases_path" \
    879     "html_directory = $html_directory" \
    880     "manpage_directory = $manpage_directory" \
    881     "sample_directory = $sample_directory" \
    882     "readme_directory = $readme_directory" \
    883     "shlib_directory = $shlib_directory" \
    884     "meta_directory = $meta_directory" \
    885 || exit 1
    886 
    887 # If Postfix is being installed locally from source code, do the
    888 # post-install processing now.
    889 
    890 # The unexpansion above may have side effects on exported variables.
    891 # It does not matter because bin/postfix below will override them.
    892 
    893 test -n "$install_root" || {
    894     bin/postfix post-install $post_install_options || exit 1
    895 }
    896