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