xref: /netbsd-src/external/ibm-public/postfix/dist/postfix-install (revision 67b9b338a7386232ac596b5fd0cd5a9cc8a03c71)
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#	$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
200umask 022
201PATH=/bin:/usr/bin:/usr/sbin:/usr/etc:/sbin:/etc:/usr/contrib/bin:/usr/gnu/bin:/usr/ucb:/usr/bsd
202SHELL=/bin/sh
203IFS="
204"
205BACKUP_IFS="$IFS"
206
207# This script uses outputs from Postfix and non-Postfix commands.
208# Override all LC_* settings and LANG for robustness.
209LC_ALL=C; export LC_ALL
210
211if [ -n "$SHLIB_ENV_VAR" ]; then
212    junk="${SHLIB_ENV_VAL}"
213    eval export "$SHLIB_ENV_VAR=\$junk"
214fi
215
216USAGE="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
226for arg
227do
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
238done
239
240# Sanity checks.
241
242test -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
247test -x bin/postconf || {
248    echo $0: Error: no bin/postconf file. Did you forget to run \"make\"? 1>&2
249    exit 1
250}
251
252CONFIG_PARAMS="command_directory daemon_directory data_directory \
253html_directory mail_owner mailq_path manpage_directory newaliases_path \
254queue_directory readme_directory sendmail_path setgid_group shlib_directory \
255meta_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
263for name in $CONFIG_PARAMS sample_directory install_root tempdir
264do
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
278done
279
280case `uname -s` in
281HP-UX*) FMT=cat;;
282     *) FMT=fmt;;
283esac
284
285# Disclaimer.
286
287test -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.
297EOF
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
305compare_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
324myreadlink() {
325    ls -ld -- "$@" 2>/dev/null | awk '
326	/->/ { print $NF; next }
327	{ exit(1) }
328    '
329}
330
331compare_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
363compare_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
371check_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
381case `echo -n` in
382"") n=-n; c=;;
383 *) n=; c='\c';;
384esac
385
386# Prompts.
387
388install_root_prompt="the prefix for installed file names. Specify
389this ONLY if you are building ready-to-install packages for
390distribution to OTHER machines. See PACKAGE_README for instructions."
391
392tempdir_prompt="a directory for scratch files while installing
393Postfix.  You must have write permission in this directory."
394
395config_directory_prompt="the final destination directory for
396installed Postfix configuration files."
397
398data_directory_prompt="the final destination directory for
399Postfix-writable data files such as caches or random numbers.  This
400directory should not be shared with non-Postfix software."
401
402daemon_directory_prompt="the final destination directory for
403installed Postfix daemon programs.  This directory should not be
404in the command search path of any users."
405
406command_directory_prompt="the final destination directory for
407installed Postfix administrative commands.  This directory should
408be in the command search path of administrative users."
409
410queue_directory_prompt="the final destination directory for Postfix
411queues."
412
413sendmail_path_prompt="the final destination pathname for the
414installed Postfix sendmail command. This is the Sendmail-compatible
415mail posting interface."
416
417newaliases_path_prompt="the final destination pathname for the
418installed Postfix newaliases command.  This is the Sendmail-compatible
419command to build alias databases for the Postfix local delivery
420agent."
421
422mailq_path_prompt="the final destination pathname for the installed
423Postfix mailq command.  This is the Sendmail-compatible mail queue
424listing command."
425
426mail_owner_prompt="the owner of the Postfix queue. Specify an
427account with numerical user ID and group ID values that are not
428used by any other accounts on the system."
429
430setgid_group_prompt="the group for mail submission and for queue
431management commands.  Specify a group name with a numerical group
432ID that is not shared with other accounts, not even with the Postfix
433mail_owner account. You can no longer specify \"no\" here."
434
435manpage_directory_prompt="the final destination directory for the
436Postfix on-line manual pages. You can no longer specify \"no\"
437here."
438
439readme_directory_prompt="the final destination directory for the Postfix
440README files. Specify \"no\" if you do not want to install these files."
441
442html_directory_prompt="the final destination directory for the Postfix
443HTML files. Specify \"no\" if you do not want to install these files."
444
445shlib_directory_prompt="the final destination directory for Postfix
446shared-library files."
447
448meta_directory_prompt="the final destination directory for
449non-executable files that are shared among multiple Postfix instances,
450such as postfix-files, dynamicmaps.cf, as well as the multi-instance
451template 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
461test -z "$non_interactive" && for name in install_root tempdir config_directory
462do
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
477done
478
479# In case some systems special-case pathnames beginning with //.
480
481case $install_root in
482/) install_root=
483esac
484
485test -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
490CONFIG_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
498grep 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
516test -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
530for name in $CONFIG_PARAMS sample_directory
531do
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
537done
538
539# Override settings manually.
540
541test -z "$non_interactive" && for name in $CONFIG_PARAMS
542do
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
554done
555
556# Sanity checks
557
558case "$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;;
564esac
565
566case "$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;;
572esac
573
574for path in "$html_directory" "$readme_directory" "$shlib_directory"
575do
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
582done
583
584for path in "$daemon_directory" "$data_directory" "$command_directory" "$queue_directory" \
585    "$sendmail_path" "$newaliases_path" "$mailq_path" "$manpage_directory" \
586    "$meta_directory"
587do
588   case "$path" in
589   /*) ;;
590    *) echo $0: Error: \"$path\" should be an absolute path name. 1>&2; exit 1;;
591   esac
592done
593
594for path in mailq_path newaliases_path sendmail_path
595do
596    eval test -d $install_root\$$path && {
597	echo $0: Error: \"$path\" specifies a directory. 1>&2
598	exit 1
599    }
600done
601
602for path in command_directory config_directory daemon_directory data_directory \
603    manpage_directory queue_directory shlib_directory html_directory \
604    readme_directory meta_directory
605do
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
613done
614
615# Don't allow space or tab in parameter settings.
616
617for name in $CONFIG_PARAMS sample_directory
618do
619    eval junk=\$$name
620    case "$junk" in
621*"[ 	]"*) echo "$0: Error: $name value contains whitespace: '$junk'" 1>&2
622	     exit 1;;
623    esac
624done
625
626test -d $tempdir || mkdir -p $tempdir || exit 1
627
628trap "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
636test -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
657rm -f $tempdir/junk || exit 1
658
659trap 0 1 2 3 15
660
661# Avoid clumsiness.
662
663DAEMON_DIRECTORY=$install_root$daemon_directory
664COMMAND_DIRECTORY=$install_root$command_directory
665QUEUE_DIRECTORY=$install_root$queue_directory
666SENDMAIL_PATH=$install_root$sendmail_path
667HTML_DIRECTORY=$install_root$html_directory
668MANPAGE_DIRECTORY=$install_root$manpage_directory
669README_DIRECTORY=$install_root$readme_directory
670SHLIB_DIRECTORY=$install_root$shlib_directory
671META_DIRECTORY=$install_root$meta_directory
672
673# Avoid repeated tests for existence of these; default permissions suffice.
674
675test -d $DAEMON_DIRECTORY || mkdir -p $DAEMON_DIRECTORY || exit 1
676test -d $COMMAND_DIRECTORY || mkdir -p $COMMAND_DIRECTORY || exit 1
677test -d $QUEUE_DIRECTORY || mkdir -p $QUEUE_DIRECTORY || exit 1
678test "$shlib_directory" = "no" -o -d $SHLIB_DIRECTORY ||
679	mkdir -p $SHLIB_DIRECTORY || exit 1
680test "$html_directory" = "no" -o -d $HTML_DIRECTORY ||
681	mkdir -p $HTML_DIRECTORY || exit 1
682test "$readme_directory" = "no" -o -d $README_DIRECTORY ||
683	mkdir -p $README_DIRECTORY || exit 1
684test -d $META_DIRECTORY || mkdir -p $META_DIRECTORY || exit 1
685
686# Upgrade or first-time installation?
687
688if [ -f $CONFIG_DIRECTORY/main.cf ]
689then
690    post_install_options="upgrade-source"
691else
692    post_install_options="first-install"
693fi
694
695# Install files, using information from the postfix-files file.
696
697exec < meta/postfix-files || exit 1
698while IFS=: read path type owner group mode flags junk
699do
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
834done
835# More (solaris9) shell brain damage!
836IFS="$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
843case "$mail_version" in
844"") mail_version="`bin/postconf -dhx mail_version`" || exit 1
845esac
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
851for name in $CONFIG_PARAMS sample_directory
852do
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
862done
863
864bin/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
888test -n "$install_root" || {
889    bin/postfix post-install $post_install_options || exit 1
890}
891