1#!/bin/sh
2
3# mergemaster mtree database generator
4
5# This script is intended to be used as part of the release building
6# process to generate the /var/db/mergemaster.mtree file relevant to
7# the source tree used to create the release so that users can make
8# use of mergemaster's -U option to update their files after updating
9# to -stable.
10
11# Copyright 2009 Douglas Barton
12# dougb@FreeBSD.org
13
14PATH=/bin:/usr/bin:/usr/sbin
15
16display_usage () {
17  VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4`
18  echo "${0##*/} version ${VERSION_NUMBER}"
19  echo "Usage: ${0##*/} [-m /path] [-t /path] [-A arch] [-F <make args>] [-D /path]"
20  echo "Options:"
21  echo "  -m /path/directory  Specify location of source to do the make in"
22  echo "  -t /path/directory  Specify temp root directory"
23  echo "  -A architecture  Alternative architecture name to pass to make"
24  echo "  -F <arguments for make> Specify what to put on the make command line"
25  echo '  -D /path/directory  Specify the destination directory to install files to'
26  echo ''
27}
28
29# Set the default path for the temporary root environment
30#
31TEMPROOT=`TMPDIR=/var/tmp mktemp -d -t temproot`
32
33# Assign the location of the mtree database
34#
35MTREEDB=${MTREEDB:-/var/db}
36MTREEFILE="${MTREEDB}/mergemaster.mtree"
37
38# Check the command line options
39#
40while getopts "m:t:A:F:D:h" COMMAND_LINE_ARGUMENT ; do
41  case "${COMMAND_LINE_ARGUMENT}" in
42  m)
43    SOURCEDIR=${OPTARG}
44    ;;
45  t)
46    TEMPROOT=${OPTARG}
47    ;;
48  A)
49    ARCHSTRING='TARGET_ARCH='${OPTARG}
50    ;;
51  F)
52    MM_MAKE_ARGS="${OPTARG}"
53    ;;
54  D)
55    DESTDIR=${OPTARG}
56    ;;
57  h)
58    display_usage
59    exit 0
60    ;;
61  *)
62    echo ''
63    display_usage
64    exit 1
65    ;;
66  esac
67done
68
69# Assign the source directory
70#
71SOURCEDIR=${SOURCEDIR:-/usr/src}
72if [ ! -f ${SOURCEDIR}/Makefile.inc1 -a \
73   -f ${SOURCEDIR}/../Makefile.inc1 ]; then
74  echo " *** The source directory you specified (${SOURCEDIR})"
75  echo "     will be reset to ${SOURCEDIR}/.."
76  echo ''
77  sleep 3
78  SOURCEDIR=${SOURCEDIR}/..
79fi
80
81# Setup make to use system files from SOURCEDIR
82MM_MAKE="make ${ARCHSTRING} ${MM_MAKE_ARGS} -m ${SOURCEDIR}/share/mk -DDB_FROM_SRC"
83
84delete_temproot () {
85  rm -rf "${TEMPROOT}" 2>/dev/null
86  chflags -R 0 "${TEMPROOT}" 2>/dev/null
87  rm -rf "${TEMPROOT}" || exit 1
88}
89
90[ -d "${TEMPROOT}" ] && delete_temproot
91
92echo "*** Creating the temporary root environment in ${TEMPROOT}"
93
94if mkdir -p "${TEMPROOT}"; then
95  echo " *** ${TEMPROOT} ready for use"
96fi
97
98if [ ! -d "${TEMPROOT}" ]; then
99  echo ''
100  echo "  *** FATAL ERROR: Cannot create ${TEMPROOT}"
101  echo ''
102  exit 1
103fi
104
105echo " *** Creating and populating directory structure in ${TEMPROOT}"
106echo ''
107
108{ cd ${SOURCEDIR} || { echo "*** Cannot cd to ${SOURCEDIR}" ; exit 1;}
109  case "${DESTDIR}" in
110  '') ;;
111  *)
112    ${MM_MAKE} DESTDIR=${DESTDIR} distrib-dirs
113    ;;
114  esac
115  ${MM_MAKE} DESTDIR=${TEMPROOT} distrib-dirs &&
116  ${MM_MAKE} _obj SUBDIR_OVERRIDE=etc &&
117  ${MM_MAKE} everything SUBDIR_OVERRIDE=etc &&
118  ${MM_MAKE} DESTDIR=${TEMPROOT} distribution;} ||
119  { echo '';
120    echo "  *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to";
121    echo "      the temproot environment";
122    echo '';
123    exit 1;}
124
125# We really don't want to have to deal with files like login.conf.db, pwd.db,
126# or spwd.db.  Instead, we want to compare the text versions, and run *_mkdb.
127# Prompt the user to do so below, as needed.
128#
129rm -f ${TEMPROOT}/etc/*.db ${TEMPROOT}/etc/passwd
130
131# We only need to compare things like freebsd.cf once
132find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null
133
134# Delete stuff we do not need to keep the mtree database small,
135# and to make the actual comparison faster.
136find ${TEMPROOT}/usr -type l -delete 2>/dev/null
137find ${TEMPROOT} -type f -size 0 -delete 2>/dev/null
138find -d ${TEMPROOT} -type d -empty -delete 2>/dev/null
139
140# Build the mtree database in a temporary location.
141MTREENEW=`mktemp -t mergemaster.mtree`
142mtree -nci -p ${TEMPROOT} -k size,md5digest > ${MTREENEW} 2>/dev/null
143
144if [ -s "${MTREENEW}" ]; then
145  echo "*** Saving mtree database for future upgrades"
146  test -e "${DESTDIR}${MTREEFILE}" && unlink ${DESTDIR}${MTREEFILE}
147  mv ${MTREENEW} ${DESTDIR}${MTREEFILE}
148fi
149
150delete_temproot
151
152exit 0
153