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