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