Bugzilla #2: If the last fallback host listed was multihomed, only its
[users/jgh/exim.git] / src / scripts / exim_install
1 #! /bin/sh
2 # $Cambridge: exim/src/scripts/exim_install,v 1.1 2004/10/06 15:07:40 ph10 Exp $
3
4 # Script to install Exim binaries in BIN_DIRECTORY, which is defined in
5 # the local Makefile. It expects to be run in a build directory. It needs
6 # to be run as root in order to make exim setuid to root. If exim runs setuid
7 # to (e.g.) exim, this script should be run as that user or root.
8
9 # This script also installs a default configuration file in CONFIGURE_FILE
10 # if there is no configuration file there, but only if CONFIGURE_FILE specifies
11 # single file. If it specifies a list, no action is taken.
12
13 # If a default configuration file is installed, the existence of the system
14 # aliases file is tested. A default, containing only comments, is installed if
15 # necessary.
16
17 # If INFO_DIRECTORY is defined in any of the local Makefiles, and the Exim doc
18 # directory contains the Texinfo documentation, this script also installs a
19 # the info files in INFO_DIRECTORY.
20
21 # If DESTDIR is defined, all file paths are prefixed with ${DESTDIR}, with the
22 # sole exception of the reference to the system aliases file in the default
23 # configuration, because it is assumed that Exim is not actually going to be
24 # run from this position. For backward compatibility, if DESTDIR is not
25 # defined, ROOT is used instead.
26
27 # The script can be made to output what it would do, without actually doing
28 # anything, by giving it the option "-n" (cf make). Arguments are the names
29 # of things to install. No arguments installs everything.
30
31 do_chown=yes
32 do_symlink=yes
33
34 while [ $# -gt 0 ] ; do
35   case "$1" in
36     -n)
37       real="true || "
38       ver="verification "
39       com=": "
40       echo $com ""
41       echo $com "*** Verification mode only: no commands will actually be obeyed"
42       echo $com "*** You can cut and paste the bits you want to a shell, etc"
43       echo $com ""
44       echo cd `pwd`
45       ;;
46
47     -no_chown)
48       do_chown=no
49       ;;
50
51     -no_symlink)
52       do_symlink=no
53       ;;
54
55     *)
56       break
57       ;;
58   esac
59   shift
60 done
61
62 # Get the values of BIN_DIRECTORY, CONFIGURE_FILE, INFO_DIRECTORY, NO_SYMLINK,
63 # SYSTEM_ALIASES_FILE, and EXE from the global Makefile (in the build
64 # directory). EXE is empty except in the Cygwin environment. In each case, keep
65 # the latest definition, thus respecting the Makefiles precedence. The sed
66 # sequences here are messy, but have to be very "basic" in order to work on
67 # Solaris, where the regular expressions in sed are primitive indeed. Modify at
68 # your peril.
69
70 BIN_DIRECTORY=`sed -n   -e '/^ *BIN_DIRECTORY *=/{s/^[^=]*= *//; s/ \{1,\}#.*//;s/ *$//;h;}' -e '${g;p;}' Makefile`
71 CONFIGURE_FILE=`sed -n -e '/^ *CONFIGURE_FILE *=/{s/^[^=]*= *//; s/ \{1,\}#.*//;s/ *$//;h;}' -e '${g;p;}' Makefile`
72 INFO_DIRECTORY=`sed -n -e '/^ *INFO_DIRECTORY *=/{s/^[^=]*= *//; s/ \{1,\}#.*//;s/ *$//;h;}' -e '${g;p;}' Makefile`
73 NO_SYMLINK=`sed -n         -e '/^ *NO_SYMLINK *=/{s/^[^=]*= *//; s/ \{1,\}#.*//;s/ *$//;h;}' -e '${g;p;}' Makefile`
74 SYSTEM_ALIASES_FILE=`sed -n -e '/^ *SYSTEM_ALIASES_FILE *=/{s/^[^=]*= *//; s/ \{1,\}#.*//;s/ *$//;h;}' -e '${g;p;}' Makefile`
75 EXE=`sed -n                                 -e '/^ *EXE *=/{s/^[^=]*= *//; s/ \{1,\}#.*//;s/ *$//;h;}' -e '${g;p;}' Makefile`
76
77 # Set a default for SYSTEM_ALIASES_FILE
78
79 if [ "${SYSTEM_ALIASES_FILE}" = "" ] ; then
80   SYSTEM_ALIASES_FILE=/etc/aliases
81 fi
82
83 # Allow INST_xx to over-ride xx
84 case "$INST_BIN_DIRECTORY"       in ?*) BIN_DIRECTORY="$INST_BIN_DIRECTORY";; esac
85 case "$INST_CONFIGURE_FILE"      in ?*) CONFIGURE_FILE="$INST_CONFIGURE_FILE";; esac
86 case "$INST_INFO_DIRECTORY"      in ?*) INFO_DIRECTORY="$INST_INFO_DIRECTORY";; esac
87 case "$INST_SYSTEM_ALIASES_FILE" in ?*) SYSTEM_ALIASES_FILE="$INST_SYSTEM_ALIASES_FILE";; esac
88
89 case "$INST_UID"     in '') INST_UID=root;;    *) INST_UID="$INST_UID";; esac
90 case "$INST_CP"      in '') CP=cp;;            *) CP="$INST_CP";; esac
91 case "$INST_MV"      in '') MV=mv;;            *) MV="$INST_MV";; esac
92 case "$INST_LN"      in '') LN=ln;;            *) LN="$INST_LN";; esac
93 case "$INST_CHOWN"   in '') CHOWN=chown;;      *) CHOWN="$INST_CHOWN";; esac
94 case "$INST_CHMOD"   in '') CHMOD=chmod;;      *) CHMOD="$INST_CHMOD";; esac
95 case "$INST_DIRNAME" in '') DIRNAME=dirname;;  *) DIRNAME="$INST_DIRNAME";; esac
96 case "$INST_MKDIR"   in '') MKDIR=mkdir;;      *) MKDIR="$INST_MKDIR";; esac
97
98 # Allow the user to over-ride xx
99 case "$inst_dest"    in ?*) BIN_DIRECTORY="$inst_dest";; esac
100 case "$inst_conf"    in ?*) CONFIGURE_FILE="$inst_conf";; esac
101 case "$inst_info"    in ?*) INFO_DIRECTORY="$inst_info";; esac
102 case "$inst_aliases" in ?*) SYSTEM_ALIASES_FILE="$inst_aliases";; esac
103
104 # Insert ${DESTDIR} at the start of all paths so that the whole thing can be
105 # installed under a different file root. For backwards compatibility, use
106 # ${ROOT} if ${DESTDIR} is not set. However, we need to save the value of
107 # the real system aliases file, and use that in the default configuration.
108
109 ACTUAL_SYSTEM_ALIASES_FILE=${SYSTEM_ALIASES_FILE}
110 DESTDIR=${DESTDIR:-${ROOT}}
111
112 BIN_DIRECTORY=${DESTDIR}${BIN_DIRECTORY}
113 CONFIGURE_FILE=${DESTDIR}${CONFIGURE_FILE}
114 SYSTEM_ALIASES_FILE=${DESTDIR}${SYSTEM_ALIASES_FILE}
115
116 if [ "${INFO_DIRECTORY}" != "" ] ; then
117   INFO_DIRECTORY=${DESTDIR}${INFO_DIRECTORY}
118 fi
119
120 # Overrides of other things
121 case "$inst_uid"     in ?*) INST_UID="$inst_uid";; esac
122 case "$inst_cp"      in ?*) CP="$inst_cp";; esac
123 case "$inst_mv"      in ?*) MV="$inst_mv";; esac
124 case "$inst_ln"      in ?*) LN="$inst_ln";; esac
125 case "$inst_chown"   in ?*) CHOWN="$inst_chown";; esac
126 case "$inst_chmod"   in ?*) CHMOD="$inst_chmod";; esac
127 case "$inst_dirname" in ?*) DIRNAME="$inst_dirname";; esac
128 case "$inst_mkdir"   in ?*) MKDIR="$inst_mkdir";; esac
129
130 # chown is a special case; in at least one OS it is in /usr/etc instead
131 # of in /usr/bin, and therefore not likely to be on the path. Another OS
132 # has it in /usr/sbin. This fudge tries to cope with these variations.
133
134 # Otherwise, and for other commands, we assume that the normal PATH will
135 # give access to where they are on your operating system (normally /usr/bin
136 # or /bin).
137
138 if [ "${CHOWN}" = "chown" -a -x /usr/sbin/chown ] ; then
139   CHOWN=/usr/sbin/chown
140 fi
141
142 if [ "${CHOWN}" = "chown" -a ! -f /usr/bin/chown -a -f /usr/etc/chown ] ; then
143   CHOWN=/usr/etc/chown
144 fi
145
146 # See if the exim monitor has been built
147
148 if [ -f eximon -a -f eximon.bin ]; then
149   exim_monitor="eximon eximon.bin"
150 fi
151
152 # If bin directory doesn't exist, try to create it
153
154 if [ ! -d "${BIN_DIRECTORY}" ]; then
155   echo mkdir -p ${BIN_DIRECTORY}
156   ${real} mkdir -p ${BIN_DIRECTORY}
157   if [ $? -ne 0 ]; then
158     echo $com ""
159     echo $com "*** Exim installation ${ver}failed ***"
160     exit 1
161   else
162     ${real} echo $com ${BIN_DIRECTORY} created
163   fi
164 fi
165
166 # If no arguments, install everything
167
168 if [ $# -gt 0 ]; then
169   set $@
170 else
171   set exim${EXE} ${exim_monitor} exim_dumpdb${EXE} exim_fixdb${EXE} \
172       exim_tidydb${EXE} exinext exiwhat exim_dbmbuild${EXE} exicyclog \
173       exigrep eximstats exipick exiqgrep exiqsumm exim_lock${EXE} \
174       exim_checkaccess
175 fi
176
177 echo $com ""
178 echo $com Installation directory is ${BIN_DIRECTORY}
179 echo $com ""
180
181 while [ $# -gt 0 ]; do
182   name=$1
183   shift
184
185   if [ ! -s ${name} ]; then
186     echo $com ""
187     echo $com "*** `pwd`/${name} does not exist or is empty"
188     echo $com "*** Have you built Exim successfully?"
189     echo $com "*** Exim installation ${ver}failed ***"
190     exit 1
191   fi
192
193   # The exim binary is handled specially
194
195   if [ $name = exim${EXE} ]; then
196     version=exim-`./exim -bV -C /dev/null | \
197       awk '/Exim version/ { OFS=""; print $3,"-",substr($4,2,length($4)-1) }'`${EXE}
198
199     if [ "${version}" = "exim-${EXE}" ]; then
200       echo $com ""
201       echo $com "*** Could not run ./exim to find version number ***"
202       echo $com "*** Exim installation ${ver}failed ***"
203       exit 1
204     fi
205
206     # Do something only if newer than existing file, or no existing file
207
208     if ../scripts/newer ${name} ${BIN_DIRECTORY}/${version}; then
209       echo ${CP} ${name} ${BIN_DIRECTORY}/${version}
210       ${real} ${CP} ${name} ${BIN_DIRECTORY}/${version}
211       if [ $? -ne 0 ]; then
212         echo $com ""
213         echo $com "*** Exim installation ${ver}failed ***"
214         exit 1
215       fi
216
217       # After copy, set ownership and permissions, unless disabled
218
219       if [ "$do_chown" != "no" ]; then
220         echo ${CHOWN} ${INST_UID} ${BIN_DIRECTORY}/${version}
221         ${real} ${CHOWN} ${INST_UID} ${BIN_DIRECTORY}/${version}
222         if [ $? -ne 0 ]; then
223           echo $com ""
224           echo $com "*** You must be ${INST_UID} to install exim ***"
225           exit 1
226         fi
227         echo ${CHMOD} a+x ${BIN_DIRECTORY}/${version}
228         ${real} ${CHMOD} a+x ${BIN_DIRECTORY}/${version}
229         if [ $? -ne 0 ]; then
230           echo $com ""
231           echo $com "*** Exim installation ${ver}failed ***"
232           exit 1
233         fi
234         echo ${CHMOD} u+s ${BIN_DIRECTORY}/${version}
235         ${real} ${CHMOD} u+s ${BIN_DIRECTORY}/${version}
236         if [ $? -ne 0 ]; then
237           echo $com ""
238           echo $com "*** Exim installation ${ver}failed ***"
239           exit 1
240         fi
241       else
242         echo $com "$CHOWN $INST_UID omitted: -no_chown was specified"
243         echo $com "$CHMOD u+s omitted: -no_chown was specified"
244       fi
245
246       # Now sort out the "exim" alias, unless NO_SYMLINK is set.
247
248       if [ "X$NO_SYMLINK" = "X" ] && [ "$do_symlink" != "no" ] ; then
249
250         #  First check whether "exim" exists in the directory.
251         if [ -f ${BIN_DIRECTORY}/exim ]; then
252
253           # If it's not a symbolic link, make a copy with the old version number
254           if [ `ls -l ${BIN_DIRECTORY}/exim | cut -c1-1` != 'l' ]; then
255             oldversion=exim-`${BIN_DIRECTORY}/exim -bV -C /dev/null | \
256               awk '/Exim version/ { OFS=""; print $3,"-",substr($4,2,length($4)-1) }'`${EXE}
257             if [ "${version}" = "${oldversion}" ] ; then
258               echo $com ""
259               echo $com "*** Existing file called exim has the same version and compile number ***"
260               echo $com "*** Exim installation ${ver}failed ***"
261               exit 1
262             fi
263             echo ${CP} ${BIN_DIRECTORY}/exim ${BIN_DIRECTORY}/${oldversion}
264             ${real} ${CP} ${BIN_DIRECTORY}/exim ${BIN_DIRECTORY}/${oldversion}
265             if [ $? -ne 0 ]; then
266               echo $com ""
267               echo $com "*** Exim installation ${ver}failed ***"
268               exit 1
269             fi
270           fi
271
272           # Now we can move the name "exim" to be a symbolic link to the new
273           # version, atomically.
274
275           echo \(cd ${BIN_DIRECTORY}\; ${LN} -s ${version} temporary_exim\)
276           (${real} cd ${BIN_DIRECTORY}; ${real} ${LN} -s ${version} temporary_exim)
277           if [ $? -ne 0 ]; then
278             echo $com ""
279             echo $com "*** Exim installation ${ver}failed ***"
280             exit 1
281           fi
282
283           echo ${MV} -f ${BIN_DIRECTORY}/temporary_exim ${BIN_DIRECTORY}/exim
284           ${real} ${MV} -f ${BIN_DIRECTORY}/temporary_exim ${BIN_DIRECTORY}/exim
285           if [ $? -ne 0 ]; then
286             echo $com ""
287             echo $com "*** Exim installation ${ver}failed ***"
288             exit 1
289           fi
290
291         # If "exim" does not already exist just create a symbolic link.
292
293         else
294           echo \(cd ${BIN_DIRECTORY}\; ${LN} -s ${version} exim\)
295           (${real} cd ${BIN_DIRECTORY}; ${real} ${LN} -s ${version} exim)
296           if [ $? -ne 0 ]; then
297             echo $com ""
298             echo $com "*** Exim installation ${ver}failed ***"
299             exit 1
300           fi
301         fi
302
303       else
304         echo $com "creation of symlink omitted"
305         if [ "X$NO_SYMLINK" != "X" ] ; then
306           echo $com "(NO_SYMLINK is specified in Local/Makefile)"
307         else
308           echo $com "(-no_symlink was specified)"
309         fi
310       fi
311
312     # New binary is not newer than the installed file
313
314     else
315       echo $com ${name} is not newer than ${BIN_DIRECTORY}/${version}
316     fi
317
318   # Handle everything other than the exim binary itself
319
320   else
321     if ../scripts/newer ${name} ${BIN_DIRECTORY}/${name}; then
322       if [ -f ${BIN_DIRECTORY}/${name} ]; then
323         echo ${CP} ${BIN_DIRECTORY}/${name} ${BIN_DIRECTORY}/${name}.O
324         ${real} ${CP} ${BIN_DIRECTORY}/${name} ${BIN_DIRECTORY}/${name}.O
325         if [ $? -ne 0 ]; then
326           echo $com ""
327           echo $com "*** Exim installation ${ver}failed ***"
328           exit 1
329         fi
330       fi
331       echo ${CP} ${name} ${BIN_DIRECTORY}
332       ${real} ${CP} ${name} ${BIN_DIRECTORY}
333       if [ $? -ne 0 ]; then
334         echo $com ""
335         echo $com "*** Exim installation ${ver}failed ***"
336         exit 1
337       fi
338     else
339       echo $com ${name} is not newer than ${BIN_DIRECTORY}/${name}
340     fi
341   fi
342
343 done
344
345
346
347 # If there is no configuration file, install the default, modifying it to refer
348 # to the configured system aliases file. If there is no setting for
349 # SYSTEM_ALIASES_FILE, use the traditional /etc/aliases. If the file does not
350 # exist, install a default (dummy) for that too.
351
352 # However, if CONFIGURE_FILE specifies a list of files, skip this code.
353
354 echo $com ""
355
356 if [ `expr "${CONFIGURE_FILE}" : ".*:"` -ne 0 ] ; then
357   echo $com Runtime configuration is specified as the following list:
358   echo $com ' ' ${CONFIGURE_FILE}
359   echo $com Therefore, skipping automatic installation.
360
361 elif [ ! -f ${CONFIGURE_FILE} ]; then
362   echo $com Installing default configuration in ${CONFIGURE_FILE}
363   echo $com because there is no existing configuration file.
364   if [ "${SYSTEM_ALIASES_FILE}" = "" ] ; then
365     SYSTEM_ALIASES_FILE=/etc/aliases
366     echo $com This configuration has system aliases in ${SYSTEM_ALIASES_FILE}.
367   fi
368
369   echo ${MKDIR} -p `${DIRNAME} ${CONFIGURE_FILE}`
370   ${real} ${MKDIR} -p `${DIRNAME} ${CONFIGURE_FILE}`
371
372   echo sed -e '\\'
373   echo "  \"/SYSTEM_ALIASES_FILE/ s'SYSTEM_ALIASES_FILE'${ACTUAL_SYSTEM_ALIASES_FILE}'\"" '\\'
374   echo "  ../src/configure.default > \${CONFIGURE_FILE}"
375
376   # I can't find a way of writing this using the ${real} feature because
377   # it seems that the output redirection always happens, even when -n was
378   # specified. So control it the hard way.
379
380   if [ "$real" = "" ] ; then
381     sed -e \
382       "/SYSTEM_ALIASES_FILE/ s'SYSTEM_ALIASES_FILE'${ACTUAL_SYSTEM_ALIASES_FILE}'" \
383       ../src/configure.default > ${CONFIGURE_FILE}
384   else
385     true
386   fi
387
388   if [ $? -ne 0 ]; then
389     echo $com ""
390     echo $com "*** Exim installation ${ver}failed ***"
391     exit 1
392   fi
393   if [ ! -f ${SYSTEM_ALIASES_FILE} ]; then
394     echo $com '****'
395     echo $com Installing a dummy ${SYSTEM_ALIASES_FILE} file because you do not have
396     echo $com one, and the default configuration requires it. You should
397     echo $com edit ${SYSTEM_ALIASES_FILE} and at least create an alias for postmaster.
398     echo $com '***'
399     echo ${CP} ../src/aliases.default ${SYSTEM_ALIASES_FILE}
400     ${real} ${CP} ../src/aliases.default ${SYSTEM_ALIASES_FILE}
401   fi
402
403 else
404   echo $com Configuration file ${CONFIGURE_FILE} already exists
405 fi
406
407 # Install info files if the directory is defined and the Texinfo
408 # source documentation is present.
409
410 if [ "${INFO_DIRECTORY}" != "" -a -f ../doc/spec.texinfo ] ; then
411   echo $com ""
412   if [ ! -d "${INFO_DIRECTORY}" ] ; then
413     echo mkdir -p ${INFO_DIRECTORY}
414     ${real} mkdir -p ${INFO_DIRECTORY}
415     if [ $? -ne 0 ]; then
416       echo $com ""
417       echo $com "*** Exim installation ${ver}failed ***"
418       exit 1
419     else
420       echo $com ${INFO_DIRECTORY} created
421     fi
422   fi
423
424   echo $com Info installation directory is ${INFO_DIRECTORY}
425   echo $com ""
426
427   ${real} makeinfo --no-split --output exim.info ../doc/spec.texinfo
428   echo ${CP} exim.info ${INFO_DIRECTORY}
429   ${real} ${CP} exim.info ${INFO_DIRECTORY}
430   ${real} install-info --section="Exim" \
431       --entry "* User guide: (exim).           Exim manual" \
432       ${INFO_DIRECTORY}/exim.info ${INFO_DIRECTORY}/dir
433   ${real} makeinfo --no-split --output exim_filter.info ../doc/filter.texinfo
434   echo ${CP} exim_filter.info ${INFO_DIRECTORY}
435   ${real} ${CP} exim_filter.info ${INFO_DIRECTORY}
436   ${real} install-info --section="Exim" \
437       --entry "* Filtering: (exim_filter).     Filtering mail with Exim" \
438       ${INFO_DIRECTORY}/exim_filter.info ${INFO_DIRECTORY}/dir
439 fi
440
441 # Everything OK
442
443 echo $com ""
444 echo $com Exim installation ${ver}complete
445
446 # End of exim_install