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