148ffe56aSColin Percival#!/bin/sh 248ffe56aSColin Percival 348ffe56aSColin Percival#- 41de7b4b8SPedro F. Giffuni# SPDX-License-Identifier: BSD-2-Clause-FreeBSD 51de7b4b8SPedro F. Giffuni# 62328d598SColin Percival# Copyright 2004-2007 Colin Percival 748ffe56aSColin Percival# All rights reserved 848ffe56aSColin Percival# 948ffe56aSColin Percival# Redistribution and use in source and binary forms, with or without 1048ffe56aSColin Percival# modification, are permitted providing that the following conditions 1148ffe56aSColin Percival# are met: 1248ffe56aSColin Percival# 1. Redistributions of source code must retain the above copyright 1348ffe56aSColin Percival# notice, this list of conditions and the following disclaimer. 1448ffe56aSColin Percival# 2. Redistributions in binary form must reproduce the above copyright 1548ffe56aSColin Percival# notice, this list of conditions and the following disclaimer in the 1648ffe56aSColin Percival# documentation and/or other materials provided with the distribution. 1748ffe56aSColin Percival# 1848ffe56aSColin Percival# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1948ffe56aSColin Percival# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 2048ffe56aSColin Percival# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2148ffe56aSColin Percival# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 2248ffe56aSColin Percival# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2348ffe56aSColin Percival# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2448ffe56aSColin Percival# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2548ffe56aSColin Percival# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 2648ffe56aSColin Percival# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 2748ffe56aSColin Percival# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2848ffe56aSColin Percival# POSSIBILITY OF SUCH DAMAGE. 2948ffe56aSColin Percival 3048ffe56aSColin Percival# $FreeBSD$ 3148ffe56aSColin Percival 3248ffe56aSColin Percival#### Usage function -- called from command-line handling code. 3348ffe56aSColin Percival 3448ffe56aSColin Percival# Usage instructions. Options not listed: 3548ffe56aSColin Percival# --debug -- don't filter output from utilities 3648ffe56aSColin Percival# --no-stats -- don't show progress statistics while fetching files 3748ffe56aSColin Percivalusage () { 3848ffe56aSColin Percival cat <<EOF 39c76da1f0SFaraz Vahediusage: `basename $0` [options] command ... 4048ffe56aSColin Percival 4148ffe56aSColin PercivalOptions: 4248ffe56aSColin Percival -b basedir -- Operate on a system mounted at basedir 4348ffe56aSColin Percival (default: /) 4448ffe56aSColin Percival -d workdir -- Store working files in workdir 4548ffe56aSColin Percival (default: /var/db/freebsd-update/) 4648ffe56aSColin Percival -f conffile -- Read configuration options from conffile 4748ffe56aSColin Percival (default: /etc/freebsd-update.conf) 48df7e2e0dSEd Maste -F -- Force a fetch operation to proceed in the 49df7e2e0dSEd Maste case of an unfinished upgrade 50c76da1f0SFaraz Vahedi -j jail -- Operate on the given jail specified by jid or name 5148ffe56aSColin Percival -k KEY -- Trust an RSA key with SHA256 hash of KEY 52dd917c79SGleb Smirnoff -r release -- Target for upgrade (e.g., 11.1-RELEASE) 5348ffe56aSColin Percival -s server -- Server from which to fetch updates 5448ffe56aSColin Percival (default: update.FreeBSD.org) 5548ffe56aSColin Percival -t address -- Mail output of cron command, if any, to address 5648ffe56aSColin Percival (default: root) 578935f242SAllan Jude --not-running-from-cron 588935f242SAllan Jude -- Run without a tty, for use by automated tools 59b39ce43eSColin Percival --currently-running release 60b39ce43eSColin Percival -- Update as if currently running this release 6148ffe56aSColin PercivalCommands: 6248ffe56aSColin Percival fetch -- Fetch updates from server 6348ffe56aSColin Percival cron -- Sleep rand(3600) seconds, fetch updates, and send an 6448ffe56aSColin Percival email if updates were found 65db6b0a61SColin Percival upgrade -- Fetch upgrades to FreeBSD version specified via -r option 668cfda118SMichael Gmelin updatesready -- Check if there are fetched updates ready to install 67db6b0a61SColin Percival install -- Install downloaded updates or upgrades 6848ffe56aSColin Percival rollback -- Uninstall most recently installed updates 6975cb6429SEd Maste IDS -- Compare the system against an index of "known good" files 708cfda118SMichael Gmelin showconfig -- Show configuration 7148ffe56aSColin PercivalEOF 7248ffe56aSColin Percival exit 0 7348ffe56aSColin Percival} 7448ffe56aSColin Percival 7548ffe56aSColin Percival#### Configuration processing functions 7648ffe56aSColin Percival 7748ffe56aSColin Percival#- 7848ffe56aSColin Percival# Configuration options are set in the following order of priority: 7948ffe56aSColin Percival# 1. Command line options 8048ffe56aSColin Percival# 2. Configuration file options 8148ffe56aSColin Percival# 3. Default options 8248ffe56aSColin Percival# In addition, certain options (e.g., IgnorePaths) can be specified multiple 8348ffe56aSColin Percival# times and (as long as these are all in the same place, e.g., inside the 8448ffe56aSColin Percival# configuration file) they will accumulate. Finally, because the path to the 8548ffe56aSColin Percival# configuration file can be specified at the command line, the entire command 8648ffe56aSColin Percival# line must be processed before we start reading the configuration file. 8748ffe56aSColin Percival# 8848ffe56aSColin Percival# Sound like a mess? It is. Here's how we handle this: 8948ffe56aSColin Percival# 1. Initialize CONFFILE and all the options to "". 9048ffe56aSColin Percival# 2. Process the command line. Throw an error if a non-accumulating option 9148ffe56aSColin Percival# is specified twice. 9248ffe56aSColin Percival# 3. If CONFFILE is "", set CONFFILE to /etc/freebsd-update.conf . 9348ffe56aSColin Percival# 4. For all the configuration options X, set X_saved to X. 9448ffe56aSColin Percival# 5. Initialize all the options to "". 9548ffe56aSColin Percival# 6. Read CONFFILE line by line, parsing options. 9648ffe56aSColin Percival# 7. For each configuration option X, set X to X_saved iff X_saved is not "". 9748ffe56aSColin Percival# 8. Repeat steps 4-7, except setting options to their default values at (6). 9848ffe56aSColin Percival 9948ffe56aSColin PercivalCONFIGOPTIONS="KEYPRINT WORKDIR SERVERNAME MAILTO ALLOWADD ALLOWDELETE 10048ffe56aSColin Percival KEEPMODIFIEDMETADATA COMPONENTS IGNOREPATHS UPDATEIFUNMODIFIED 10108e23beeSColin Percival BASEDIR VERBOSELEVEL TARGETRELEASE STRICTCOMPONENTS MERGECHANGES 10223d827efSSimon L. B. Nielsen IDSIGNOREPATHS BACKUPKERNEL BACKUPKERNELDIR BACKUPKERNELSYMBOLFILES" 10348ffe56aSColin Percival 10448ffe56aSColin Percival# Set all the configuration options to "". 10548ffe56aSColin Percivalnullconfig () { 10648ffe56aSColin Percival for X in ${CONFIGOPTIONS}; do 10748ffe56aSColin Percival eval ${X}="" 10848ffe56aSColin Percival done 10948ffe56aSColin Percival} 11048ffe56aSColin Percival 11148ffe56aSColin Percival# For each configuration option X, set X_saved to X. 11248ffe56aSColin Percivalsaveconfig () { 11348ffe56aSColin Percival for X in ${CONFIGOPTIONS}; do 11448ffe56aSColin Percival eval ${X}_saved=\$${X} 11548ffe56aSColin Percival done 11648ffe56aSColin Percival} 11748ffe56aSColin Percival 11848ffe56aSColin Percival# For each configuration option X, set X to X_saved if X_saved is not "". 11948ffe56aSColin Percivalmergeconfig () { 12048ffe56aSColin Percival for X in ${CONFIGOPTIONS}; do 12148ffe56aSColin Percival eval _=\$${X}_saved 12248ffe56aSColin Percival if ! [ -z "${_}" ]; then 12348ffe56aSColin Percival eval ${X}=\$${X}_saved 12448ffe56aSColin Percival fi 12548ffe56aSColin Percival done 12648ffe56aSColin Percival} 12748ffe56aSColin Percival 12848ffe56aSColin Percival# Set the trusted keyprint. 12948ffe56aSColin Percivalconfig_KeyPrint () { 13048ffe56aSColin Percival if [ -z ${KEYPRINT} ]; then 13148ffe56aSColin Percival KEYPRINT=$1 13248ffe56aSColin Percival else 13348ffe56aSColin Percival return 1 13448ffe56aSColin Percival fi 13548ffe56aSColin Percival} 13648ffe56aSColin Percival 13748ffe56aSColin Percival# Set the working directory. 13848ffe56aSColin Percivalconfig_WorkDir () { 13948ffe56aSColin Percival if [ -z ${WORKDIR} ]; then 14048ffe56aSColin Percival WORKDIR=$1 14148ffe56aSColin Percival else 14248ffe56aSColin Percival return 1 14348ffe56aSColin Percival fi 14448ffe56aSColin Percival} 14548ffe56aSColin Percival 14648ffe56aSColin Percival# Set the name of the server (pool) from which to fetch updates 14748ffe56aSColin Percivalconfig_ServerName () { 14848ffe56aSColin Percival if [ -z ${SERVERNAME} ]; then 14948ffe56aSColin Percival SERVERNAME=$1 15048ffe56aSColin Percival else 15148ffe56aSColin Percival return 1 15248ffe56aSColin Percival fi 15348ffe56aSColin Percival} 15448ffe56aSColin Percival 15548ffe56aSColin Percival# Set the address to which 'cron' output will be mailed. 15648ffe56aSColin Percivalconfig_MailTo () { 15748ffe56aSColin Percival if [ -z ${MAILTO} ]; then 15848ffe56aSColin Percival MAILTO=$1 15948ffe56aSColin Percival else 16048ffe56aSColin Percival return 1 16148ffe56aSColin Percival fi 16248ffe56aSColin Percival} 16348ffe56aSColin Percival 16448ffe56aSColin Percival# Set whether FreeBSD Update is allowed to add files (or directories, or 16548ffe56aSColin Percival# symlinks) which did not previously exist. 16648ffe56aSColin Percivalconfig_AllowAdd () { 16748ffe56aSColin Percival if [ -z ${ALLOWADD} ]; then 16848ffe56aSColin Percival case $1 in 16948ffe56aSColin Percival [Yy][Ee][Ss]) 17048ffe56aSColin Percival ALLOWADD=yes 17148ffe56aSColin Percival ;; 17248ffe56aSColin Percival [Nn][Oo]) 17348ffe56aSColin Percival ALLOWADD=no 17448ffe56aSColin Percival ;; 17548ffe56aSColin Percival *) 17648ffe56aSColin Percival return 1 17748ffe56aSColin Percival ;; 17848ffe56aSColin Percival esac 17948ffe56aSColin Percival else 18048ffe56aSColin Percival return 1 18148ffe56aSColin Percival fi 18248ffe56aSColin Percival} 18348ffe56aSColin Percival 18448ffe56aSColin Percival# Set whether FreeBSD Update is allowed to remove files/directories/symlinks. 18548ffe56aSColin Percivalconfig_AllowDelete () { 18648ffe56aSColin Percival if [ -z ${ALLOWDELETE} ]; then 18748ffe56aSColin Percival case $1 in 18848ffe56aSColin Percival [Yy][Ee][Ss]) 18948ffe56aSColin Percival ALLOWDELETE=yes 19048ffe56aSColin Percival ;; 19148ffe56aSColin Percival [Nn][Oo]) 19248ffe56aSColin Percival ALLOWDELETE=no 19348ffe56aSColin Percival ;; 19448ffe56aSColin Percival *) 19548ffe56aSColin Percival return 1 19648ffe56aSColin Percival ;; 19748ffe56aSColin Percival esac 19848ffe56aSColin Percival else 19948ffe56aSColin Percival return 1 20048ffe56aSColin Percival fi 20148ffe56aSColin Percival} 20248ffe56aSColin Percival 20348ffe56aSColin Percival# Set whether FreeBSD Update should keep existing inode ownership, 20448ffe56aSColin Percival# permissions, and flags, in the event that they have been modified locally 20548ffe56aSColin Percival# after the release. 20648ffe56aSColin Percivalconfig_KeepModifiedMetadata () { 20748ffe56aSColin Percival if [ -z ${KEEPMODIFIEDMETADATA} ]; then 20848ffe56aSColin Percival case $1 in 20948ffe56aSColin Percival [Yy][Ee][Ss]) 21048ffe56aSColin Percival KEEPMODIFIEDMETADATA=yes 21148ffe56aSColin Percival ;; 21248ffe56aSColin Percival [Nn][Oo]) 21348ffe56aSColin Percival KEEPMODIFIEDMETADATA=no 21448ffe56aSColin Percival ;; 21548ffe56aSColin Percival *) 21648ffe56aSColin Percival return 1 21748ffe56aSColin Percival ;; 21848ffe56aSColin Percival esac 21948ffe56aSColin Percival else 22048ffe56aSColin Percival return 1 22148ffe56aSColin Percival fi 22248ffe56aSColin Percival} 22348ffe56aSColin Percival 22448ffe56aSColin Percival# Add to the list of components which should be kept updated. 22548ffe56aSColin Percivalconfig_Components () { 22648ffe56aSColin Percival for C in $@; do 22712294db4SMichael Gmelin COMPONENTS="${COMPONENTS} ${C}" 22812294db4SMichael Gmelin done 22912294db4SMichael Gmelin} 23012294db4SMichael Gmelin 23112294db4SMichael Gmelin# Remove src component from list if it isn't installed 23212294db4SMichael Gmelinfinalize_components_config () { 23312294db4SMichael Gmelin COMPONENTS="" 23412294db4SMichael Gmelin for C in $@; do 2355a74378cSXin LI if [ "$C" = "src" ]; then 236cfd9be9cSEd Maste if [ -e "${BASEDIR}/usr/src/COPYRIGHT" ]; then 23748ffe56aSColin Percival COMPONENTS="${COMPONENTS} ${C}" 2385a74378cSXin LI else 2395a74378cSXin LI echo "src component not installed, skipped" 2405a74378cSXin LI fi 2415a74378cSXin LI else 2425a74378cSXin LI COMPONENTS="${COMPONENTS} ${C}" 2435a74378cSXin LI fi 24448ffe56aSColin Percival done 24548ffe56aSColin Percival} 24648ffe56aSColin Percival 24748ffe56aSColin Percival# Add to the list of paths under which updates will be ignored. 24848ffe56aSColin Percivalconfig_IgnorePaths () { 24948ffe56aSColin Percival for C in $@; do 25048ffe56aSColin Percival IGNOREPATHS="${IGNOREPATHS} ${C}" 25148ffe56aSColin Percival done 25248ffe56aSColin Percival} 25348ffe56aSColin Percival 25408e23beeSColin Percival# Add to the list of paths which IDS should ignore. 25508e23beeSColin Percivalconfig_IDSIgnorePaths () { 25608e23beeSColin Percival for C in $@; do 25708e23beeSColin Percival IDSIGNOREPATHS="${IDSIGNOREPATHS} ${C}" 25808e23beeSColin Percival done 25908e23beeSColin Percival} 26008e23beeSColin Percival 26148ffe56aSColin Percival# Add to the list of paths within which updates will be performed only if the 26248ffe56aSColin Percival# file on disk has not been modified locally. 26348ffe56aSColin Percivalconfig_UpdateIfUnmodified () { 26448ffe56aSColin Percival for C in $@; do 26548ffe56aSColin Percival UPDATEIFUNMODIFIED="${UPDATEIFUNMODIFIED} ${C}" 26648ffe56aSColin Percival done 26748ffe56aSColin Percival} 26848ffe56aSColin Percival 269db6b0a61SColin Percival# Add to the list of paths within which updates to text files will be merged 270db6b0a61SColin Percival# instead of overwritten. 271db6b0a61SColin Percivalconfig_MergeChanges () { 272db6b0a61SColin Percival for C in $@; do 273db6b0a61SColin Percival MERGECHANGES="${MERGECHANGES} ${C}" 274db6b0a61SColin Percival done 275db6b0a61SColin Percival} 276db6b0a61SColin Percival 27748ffe56aSColin Percival# Work on a FreeBSD installation mounted under $1 27848ffe56aSColin Percivalconfig_BaseDir () { 27948ffe56aSColin Percival if [ -z ${BASEDIR} ]; then 28048ffe56aSColin Percival BASEDIR=$1 28148ffe56aSColin Percival else 28248ffe56aSColin Percival return 1 28348ffe56aSColin Percival fi 28448ffe56aSColin Percival} 28548ffe56aSColin Percival 286db6b0a61SColin Percival# When fetching upgrades, should we assume the user wants exactly the 287db6b0a61SColin Percival# components listed in COMPONENTS, rather than trying to guess based on 288db6b0a61SColin Percival# what's currently installed? 289db6b0a61SColin Percivalconfig_StrictComponents () { 290db6b0a61SColin Percival if [ -z ${STRICTCOMPONENTS} ]; then 291db6b0a61SColin Percival case $1 in 292db6b0a61SColin Percival [Yy][Ee][Ss]) 293db6b0a61SColin Percival STRICTCOMPONENTS=yes 294db6b0a61SColin Percival ;; 295db6b0a61SColin Percival [Nn][Oo]) 296db6b0a61SColin Percival STRICTCOMPONENTS=no 297db6b0a61SColin Percival ;; 298db6b0a61SColin Percival *) 299db6b0a61SColin Percival return 1 300db6b0a61SColin Percival ;; 301db6b0a61SColin Percival esac 302db6b0a61SColin Percival else 303db6b0a61SColin Percival return 1 304db6b0a61SColin Percival fi 305db6b0a61SColin Percival} 306db6b0a61SColin Percival 307db6b0a61SColin Percival# Upgrade to FreeBSD $1 308db6b0a61SColin Percivalconfig_TargetRelease () { 309db6b0a61SColin Percival if [ -z ${TARGETRELEASE} ]; then 310db6b0a61SColin Percival TARGETRELEASE=$1 311db6b0a61SColin Percival else 312db6b0a61SColin Percival return 1 313db6b0a61SColin Percival fi 314d23dc1eeSColin Percival if echo ${TARGETRELEASE} | grep -qE '^[0-9.]+$'; then 315d23dc1eeSColin Percival TARGETRELEASE="${TARGETRELEASE}-RELEASE" 316d23dc1eeSColin Percival fi 317db6b0a61SColin Percival} 318db6b0a61SColin Percival 3190d5c5243SEd Maste# Pretend current release is FreeBSD $1 3200d5c5243SEd Masteconfig_SourceRelease () { 3210d5c5243SEd Maste UNAME_r=$1 3220d5c5243SEd Maste if echo ${UNAME_r} | grep -qE '^[0-9.]+$'; then 3230d5c5243SEd Maste UNAME_r="${UNAME_r}-RELEASE" 3240d5c5243SEd Maste fi 325b958d4b2SEd Maste export UNAME_r 3260d5c5243SEd Maste} 3270d5c5243SEd Maste 328c76da1f0SFaraz Vahedi# Get the Jail's path and the version of its installed userland 329c76da1f0SFaraz Vahediconfig_TargetJail () { 330c76da1f0SFaraz Vahedi JAIL=$1 331c76da1f0SFaraz Vahedi UNAME_r=$(freebsd-version -j ${JAIL}) 332c76da1f0SFaraz Vahedi BASEDIR=$(jls -j ${JAIL} -h path | awk 'NR == 2 {print}') 333c76da1f0SFaraz Vahedi if [ -z ${BASEDIR} ] || [ -z ${UNAME_r} ]; then 334c76da1f0SFaraz Vahedi echo "The specified jail either doesn't exist or" \ 335c76da1f0SFaraz Vahedi "does not have freebsd-version." 336c76da1f0SFaraz Vahedi exit 1 337c76da1f0SFaraz Vahedi fi 338c76da1f0SFaraz Vahedi export UNAME_r 339c76da1f0SFaraz Vahedi} 340c76da1f0SFaraz Vahedi 34148ffe56aSColin Percival# Define what happens to output of utilities 34248ffe56aSColin Percivalconfig_VerboseLevel () { 34348ffe56aSColin Percival if [ -z ${VERBOSELEVEL} ]; then 34448ffe56aSColin Percival case $1 in 34548ffe56aSColin Percival [Dd][Ee][Bb][Uu][Gg]) 34648ffe56aSColin Percival VERBOSELEVEL=debug 34748ffe56aSColin Percival ;; 34848ffe56aSColin Percival [Nn][Oo][Ss][Tt][Aa][Tt][Ss]) 34948ffe56aSColin Percival VERBOSELEVEL=nostats 35048ffe56aSColin Percival ;; 35148ffe56aSColin Percival [Ss][Tt][Aa][Tt][Ss]) 35248ffe56aSColin Percival VERBOSELEVEL=stats 35348ffe56aSColin Percival ;; 35448ffe56aSColin Percival *) 35548ffe56aSColin Percival return 1 35648ffe56aSColin Percival ;; 35748ffe56aSColin Percival esac 35848ffe56aSColin Percival else 35948ffe56aSColin Percival return 1 36048ffe56aSColin Percival fi 36148ffe56aSColin Percival} 36248ffe56aSColin Percival 36323d827efSSimon L. B. Nielsenconfig_BackupKernel () { 36423d827efSSimon L. B. Nielsen if [ -z ${BACKUPKERNEL} ]; then 36523d827efSSimon L. B. Nielsen case $1 in 36623d827efSSimon L. B. Nielsen [Yy][Ee][Ss]) 36723d827efSSimon L. B. Nielsen BACKUPKERNEL=yes 36823d827efSSimon L. B. Nielsen ;; 36923d827efSSimon L. B. Nielsen [Nn][Oo]) 37023d827efSSimon L. B. Nielsen BACKUPKERNEL=no 37123d827efSSimon L. B. Nielsen ;; 37223d827efSSimon L. B. Nielsen *) 37323d827efSSimon L. B. Nielsen return 1 37423d827efSSimon L. B. Nielsen ;; 37523d827efSSimon L. B. Nielsen esac 37623d827efSSimon L. B. Nielsen else 37723d827efSSimon L. B. Nielsen return 1 37823d827efSSimon L. B. Nielsen fi 37923d827efSSimon L. B. Nielsen} 38023d827efSSimon L. B. Nielsen 38123d827efSSimon L. B. Nielsenconfig_BackupKernelDir () { 38223d827efSSimon L. B. Nielsen if [ -z ${BACKUPKERNELDIR} ]; then 38323d827efSSimon L. B. Nielsen if [ -z "$1" ]; then 38423d827efSSimon L. B. Nielsen echo "BackupKernelDir set to empty dir" 38523d827efSSimon L. B. Nielsen return 1 38623d827efSSimon L. B. Nielsen fi 38723d827efSSimon L. B. Nielsen 38823d827efSSimon L. B. Nielsen # We check for some paths which would be extremely odd 38923d827efSSimon L. B. Nielsen # to use, but which could cause a lot of problems if 39023d827efSSimon L. B. Nielsen # used. 39123d827efSSimon L. B. Nielsen case $1 in 39223d827efSSimon L. B. Nielsen /|/bin|/boot|/etc|/lib|/libexec|/sbin|/usr|/var) 39323d827efSSimon L. B. Nielsen echo "BackupKernelDir set to invalid path $1" 39423d827efSSimon L. B. Nielsen return 1 39523d827efSSimon L. B. Nielsen ;; 39623d827efSSimon L. B. Nielsen /*) 39723d827efSSimon L. B. Nielsen BACKUPKERNELDIR=$1 39823d827efSSimon L. B. Nielsen ;; 39923d827efSSimon L. B. Nielsen *) 40023d827efSSimon L. B. Nielsen echo "BackupKernelDir ($1) is not an absolute path" 40123d827efSSimon L. B. Nielsen return 1 40223d827efSSimon L. B. Nielsen ;; 40323d827efSSimon L. B. Nielsen esac 40423d827efSSimon L. B. Nielsen else 40523d827efSSimon L. B. Nielsen return 1 40623d827efSSimon L. B. Nielsen fi 40723d827efSSimon L. B. Nielsen} 40823d827efSSimon L. B. Nielsen 40923d827efSSimon L. B. Nielsenconfig_BackupKernelSymbolFiles () { 41023d827efSSimon L. B. Nielsen if [ -z ${BACKUPKERNELSYMBOLFILES} ]; then 41123d827efSSimon L. B. Nielsen case $1 in 41223d827efSSimon L. B. Nielsen [Yy][Ee][Ss]) 41323d827efSSimon L. B. Nielsen BACKUPKERNELSYMBOLFILES=yes 41423d827efSSimon L. B. Nielsen ;; 41523d827efSSimon L. B. Nielsen [Nn][Oo]) 41623d827efSSimon L. B. Nielsen BACKUPKERNELSYMBOLFILES=no 41723d827efSSimon L. B. Nielsen ;; 41823d827efSSimon L. B. Nielsen *) 41923d827efSSimon L. B. Nielsen return 1 42023d827efSSimon L. B. Nielsen ;; 42123d827efSSimon L. B. Nielsen esac 42223d827efSSimon L. B. Nielsen else 42323d827efSSimon L. B. Nielsen return 1 42423d827efSSimon L. B. Nielsen fi 42523d827efSSimon L. B. Nielsen} 42623d827efSSimon L. B. Nielsen 427f28f1389SDave Fullardconfig_CreateBootEnv () { 428f28f1389SDave Fullard if [ -z ${BOOTENV} ]; then 429f28f1389SDave Fullard case $1 in 430f28f1389SDave Fullard [Yy][Ee][Ss]) 431f28f1389SDave Fullard BOOTENV=yes 432f28f1389SDave Fullard ;; 433f28f1389SDave Fullard [Nn][Oo]) 434f28f1389SDave Fullard BOOTENV=no 435f28f1389SDave Fullard ;; 436f28f1389SDave Fullard *) 437f28f1389SDave Fullard return 1 438f28f1389SDave Fullard ;; 439f28f1389SDave Fullard esac 440f28f1389SDave Fullard else 441f28f1389SDave Fullard return 1 442f28f1389SDave Fullard fi 443f28f1389SDave Fullard} 44448ffe56aSColin Percival# Handle one line of configuration 44548ffe56aSColin Percivalconfigline () { 44648ffe56aSColin Percival if [ $# -eq 0 ]; then 44748ffe56aSColin Percival return 44848ffe56aSColin Percival fi 44948ffe56aSColin Percival 45048ffe56aSColin Percival OPT=$1 45148ffe56aSColin Percival shift 45248ffe56aSColin Percival config_${OPT} $@ 45348ffe56aSColin Percival} 45448ffe56aSColin Percival 45548ffe56aSColin Percival#### Parameter handling functions. 45648ffe56aSColin Percival 45748ffe56aSColin Percival# Initialize parameters to null, just in case they're 45848ffe56aSColin Percival# set in the environment. 45948ffe56aSColin Percivalinit_params () { 46048ffe56aSColin Percival # Configration settings 46148ffe56aSColin Percival nullconfig 46248ffe56aSColin Percival 46348ffe56aSColin Percival # No configuration file set yet 46448ffe56aSColin Percival CONFFILE="" 46548ffe56aSColin Percival 46648ffe56aSColin Percival # No commands specified yet 46748ffe56aSColin Percival COMMANDS="" 4688935f242SAllan Jude 4698935f242SAllan Jude # Force fetch to proceed 4708935f242SAllan Jude FORCEFETCH=0 4718935f242SAllan Jude 4728935f242SAllan Jude # Run without a TTY 4738935f242SAllan Jude NOTTYOK=0 47433bd05c3SGuangyuan Yang 47533bd05c3SGuangyuan Yang # Fetched first in a chain of commands 47633bd05c3SGuangyuan Yang ISFETCHED=0 47748ffe56aSColin Percival} 47848ffe56aSColin Percival 47948ffe56aSColin Percival# Parse the command line 48048ffe56aSColin Percivalparse_cmdline () { 48148ffe56aSColin Percival while [ $# -gt 0 ]; do 48248ffe56aSColin Percival case "$1" in 48348ffe56aSColin Percival # Location of configuration file 48448ffe56aSColin Percival -f) 48548ffe56aSColin Percival if [ $# -eq 1 ]; then usage; fi 48648ffe56aSColin Percival if [ ! -z "${CONFFILE}" ]; then usage; fi 48748ffe56aSColin Percival shift; CONFFILE="$1" 48848ffe56aSColin Percival ;; 4898935f242SAllan Jude -F) 4908935f242SAllan Jude FORCEFETCH=1 4918935f242SAllan Jude ;; 4928935f242SAllan Jude --not-running-from-cron) 4938935f242SAllan Jude NOTTYOK=1 4948935f242SAllan Jude ;; 495b39ce43eSColin Percival --currently-running) 4960d5c5243SEd Maste shift 4970d5c5243SEd Maste config_SourceRelease $1 || usage 498b39ce43eSColin Percival ;; 49948ffe56aSColin Percival 50048ffe56aSColin Percival # Configuration file equivalents 50148ffe56aSColin Percival -b) 50248ffe56aSColin Percival if [ $# -eq 1 ]; then usage; fi; shift 50348ffe56aSColin Percival config_BaseDir $1 || usage 50448ffe56aSColin Percival ;; 50548ffe56aSColin Percival -d) 50648ffe56aSColin Percival if [ $# -eq 1 ]; then usage; fi; shift 50748ffe56aSColin Percival config_WorkDir $1 || usage 50848ffe56aSColin Percival ;; 509c76da1f0SFaraz Vahedi -j) 510c76da1f0SFaraz Vahedi if [ $# -eq 1 ]; then usage; fi; shift 511c76da1f0SFaraz Vahedi config_TargetJail $1 || usage 512c76da1f0SFaraz Vahedi ;; 51348ffe56aSColin Percival -k) 51448ffe56aSColin Percival if [ $# -eq 1 ]; then usage; fi; shift 51548ffe56aSColin Percival config_KeyPrint $1 || usage 51648ffe56aSColin Percival ;; 51748ffe56aSColin Percival -s) 51848ffe56aSColin Percival if [ $# -eq 1 ]; then usage; fi; shift 51948ffe56aSColin Percival config_ServerName $1 || usage 52048ffe56aSColin Percival ;; 521db6b0a61SColin Percival -r) 522db6b0a61SColin Percival if [ $# -eq 1 ]; then usage; fi; shift 523db6b0a61SColin Percival config_TargetRelease $1 || usage 524db6b0a61SColin Percival ;; 52548ffe56aSColin Percival -t) 52648ffe56aSColin Percival if [ $# -eq 1 ]; then usage; fi; shift 52748ffe56aSColin Percival config_MailTo $1 || usage 52848ffe56aSColin Percival ;; 52948ffe56aSColin Percival -v) 53048ffe56aSColin Percival if [ $# -eq 1 ]; then usage; fi; shift 53148ffe56aSColin Percival config_VerboseLevel $1 || usage 53248ffe56aSColin Percival ;; 53348ffe56aSColin Percival 53448ffe56aSColin Percival # Aliases for "-v debug" and "-v nostats" 53548ffe56aSColin Percival --debug) 53648ffe56aSColin Percival config_VerboseLevel debug || usage 53748ffe56aSColin Percival ;; 53848ffe56aSColin Percival --no-stats) 53948ffe56aSColin Percival config_VerboseLevel nostats || usage 54048ffe56aSColin Percival ;; 54148ffe56aSColin Percival 54248ffe56aSColin Percival # Commands 5438cfda118SMichael Gmelin cron | fetch | upgrade | updatesready | install | rollback |\ 5448cfda118SMichael Gmelin IDS | showconfig) 54548ffe56aSColin Percival COMMANDS="${COMMANDS} $1" 54648ffe56aSColin Percival ;; 54748ffe56aSColin Percival 54848ffe56aSColin Percival # Anything else is an error 54948ffe56aSColin Percival *) 55048ffe56aSColin Percival usage 55148ffe56aSColin Percival ;; 55248ffe56aSColin Percival esac 55348ffe56aSColin Percival shift 55448ffe56aSColin Percival done 55548ffe56aSColin Percival 55648ffe56aSColin Percival # Make sure we have at least one command 55748ffe56aSColin Percival if [ -z "${COMMANDS}" ]; then 55848ffe56aSColin Percival usage 55948ffe56aSColin Percival fi 56048ffe56aSColin Percival} 56148ffe56aSColin Percival 56248ffe56aSColin Percival# Parse the configuration file 56348ffe56aSColin Percivalparse_conffile () { 56448ffe56aSColin Percival # If a configuration file was specified on the command line, check 56548ffe56aSColin Percival # that it exists and is readable. 56648ffe56aSColin Percival if [ ! -z "${CONFFILE}" ] && [ ! -r "${CONFFILE}" ]; then 56748ffe56aSColin Percival echo -n "File does not exist " 56848ffe56aSColin Percival echo -n "or is not readable: " 56948ffe56aSColin Percival echo ${CONFFILE} 57048ffe56aSColin Percival exit 1 57148ffe56aSColin Percival fi 57248ffe56aSColin Percival 57348ffe56aSColin Percival # If a configuration file was not specified on the command line, 57448ffe56aSColin Percival # use the default configuration file path. If that default does 57548ffe56aSColin Percival # not exist, give up looking for any configuration. 57648ffe56aSColin Percival if [ -z "${CONFFILE}" ]; then 57748ffe56aSColin Percival CONFFILE="/etc/freebsd-update.conf" 57848ffe56aSColin Percival if [ ! -r "${CONFFILE}" ]; then 57948ffe56aSColin Percival return 58048ffe56aSColin Percival fi 58148ffe56aSColin Percival fi 58248ffe56aSColin Percival 58348ffe56aSColin Percival # Save the configuration options specified on the command line, and 58448ffe56aSColin Percival # clear all the options in preparation for reading the config file. 58548ffe56aSColin Percival saveconfig 58648ffe56aSColin Percival nullconfig 58748ffe56aSColin Percival 58848ffe56aSColin Percival # Read the configuration file. Anything after the first '#' is 58948ffe56aSColin Percival # ignored, and any blank lines are ignored. 59048ffe56aSColin Percival L=0 59148ffe56aSColin Percival while read LINE; do 59248ffe56aSColin Percival L=$(($L + 1)) 59348ffe56aSColin Percival LINEX=`echo "${LINE}" | cut -f 1 -d '#'` 59448ffe56aSColin Percival if ! configline ${LINEX}; then 59548ffe56aSColin Percival echo "Error processing configuration file, line $L:" 59648ffe56aSColin Percival echo "==> ${LINE}" 59748ffe56aSColin Percival exit 1 59848ffe56aSColin Percival fi 59948ffe56aSColin Percival done < ${CONFFILE} 60048ffe56aSColin Percival 60148ffe56aSColin Percival # Merge the settings read from the configuration file with those 60248ffe56aSColin Percival # provided at the command line. 60348ffe56aSColin Percival mergeconfig 60448ffe56aSColin Percival} 60548ffe56aSColin Percival 60648ffe56aSColin Percival# Provide some default parameters 60748ffe56aSColin Percivaldefault_params () { 60848ffe56aSColin Percival # Save any parameters already configured, and clear the slate 60948ffe56aSColin Percival saveconfig 61048ffe56aSColin Percival nullconfig 61148ffe56aSColin Percival 61248ffe56aSColin Percival # Default configurations 61348ffe56aSColin Percival config_WorkDir /var/db/freebsd-update 61448ffe56aSColin Percival config_MailTo root 61548ffe56aSColin Percival config_AllowAdd yes 61648ffe56aSColin Percival config_AllowDelete yes 61748ffe56aSColin Percival config_KeepModifiedMetadata yes 61848ffe56aSColin Percival config_BaseDir / 61948ffe56aSColin Percival config_VerboseLevel stats 620db6b0a61SColin Percival config_StrictComponents no 62123d827efSSimon L. B. Nielsen config_BackupKernel yes 62223d827efSSimon L. B. Nielsen config_BackupKernelDir /boot/kernel.old 62323d827efSSimon L. B. Nielsen config_BackupKernelSymbolFiles no 624f28f1389SDave Fullard config_CreateBootEnv yes 62548ffe56aSColin Percival 62648ffe56aSColin Percival # Merge these defaults into the earlier-configured settings 62748ffe56aSColin Percival mergeconfig 62848ffe56aSColin Percival} 62948ffe56aSColin Percival 63048ffe56aSColin Percival# Set utility output filtering options, based on ${VERBOSELEVEL} 63148ffe56aSColin Percivalfetch_setup_verboselevel () { 63248ffe56aSColin Percival case ${VERBOSELEVEL} in 63348ffe56aSColin Percival debug) 63448ffe56aSColin Percival QUIETREDIR="/dev/stderr" 63548ffe56aSColin Percival QUIETFLAG=" " 63648ffe56aSColin Percival STATSREDIR="/dev/stderr" 63748ffe56aSColin Percival DDSTATS=".." 63848ffe56aSColin Percival XARGST="-t" 63948ffe56aSColin Percival NDEBUG=" " 64048ffe56aSColin Percival ;; 64148ffe56aSColin Percival nostats) 64248ffe56aSColin Percival QUIETREDIR="" 64348ffe56aSColin Percival QUIETFLAG="" 64448ffe56aSColin Percival STATSREDIR="/dev/null" 64548ffe56aSColin Percival DDSTATS=".." 64648ffe56aSColin Percival XARGST="" 64748ffe56aSColin Percival NDEBUG="" 64848ffe56aSColin Percival ;; 64948ffe56aSColin Percival stats) 65048ffe56aSColin Percival QUIETREDIR="/dev/null" 65148ffe56aSColin Percival QUIETFLAG="-q" 65248ffe56aSColin Percival STATSREDIR="/dev/stdout" 65348ffe56aSColin Percival DDSTATS="" 65448ffe56aSColin Percival XARGST="" 65548ffe56aSColin Percival NDEBUG="-n" 65648ffe56aSColin Percival ;; 65748ffe56aSColin Percival esac 65848ffe56aSColin Percival} 65948ffe56aSColin Percival 66048ffe56aSColin Percival# Perform sanity checks and set some final parameters 66148ffe56aSColin Percival# in preparation for fetching files. Figure out which 66248ffe56aSColin Percival# set of updates should be downloaded: If the user is 66348ffe56aSColin Percival# running *-p[0-9]+, strip off the last part; if the 66448ffe56aSColin Percival# user is running -SECURITY, call it -RELEASE. Chdir 66548ffe56aSColin Percival# into the working directory. 666211f2ba0SColin Percivalfetchupgrade_check_params () { 66748ffe56aSColin Percival export HTTP_USER_AGENT="freebsd-update (${COMMAND}, `uname -r`)" 66848ffe56aSColin Percival 66948ffe56aSColin Percival _SERVERNAME_z=\ 67048ffe56aSColin Percival"SERVERNAME must be given via command line or configuration file." 67148ffe56aSColin Percival _KEYPRINT_z="Key must be given via -k option or configuration file." 67248ffe56aSColin Percival _KEYPRINT_bad="Invalid key fingerprint: " 67348ffe56aSColin Percival _WORKDIR_bad="Directory does not exist or is not writable: " 674f88076f0SMark Felder _WORKDIR_bad2="Directory is not on a persistent filesystem: " 67548ffe56aSColin Percival 67648ffe56aSColin Percival if [ -z "${SERVERNAME}" ]; then 67748ffe56aSColin Percival echo -n "`basename $0`: " 67848ffe56aSColin Percival echo "${_SERVERNAME_z}" 67948ffe56aSColin Percival exit 1 68048ffe56aSColin Percival fi 68148ffe56aSColin Percival if [ -z "${KEYPRINT}" ]; then 68248ffe56aSColin Percival echo -n "`basename $0`: " 68348ffe56aSColin Percival echo "${_KEYPRINT_z}" 68448ffe56aSColin Percival exit 1 68548ffe56aSColin Percival fi 68648ffe56aSColin Percival if ! echo "${KEYPRINT}" | grep -qE "^[0-9a-f]{64}$"; then 68748ffe56aSColin Percival echo -n "`basename $0`: " 68848ffe56aSColin Percival echo -n "${_KEYPRINT_bad}" 68948ffe56aSColin Percival echo ${KEYPRINT} 69048ffe56aSColin Percival exit 1 69148ffe56aSColin Percival fi 69248ffe56aSColin Percival if ! [ -d "${WORKDIR}" -a -w "${WORKDIR}" ]; then 69348ffe56aSColin Percival echo -n "`basename $0`: " 69448ffe56aSColin Percival echo -n "${_WORKDIR_bad}" 69548ffe56aSColin Percival echo ${WORKDIR} 69648ffe56aSColin Percival exit 1 69748ffe56aSColin Percival fi 698dfe9215bSMark Felder case `df -T ${WORKDIR}` in */dev/md[0-9]* | *tmpfs*) 699f88076f0SMark Felder echo -n "`basename $0`: " 700f88076f0SMark Felder echo -n "${_WORKDIR_bad2}" 701f88076f0SMark Felder echo ${WORKDIR} 702f88076f0SMark Felder exit 1 703dfe9215bSMark Felder ;; 704dfe9215bSMark Felder esac 705a2356430SColin Percival chmod 700 ${WORKDIR} 70648ffe56aSColin Percival cd ${WORKDIR} || exit 1 70748ffe56aSColin Percival 70848ffe56aSColin Percival # Generate release number. The s/SECURITY/RELEASE/ bit exists 70948ffe56aSColin Percival # to provide an upgrade path for FreeBSD Update 1.x users, since 71048ffe56aSColin Percival # the kernels provided by FreeBSD Update 1.x are always labelled 71148ffe56aSColin Percival # as X.Y-SECURITY. 71248ffe56aSColin Percival RELNUM=`uname -r | 71348ffe56aSColin Percival sed -E 's,-p[0-9]+,,' | 71448ffe56aSColin Percival sed -E 's,-SECURITY,-RELEASE,'` 71548ffe56aSColin Percival ARCH=`uname -m` 71648ffe56aSColin Percival FETCHDIR=${RELNUM}/${ARCH} 717db6b0a61SColin Percival PATCHDIR=${RELNUM}/${ARCH}/bp 71848ffe56aSColin Percival 719d308a8bfSEd Maste # Disallow upgrade from a version that is not a release 720d308a8bfSEd Maste case ${RELNUM} in 721d308a8bfSEd Maste *-RELEASE | *-ALPHA* | *-BETA* | *-RC*) 722d308a8bfSEd Maste ;; 723d308a8bfSEd Maste *) 7240d5c5243SEd Maste echo -n "`basename $0`: " 7250d5c5243SEd Maste cat <<- EOF 726d308a8bfSEd Maste Cannot upgrade from a version that is not a release 727d308a8bfSEd Maste (including alpha, beta and release candidates) 728d308a8bfSEd Maste using `basename $0`. Instead, FreeBSD can be directly 729d308a8bfSEd Maste upgraded by source or upgraded to a RELEASE/RELENG version 730d308a8bfSEd Maste prior to running `basename $0`. 731d308a8bfSEd Maste Currently running: ${RELNUM} 7320d5c5243SEd Maste EOF 7330d5c5243SEd Maste exit 1 734d308a8bfSEd Maste ;; 735d308a8bfSEd Maste esac 7360d5c5243SEd Maste 73748ffe56aSColin Percival # Figure out what directory contains the running kernel 73848ffe56aSColin Percival BOOTFILE=`sysctl -n kern.bootfile` 73948ffe56aSColin Percival KERNELDIR=${BOOTFILE%/kernel} 74048ffe56aSColin Percival if ! [ -d ${KERNELDIR} ]; then 74148ffe56aSColin Percival echo "Cannot identify running kernel" 74248ffe56aSColin Percival exit 1 74348ffe56aSColin Percival fi 74448ffe56aSColin Percival 7452c434b2cSColin Percival # Figure out what kernel configuration is running. We start with 7462c434b2cSColin Percival # the output of `uname -i`, and then make the following adjustments: 7472c434b2cSColin Percival # 1. Replace "SMP-GENERIC" with "SMP". Why the SMP kernel config 7482c434b2cSColin Percival # file says "ident SMP-GENERIC", I don't know... 7492c434b2cSColin Percival # 2. If the kernel claims to be GENERIC _and_ ${ARCH} is "amd64" 7502c434b2cSColin Percival # _and_ `sysctl kern.version` contains a line which ends "/SMP", then 7512c434b2cSColin Percival # we're running an SMP kernel. This mis-identification is a bug 7522c434b2cSColin Percival # which was fixed in 6.2-STABLE. 7532c434b2cSColin Percival KERNCONF=`uname -i` 7542c434b2cSColin Percival if [ ${KERNCONF} = "SMP-GENERIC" ]; then 7552c434b2cSColin Percival KERNCONF=SMP 7562c434b2cSColin Percival fi 7572c434b2cSColin Percival if [ ${KERNCONF} = "GENERIC" ] && [ ${ARCH} = "amd64" ]; then 7582c434b2cSColin Percival if sysctl kern.version | grep -qE '/SMP$'; then 7592c434b2cSColin Percival KERNCONF=SMP 7602c434b2cSColin Percival fi 7612c434b2cSColin Percival fi 7622c434b2cSColin Percival 76348ffe56aSColin Percival # Define some paths 76448ffe56aSColin Percival BSPATCH=/usr/bin/bspatch 76548ffe56aSColin Percival SHA256=/sbin/sha256 76648ffe56aSColin Percival PHTTPGET=/usr/libexec/phttpget 76748ffe56aSColin Percival 76848ffe56aSColin Percival # Set up variables relating to VERBOSELEVEL 76948ffe56aSColin Percival fetch_setup_verboselevel 77048ffe56aSColin Percival 77148ffe56aSColin Percival # Construct a unique name from ${BASEDIR} 77248ffe56aSColin Percival BDHASH=`echo ${BASEDIR} | sha256 -q` 77348ffe56aSColin Percival} 77448ffe56aSColin Percival 775211f2ba0SColin Percival# Perform sanity checks etc. before fetching updates. 776211f2ba0SColin Percivalfetch_check_params () { 777211f2ba0SColin Percival fetchupgrade_check_params 778211f2ba0SColin Percival 779211f2ba0SColin Percival if ! [ -z "${TARGETRELEASE}" ]; then 780211f2ba0SColin Percival echo -n "`basename $0`: " 781211f2ba0SColin Percival echo -n "-r option is meaningless with 'fetch' command. " 782211f2ba0SColin Percival echo "(Did you mean 'upgrade' instead?)" 783211f2ba0SColin Percival exit 1 784211f2ba0SColin Percival fi 7858935f242SAllan Jude 7868935f242SAllan Jude # Check that we have updates ready to install 7878bf2dcceSAllan Jude if [ -f ${BDHASH}-install/kerneldone -a $FORCEFETCH -eq 0 ]; then 7888935f242SAllan Jude echo "You have a partially completed upgrade pending" 7898935f242SAllan Jude echo "Run '$0 install' first." 7908935f242SAllan Jude echo "Run '$0 fetch -F' to proceed anyway." 7918935f242SAllan Jude exit 1 7928935f242SAllan Jude fi 793211f2ba0SColin Percival} 794211f2ba0SColin Percival 795db6b0a61SColin Percival# Perform sanity checks etc. before fetching upgrades. 796db6b0a61SColin Percivalupgrade_check_params () { 797211f2ba0SColin Percival fetchupgrade_check_params 798db6b0a61SColin Percival 799db6b0a61SColin Percival # Unless set otherwise, we're upgrading to the same kernel config. 800db6b0a61SColin Percival NKERNCONF=${KERNCONF} 801db6b0a61SColin Percival 802db6b0a61SColin Percival # We need TARGETRELEASE set 803db6b0a61SColin Percival _TARGETRELEASE_z="Release target must be specified via -r option." 804db6b0a61SColin Percival if [ -z "${TARGETRELEASE}" ]; then 805db6b0a61SColin Percival echo -n "`basename $0`: " 806db6b0a61SColin Percival echo "${_TARGETRELEASE_z}" 807db6b0a61SColin Percival exit 1 808db6b0a61SColin Percival fi 809db6b0a61SColin Percival 810db6b0a61SColin Percival # The target release should be != the current release. 811db6b0a61SColin Percival if [ "${TARGETRELEASE}" = "${RELNUM}" ]; then 812db6b0a61SColin Percival echo -n "`basename $0`: " 813db6b0a61SColin Percival echo "Cannot upgrade from ${RELNUM} to itself" 814db6b0a61SColin Percival exit 1 815db6b0a61SColin Percival fi 816db6b0a61SColin Percival 817db6b0a61SColin Percival # Turning off AllowAdd or AllowDelete is a bad idea for upgrades. 818db6b0a61SColin Percival if [ "${ALLOWADD}" = "no" ]; then 819db6b0a61SColin Percival echo -n "`basename $0`: " 820db6b0a61SColin Percival echo -n "WARNING: \"AllowAdd no\" is a bad idea " 821db6b0a61SColin Percival echo "when upgrading between releases." 822db6b0a61SColin Percival echo 823db6b0a61SColin Percival fi 824db6b0a61SColin Percival if [ "${ALLOWDELETE}" = "no" ]; then 825db6b0a61SColin Percival echo -n "`basename $0`: " 826db6b0a61SColin Percival echo -n "WARNING: \"AllowDelete no\" is a bad idea " 827db6b0a61SColin Percival echo "when upgrading between releases." 828db6b0a61SColin Percival echo 829db6b0a61SColin Percival fi 830db6b0a61SColin Percival 831db6b0a61SColin Percival # Set EDITOR to /usr/bin/vi if it isn't already set 832db6b0a61SColin Percival : ${EDITOR:='/usr/bin/vi'} 833db6b0a61SColin Percival} 834db6b0a61SColin Percival 83548ffe56aSColin Percival# Perform sanity checks and set some final parameters in 83648ffe56aSColin Percival# preparation for installing updates. 83748ffe56aSColin Percivalinstall_check_params () { 83848ffe56aSColin Percival # Check that we are root. All sorts of things won't work otherwise. 83948ffe56aSColin Percival if [ `id -u` != 0 ]; then 84048ffe56aSColin Percival echo "You must be root to run this." 84148ffe56aSColin Percival exit 1 84248ffe56aSColin Percival fi 84348ffe56aSColin Percival 8442328d598SColin Percival # Check that securelevel <= 0. Otherwise we can't update schg files. 8452328d598SColin Percival if [ `sysctl -n kern.securelevel` -gt 0 ]; then 8462328d598SColin Percival echo "Updates cannot be installed when the system securelevel" 8472328d598SColin Percival echo "is greater than zero." 8482328d598SColin Percival exit 1 8492328d598SColin Percival fi 8502328d598SColin Percival 85148ffe56aSColin Percival # Check that we have a working directory 85248ffe56aSColin Percival _WORKDIR_bad="Directory does not exist or is not writable: " 85348ffe56aSColin Percival if ! [ -d "${WORKDIR}" -a -w "${WORKDIR}" ]; then 85448ffe56aSColin Percival echo -n "`basename $0`: " 85548ffe56aSColin Percival echo -n "${_WORKDIR_bad}" 85648ffe56aSColin Percival echo ${WORKDIR} 85748ffe56aSColin Percival exit 1 85848ffe56aSColin Percival fi 85948ffe56aSColin Percival cd ${WORKDIR} || exit 1 86048ffe56aSColin Percival 86148ffe56aSColin Percival # Construct a unique name from ${BASEDIR} 86248ffe56aSColin Percival BDHASH=`echo ${BASEDIR} | sha256 -q` 86348ffe56aSColin Percival 86448ffe56aSColin Percival # Check that we have updates ready to install 86548ffe56aSColin Percival if ! [ -L ${BDHASH}-install ]; then 86648ffe56aSColin Percival echo "No updates are available to install." 86733bd05c3SGuangyuan Yang if [ $ISFETCHED -eq 0 ]; then 86848ffe56aSColin Percival echo "Run '$0 fetch' first." 8698cfda118SMichael Gmelin exit 2 87033bd05c3SGuangyuan Yang fi 87133bd05c3SGuangyuan Yang exit 0 87248ffe56aSColin Percival fi 87348ffe56aSColin Percival if ! [ -f ${BDHASH}-install/INDEX-OLD ] || 87448ffe56aSColin Percival ! [ -f ${BDHASH}-install/INDEX-NEW ]; then 87548ffe56aSColin Percival echo "Update manifest is corrupt -- this should never happen." 87648ffe56aSColin Percival echo "Re-run '$0 fetch'." 87748ffe56aSColin Percival exit 1 87848ffe56aSColin Percival fi 87923d827efSSimon L. B. Nielsen 88023d827efSSimon L. B. Nielsen # Figure out what directory contains the running kernel 88123d827efSSimon L. B. Nielsen BOOTFILE=`sysctl -n kern.bootfile` 88223d827efSSimon L. B. Nielsen KERNELDIR=${BOOTFILE%/kernel} 88323d827efSSimon L. B. Nielsen if ! [ -d ${KERNELDIR} ]; then 88423d827efSSimon L. B. Nielsen echo "Cannot identify running kernel" 88523d827efSSimon L. B. Nielsen exit 1 88623d827efSSimon L. B. Nielsen fi 88748ffe56aSColin Percival} 88848ffe56aSColin Percival 889f28f1389SDave Fullard# Creates a new boot environment 890f28f1389SDave Fullardinstall_create_be () { 891f28f1389SDave Fullard # Figure out if we're running in a jail and return if we are 892f28f1389SDave Fullard if [ `sysctl -n security.jail.jailed` = 1 ]; then 893f28f1389SDave Fullard return 1 894f28f1389SDave Fullard fi 895e01e8f91SKyle Evans # Operating on roots that aren't located at / will, more often than not, 896e01e8f91SKyle Evans # not touch the boot environment. 897e01e8f91SKyle Evans if [ "$BASEDIR" != "/" ]; then 898e01e8f91SKyle Evans return 1 899e01e8f91SKyle Evans fi 900f28f1389SDave Fullard # Create a boot environment if enabled 901f28f1389SDave Fullard if [ ${BOOTENV} = yes ]; then 902f28f1389SDave Fullard bectl check 2>/dev/null 903f28f1389SDave Fullard case $? in 904f28f1389SDave Fullard 0) 905f28f1389SDave Fullard # Boot environment are supported 906f28f1389SDave Fullard CREATEBE=yes 907f28f1389SDave Fullard ;; 908f28f1389SDave Fullard 255) 909f28f1389SDave Fullard # Boot environments are not supported 910f28f1389SDave Fullard CREATEBE=no 911f28f1389SDave Fullard ;; 912f28f1389SDave Fullard *) 913f28f1389SDave Fullard # If bectl returns an unexpected exit code, don't create a BE 914f28f1389SDave Fullard CREATEBE=no 915f28f1389SDave Fullard ;; 916f28f1389SDave Fullard esac 917f28f1389SDave Fullard if [ ${CREATEBE} = yes ]; then 918f28f1389SDave Fullard echo -n "Creating snapshot of existing boot environment... " 919e01e8f91SKyle Evans VERSION=`freebsd-version -ku | sort -V | tail -n 1` 920f28f1389SDave Fullard TIMESTAMP=`date +"%Y-%m-%d_%H%M%S"` 921f28f1389SDave Fullard bectl create ${VERSION}_${TIMESTAMP} 922f28f1389SDave Fullard if [ $? -eq 0 ]; then 923f28f1389SDave Fullard echo "done."; 924f28f1389SDave Fullard else 925f28f1389SDave Fullard echo "failed." 926f28f1389SDave Fullard exit 1 927f28f1389SDave Fullard fi 928f28f1389SDave Fullard fi 929f28f1389SDave Fullard fi 930f28f1389SDave Fullard} 931f28f1389SDave Fullard 93248ffe56aSColin Percival# Perform sanity checks and set some final parameters in 93348ffe56aSColin Percival# preparation for UNinstalling updates. 93448ffe56aSColin Percivalrollback_check_params () { 93548ffe56aSColin Percival # Check that we are root. All sorts of things won't work otherwise. 93648ffe56aSColin Percival if [ `id -u` != 0 ]; then 93748ffe56aSColin Percival echo "You must be root to run this." 93848ffe56aSColin Percival exit 1 93948ffe56aSColin Percival fi 94048ffe56aSColin Percival 94148ffe56aSColin Percival # Check that we have a working directory 94248ffe56aSColin Percival _WORKDIR_bad="Directory does not exist or is not writable: " 94348ffe56aSColin Percival if ! [ -d "${WORKDIR}" -a -w "${WORKDIR}" ]; then 94448ffe56aSColin Percival echo -n "`basename $0`: " 94548ffe56aSColin Percival echo -n "${_WORKDIR_bad}" 94648ffe56aSColin Percival echo ${WORKDIR} 94748ffe56aSColin Percival exit 1 94848ffe56aSColin Percival fi 94948ffe56aSColin Percival cd ${WORKDIR} || exit 1 95048ffe56aSColin Percival 95148ffe56aSColin Percival # Construct a unique name from ${BASEDIR} 95248ffe56aSColin Percival BDHASH=`echo ${BASEDIR} | sha256 -q` 95348ffe56aSColin Percival 95448ffe56aSColin Percival # Check that we have updates ready to rollback 95548ffe56aSColin Percival if ! [ -L ${BDHASH}-rollback ]; then 95648ffe56aSColin Percival echo "No rollback directory found." 95748ffe56aSColin Percival exit 1 95848ffe56aSColin Percival fi 95948ffe56aSColin Percival if ! [ -f ${BDHASH}-rollback/INDEX-OLD ] || 96048ffe56aSColin Percival ! [ -f ${BDHASH}-rollback/INDEX-NEW ]; then 96148ffe56aSColin Percival echo "Update manifest is corrupt -- this should never happen." 96248ffe56aSColin Percival exit 1 96348ffe56aSColin Percival fi 96448ffe56aSColin Percival} 96548ffe56aSColin Percival 96608e23beeSColin Percival# Perform sanity checks and set some final parameters 96708e23beeSColin Percival# in preparation for comparing the system against the 96808e23beeSColin Percival# published index. Figure out which index we should 96908e23beeSColin Percival# compare against: If the user is running *-p[0-9]+, 97008e23beeSColin Percival# strip off the last part; if the user is running 97108e23beeSColin Percival# -SECURITY, call it -RELEASE. Chdir into the working 97208e23beeSColin Percival# directory. 97308e23beeSColin PercivalIDS_check_params () { 97408e23beeSColin Percival export HTTP_USER_AGENT="freebsd-update (${COMMAND}, `uname -r`)" 97508e23beeSColin Percival 97608e23beeSColin Percival _SERVERNAME_z=\ 97708e23beeSColin Percival"SERVERNAME must be given via command line or configuration file." 97808e23beeSColin Percival _KEYPRINT_z="Key must be given via -k option or configuration file." 97908e23beeSColin Percival _KEYPRINT_bad="Invalid key fingerprint: " 98008e23beeSColin Percival _WORKDIR_bad="Directory does not exist or is not writable: " 98108e23beeSColin Percival 98208e23beeSColin Percival if [ -z "${SERVERNAME}" ]; then 98308e23beeSColin Percival echo -n "`basename $0`: " 98408e23beeSColin Percival echo "${_SERVERNAME_z}" 98508e23beeSColin Percival exit 1 98608e23beeSColin Percival fi 98708e23beeSColin Percival if [ -z "${KEYPRINT}" ]; then 98808e23beeSColin Percival echo -n "`basename $0`: " 98908e23beeSColin Percival echo "${_KEYPRINT_z}" 99008e23beeSColin Percival exit 1 99108e23beeSColin Percival fi 99208e23beeSColin Percival if ! echo "${KEYPRINT}" | grep -qE "^[0-9a-f]{64}$"; then 99308e23beeSColin Percival echo -n "`basename $0`: " 99408e23beeSColin Percival echo -n "${_KEYPRINT_bad}" 99508e23beeSColin Percival echo ${KEYPRINT} 99608e23beeSColin Percival exit 1 99708e23beeSColin Percival fi 99808e23beeSColin Percival if ! [ -d "${WORKDIR}" -a -w "${WORKDIR}" ]; then 99908e23beeSColin Percival echo -n "`basename $0`: " 100008e23beeSColin Percival echo -n "${_WORKDIR_bad}" 100108e23beeSColin Percival echo ${WORKDIR} 100208e23beeSColin Percival exit 1 100308e23beeSColin Percival fi 100408e23beeSColin Percival cd ${WORKDIR} || exit 1 100508e23beeSColin Percival 100608e23beeSColin Percival # Generate release number. The s/SECURITY/RELEASE/ bit exists 100708e23beeSColin Percival # to provide an upgrade path for FreeBSD Update 1.x users, since 100808e23beeSColin Percival # the kernels provided by FreeBSD Update 1.x are always labelled 100908e23beeSColin Percival # as X.Y-SECURITY. 101008e23beeSColin Percival RELNUM=`uname -r | 101108e23beeSColin Percival sed -E 's,-p[0-9]+,,' | 101208e23beeSColin Percival sed -E 's,-SECURITY,-RELEASE,'` 101308e23beeSColin Percival ARCH=`uname -m` 101408e23beeSColin Percival FETCHDIR=${RELNUM}/${ARCH} 101508e23beeSColin Percival PATCHDIR=${RELNUM}/${ARCH}/bp 101608e23beeSColin Percival 101708e23beeSColin Percival # Figure out what directory contains the running kernel 101808e23beeSColin Percival BOOTFILE=`sysctl -n kern.bootfile` 101908e23beeSColin Percival KERNELDIR=${BOOTFILE%/kernel} 102008e23beeSColin Percival if ! [ -d ${KERNELDIR} ]; then 102108e23beeSColin Percival echo "Cannot identify running kernel" 102208e23beeSColin Percival exit 1 102308e23beeSColin Percival fi 102408e23beeSColin Percival 102508e23beeSColin Percival # Figure out what kernel configuration is running. We start with 102608e23beeSColin Percival # the output of `uname -i`, and then make the following adjustments: 102708e23beeSColin Percival # 1. Replace "SMP-GENERIC" with "SMP". Why the SMP kernel config 102808e23beeSColin Percival # file says "ident SMP-GENERIC", I don't know... 102908e23beeSColin Percival # 2. If the kernel claims to be GENERIC _and_ ${ARCH} is "amd64" 103008e23beeSColin Percival # _and_ `sysctl kern.version` contains a line which ends "/SMP", then 103108e23beeSColin Percival # we're running an SMP kernel. This mis-identification is a bug 103208e23beeSColin Percival # which was fixed in 6.2-STABLE. 103308e23beeSColin Percival KERNCONF=`uname -i` 103408e23beeSColin Percival if [ ${KERNCONF} = "SMP-GENERIC" ]; then 103508e23beeSColin Percival KERNCONF=SMP 103608e23beeSColin Percival fi 103708e23beeSColin Percival if [ ${KERNCONF} = "GENERIC" ] && [ ${ARCH} = "amd64" ]; then 103808e23beeSColin Percival if sysctl kern.version | grep -qE '/SMP$'; then 103908e23beeSColin Percival KERNCONF=SMP 104008e23beeSColin Percival fi 104108e23beeSColin Percival fi 104208e23beeSColin Percival 104308e23beeSColin Percival # Define some paths 104408e23beeSColin Percival SHA256=/sbin/sha256 104508e23beeSColin Percival PHTTPGET=/usr/libexec/phttpget 104608e23beeSColin Percival 104708e23beeSColin Percival # Set up variables relating to VERBOSELEVEL 104808e23beeSColin Percival fetch_setup_verboselevel 104908e23beeSColin Percival} 105008e23beeSColin Percival 105148ffe56aSColin Percival#### Core functionality -- the actual work gets done here 105248ffe56aSColin Percival 105348ffe56aSColin Percival# Use an SRV query to pick a server. If the SRV query doesn't provide 105448ffe56aSColin Percival# a useful answer, use the server name specified by the user. 105548ffe56aSColin Percival# Put another way... look up _http._tcp.${SERVERNAME} and pick a server 105648ffe56aSColin Percival# from that; or if no servers are returned, use ${SERVERNAME}. 105748ffe56aSColin Percival# This allows a user to specify "portsnap.freebsd.org" (in which case 105848ffe56aSColin Percival# portsnap will select one of the mirrors) or "portsnap5.tld.freebsd.org" 105948ffe56aSColin Percival# (in which case portsnap will use that particular server, since there 106048ffe56aSColin Percival# won't be an SRV entry for that name). 106148ffe56aSColin Percival# 106248ffe56aSColin Percival# We ignore the Port field, since we are always going to use port 80. 106348ffe56aSColin Percival 106448ffe56aSColin Percival# Fetch the mirror list, but do not pick a mirror yet. Returns 1 if 106548ffe56aSColin Percival# no mirrors are available for any reason. 106648ffe56aSColin Percivalfetch_pick_server_init () { 106748ffe56aSColin Percival : > serverlist_tried 106848ffe56aSColin Percival 106948ffe56aSColin Percival# Check that host(1) exists (i.e., that the system wasn't built with the 107048ffe56aSColin Percival# WITHOUT_BIND set) and don't try to find a mirror if it doesn't exist. 107148ffe56aSColin Percival if ! which -s host; then 107248ffe56aSColin Percival : > serverlist_full 107348ffe56aSColin Percival return 1 107448ffe56aSColin Percival fi 107548ffe56aSColin Percival 107648ffe56aSColin Percival echo -n "Looking up ${SERVERNAME} mirrors... " 107748ffe56aSColin Percival 107848ffe56aSColin Percival# Issue the SRV query and pull out the Priority, Weight, and Target fields. 107948ffe56aSColin Percival# BIND 9 prints "$name has SRV record ..." while BIND 8 prints 108048ffe56aSColin Percival# "$name server selection ..."; we allow either format. 108148ffe56aSColin Percival MLIST="_http._tcp.${SERVERNAME}" 108248ffe56aSColin Percival host -t srv "${MLIST}" | 1083e7fd266eSColin Percival sed -nE "s/${MLIST} (has SRV record|server selection) //Ip" | 108448ffe56aSColin Percival cut -f 1,2,4 -d ' ' | 108548ffe56aSColin Percival sed -e 's/\.$//' | 108648ffe56aSColin Percival sort > serverlist_full 108748ffe56aSColin Percival 108848ffe56aSColin Percival# If no records, give up -- we'll just use the server name we were given. 108948ffe56aSColin Percival if [ `wc -l < serverlist_full` -eq 0 ]; then 109048ffe56aSColin Percival echo "none found." 109148ffe56aSColin Percival return 1 109248ffe56aSColin Percival fi 109348ffe56aSColin Percival 109448ffe56aSColin Percival# Report how many mirrors we found. 109548ffe56aSColin Percival echo `wc -l < serverlist_full` "mirrors found." 109648ffe56aSColin Percival 109748ffe56aSColin Percival# Generate a random seed for use in picking mirrors. If HTTP_PROXY 109848ffe56aSColin Percival# is set, this will be used to generate the seed; otherwise, the seed 109948ffe56aSColin Percival# will be random. 110048ffe56aSColin Percival if [ -n "${HTTP_PROXY}${http_proxy}" ]; then 110148ffe56aSColin Percival RANDVALUE=`sha256 -qs "${HTTP_PROXY}${http_proxy}" | 110248ffe56aSColin Percival tr -d 'a-f' | 110348ffe56aSColin Percival cut -c 1-9` 110448ffe56aSColin Percival else 110548ffe56aSColin Percival RANDVALUE=`jot -r 1 0 999999999` 110648ffe56aSColin Percival fi 110748ffe56aSColin Percival} 110848ffe56aSColin Percival 110948ffe56aSColin Percival# Pick a mirror. Returns 1 if we have run out of mirrors to try. 111048ffe56aSColin Percivalfetch_pick_server () { 111148ffe56aSColin Percival# Generate a list of not-yet-tried mirrors 111248ffe56aSColin Percival sort serverlist_tried | 111348ffe56aSColin Percival comm -23 serverlist_full - > serverlist 111448ffe56aSColin Percival 111548ffe56aSColin Percival# Have we run out of mirrors? 111648ffe56aSColin Percival if [ `wc -l < serverlist` -eq 0 ]; then 11179e8c28fcSEd Maste cat <<- EOF 11189e8c28fcSEd Maste No mirrors remaining, giving up. 11199e8c28fcSEd Maste 11209e8c28fcSEd Maste This may be because upgrading from this platform (${ARCH}) 11219e8c28fcSEd Maste or release (${RELNUM}) is unsupported by `basename $0`. Only 11229e8c28fcSEd Maste platforms with Tier 1 support can be upgraded by `basename $0`. 112386d0d3aaSLi-Wen Hsu See https://www.freebsd.org/platforms/ for more info. 11249e8c28fcSEd Maste 11259e8c28fcSEd Maste If unsupported, FreeBSD must be upgraded by source. 11269e8c28fcSEd Maste EOF 112748ffe56aSColin Percival return 1 112848ffe56aSColin Percival fi 112948ffe56aSColin Percival 113048ffe56aSColin Percival# Find the highest priority level (lowest numeric value). 113148ffe56aSColin Percival SRV_PRIORITY=`cut -f 1 -d ' ' serverlist | sort -n | head -1` 113248ffe56aSColin Percival 113348ffe56aSColin Percival# Add up the weights of the response lines at that priority level. 113448ffe56aSColin Percival SRV_WSUM=0; 113548ffe56aSColin Percival while read X; do 113648ffe56aSColin Percival case "$X" in 113748ffe56aSColin Percival ${SRV_PRIORITY}\ *) 113848ffe56aSColin Percival SRV_W=`echo $X | cut -f 2 -d ' '` 113948ffe56aSColin Percival SRV_WSUM=$(($SRV_WSUM + $SRV_W)) 114048ffe56aSColin Percival ;; 114148ffe56aSColin Percival esac 114248ffe56aSColin Percival done < serverlist 114348ffe56aSColin Percival 114448ffe56aSColin Percival# If all the weights are 0, pretend that they are all 1 instead. 114548ffe56aSColin Percival if [ ${SRV_WSUM} -eq 0 ]; then 114648ffe56aSColin Percival SRV_WSUM=`grep -E "^${SRV_PRIORITY} " serverlist | wc -l` 114748ffe56aSColin Percival SRV_W_ADD=1 114848ffe56aSColin Percival else 114948ffe56aSColin Percival SRV_W_ADD=0 115048ffe56aSColin Percival fi 115148ffe56aSColin Percival 115248ffe56aSColin Percival# Pick a value between 0 and the sum of the weights - 1 115348ffe56aSColin Percival SRV_RND=`expr ${RANDVALUE} % ${SRV_WSUM}` 115448ffe56aSColin Percival 115548ffe56aSColin Percival# Read through the list of mirrors and set SERVERNAME. Write the line 115648ffe56aSColin Percival# corresponding to the mirror we selected into serverlist_tried so that 115748ffe56aSColin Percival# we won't try it again. 115848ffe56aSColin Percival while read X; do 115948ffe56aSColin Percival case "$X" in 116048ffe56aSColin Percival ${SRV_PRIORITY}\ *) 116148ffe56aSColin Percival SRV_W=`echo $X | cut -f 2 -d ' '` 116248ffe56aSColin Percival SRV_W=$(($SRV_W + $SRV_W_ADD)) 116348ffe56aSColin Percival if [ $SRV_RND -lt $SRV_W ]; then 116448ffe56aSColin Percival SERVERNAME=`echo $X | cut -f 3 -d ' '` 116548ffe56aSColin Percival echo "$X" >> serverlist_tried 116648ffe56aSColin Percival break 116748ffe56aSColin Percival else 116848ffe56aSColin Percival SRV_RND=$(($SRV_RND - $SRV_W)) 116948ffe56aSColin Percival fi 117048ffe56aSColin Percival ;; 117148ffe56aSColin Percival esac 117248ffe56aSColin Percival done < serverlist 117348ffe56aSColin Percival} 117448ffe56aSColin Percival 117548ffe56aSColin Percival# Take a list of ${oldhash}|${newhash} and output a list of needed patches, 117648ffe56aSColin Percival# i.e., those for which we have ${oldhash} and don't have ${newhash}. 117748ffe56aSColin Percivalfetch_make_patchlist () { 117848ffe56aSColin Percival grep -vE "^([0-9a-f]{64})\|\1$" | 117948ffe56aSColin Percival tr '|' ' ' | 118048ffe56aSColin Percival while read X Y; do 118148ffe56aSColin Percival if [ -f "files/${Y}.gz" ] || 118248ffe56aSColin Percival [ ! -f "files/${X}.gz" ]; then 118348ffe56aSColin Percival continue 118448ffe56aSColin Percival fi 118548ffe56aSColin Percival echo "${X}|${Y}" 1186f6e21461SEd Maste done | sort -u 118748ffe56aSColin Percival} 118848ffe56aSColin Percival 118948ffe56aSColin Percival# Print user-friendly progress statistics 119048ffe56aSColin Percivalfetch_progress () { 119148ffe56aSColin Percival LNC=0 119248ffe56aSColin Percival while read x; do 119348ffe56aSColin Percival LNC=$(($LNC + 1)) 119448ffe56aSColin Percival if [ $(($LNC % 10)) = 0 ]; then 119548ffe56aSColin Percival echo -n $LNC 119648ffe56aSColin Percival elif [ $(($LNC % 2)) = 0 ]; then 119748ffe56aSColin Percival echo -n . 119848ffe56aSColin Percival fi 119948ffe56aSColin Percival done 120048ffe56aSColin Percival echo -n " " 120148ffe56aSColin Percival} 120248ffe56aSColin Percival 1203db6b0a61SColin Percival# Function for asking the user if everything is ok 1204db6b0a61SColin Percivalcontinuep () { 1205db6b0a61SColin Percival while read -p "Does this look reasonable (y/n)? " CONTINUE; do 1206db6b0a61SColin Percival case "${CONTINUE}" in 1207db6b0a61SColin Percival y*) 1208db6b0a61SColin Percival return 0 1209db6b0a61SColin Percival ;; 1210db6b0a61SColin Percival n*) 1211db6b0a61SColin Percival return 1 1212db6b0a61SColin Percival ;; 1213db6b0a61SColin Percival esac 1214db6b0a61SColin Percival done 1215db6b0a61SColin Percival} 1216db6b0a61SColin Percival 121748ffe56aSColin Percival# Initialize the working directory 121848ffe56aSColin Percivalworkdir_init () { 121948ffe56aSColin Percival mkdir -p files 122048ffe56aSColin Percival touch tINDEX.present 122148ffe56aSColin Percival} 122248ffe56aSColin Percival 122348ffe56aSColin Percival# Check that we have a public key with an appropriate hash, or 122448ffe56aSColin Percival# fetch the key if it doesn't exist. Returns 1 if the key has 122548ffe56aSColin Percival# not yet been fetched. 122648ffe56aSColin Percivalfetch_key () { 122748ffe56aSColin Percival if [ -r pub.ssl ] && [ `${SHA256} -q pub.ssl` = ${KEYPRINT} ]; then 122848ffe56aSColin Percival return 0 122948ffe56aSColin Percival fi 123048ffe56aSColin Percival 123148ffe56aSColin Percival echo -n "Fetching public key from ${SERVERNAME}... " 123248ffe56aSColin Percival rm -f pub.ssl 123348ffe56aSColin Percival fetch ${QUIETFLAG} http://${SERVERNAME}/${FETCHDIR}/pub.ssl \ 123448ffe56aSColin Percival 2>${QUIETREDIR} || true 123548ffe56aSColin Percival if ! [ -r pub.ssl ]; then 123648ffe56aSColin Percival echo "failed." 123748ffe56aSColin Percival return 1 123848ffe56aSColin Percival fi 123948ffe56aSColin Percival if ! [ `${SHA256} -q pub.ssl` = ${KEYPRINT} ]; then 124048ffe56aSColin Percival echo "key has incorrect hash." 124148ffe56aSColin Percival rm -f pub.ssl 124248ffe56aSColin Percival return 1 124348ffe56aSColin Percival fi 124448ffe56aSColin Percival echo "done." 124548ffe56aSColin Percival} 124648ffe56aSColin Percival 124748ffe56aSColin Percival# Fetch metadata signature, aka "tag". 124848ffe56aSColin Percivalfetch_tag () { 1249db6b0a61SColin Percival echo -n "Fetching metadata signature " 1250db6b0a61SColin Percival echo ${NDEBUG} "for ${RELNUM} from ${SERVERNAME}... " 125148ffe56aSColin Percival rm -f latest.ssl 125248ffe56aSColin Percival fetch ${QUIETFLAG} http://${SERVERNAME}/${FETCHDIR}/latest.ssl \ 125348ffe56aSColin Percival 2>${QUIETREDIR} || true 125448ffe56aSColin Percival if ! [ -r latest.ssl ]; then 125548ffe56aSColin Percival echo "failed." 125648ffe56aSColin Percival return 1 125748ffe56aSColin Percival fi 125848ffe56aSColin Percival 125948ffe56aSColin Percival openssl rsautl -pubin -inkey pub.ssl -verify \ 126048ffe56aSColin Percival < latest.ssl > tag.new 2>${QUIETREDIR} || true 126148ffe56aSColin Percival rm latest.ssl 126248ffe56aSColin Percival 126348ffe56aSColin Percival if ! [ `wc -l < tag.new` = 1 ] || 126448ffe56aSColin Percival ! grep -qE \ 126548ffe56aSColin Percival "^freebsd-update\|${ARCH}\|${RELNUM}\|[0-9]+\|[0-9a-f]{64}\|[0-9]{10}" \ 126648ffe56aSColin Percival tag.new; then 126748ffe56aSColin Percival echo "invalid signature." 126848ffe56aSColin Percival return 1 126948ffe56aSColin Percival fi 127048ffe56aSColin Percival 127148ffe56aSColin Percival echo "done." 127248ffe56aSColin Percival 127348ffe56aSColin Percival RELPATCHNUM=`cut -f 4 -d '|' < tag.new` 127448ffe56aSColin Percival TINDEXHASH=`cut -f 5 -d '|' < tag.new` 127548ffe56aSColin Percival EOLTIME=`cut -f 6 -d '|' < tag.new` 127648ffe56aSColin Percival} 127748ffe56aSColin Percival 127848ffe56aSColin Percival# Sanity-check the patch number in a tag, to make sure that we're not 127948ffe56aSColin Percival# going to "update" backwards and to prevent replay attacks. 128048ffe56aSColin Percivalfetch_tagsanity () { 128148ffe56aSColin Percival # Check that we're not going to move from -pX to -pY with Y < X. 128248ffe56aSColin Percival RELPX=`uname -r | sed -E 's,.*-,,'` 128348ffe56aSColin Percival if echo ${RELPX} | grep -qE '^p[0-9]+$'; then 128448ffe56aSColin Percival RELPX=`echo ${RELPX} | cut -c 2-` 128548ffe56aSColin Percival else 128648ffe56aSColin Percival RELPX=0 128748ffe56aSColin Percival fi 128848ffe56aSColin Percival if [ "${RELPATCHNUM}" -lt "${RELPX}" ]; then 128948ffe56aSColin Percival echo 129048ffe56aSColin Percival echo -n "Files on mirror (${RELNUM}-p${RELPATCHNUM})" 129148ffe56aSColin Percival echo " appear older than what" 129248ffe56aSColin Percival echo "we are currently running (`uname -r`)!" 129348ffe56aSColin Percival echo "Cowardly refusing to proceed any further." 129448ffe56aSColin Percival return 1 129548ffe56aSColin Percival fi 129648ffe56aSColin Percival 129748ffe56aSColin Percival # If "tag" exists and corresponds to ${RELNUM}, make sure that 129848ffe56aSColin Percival # it contains a patch number <= RELPATCHNUM, in order to protect 129948ffe56aSColin Percival # against rollback (replay) attacks. 130048ffe56aSColin Percival if [ -f tag ] && 130148ffe56aSColin Percival grep -qE \ 130248ffe56aSColin Percival "^freebsd-update\|${ARCH}\|${RELNUM}\|[0-9]+\|[0-9a-f]{64}\|[0-9]{10}" \ 130348ffe56aSColin Percival tag; then 130448ffe56aSColin Percival LASTRELPATCHNUM=`cut -f 4 -d '|' < tag` 130548ffe56aSColin Percival 130648ffe56aSColin Percival if [ "${RELPATCHNUM}" -lt "${LASTRELPATCHNUM}" ]; then 130748ffe56aSColin Percival echo 130848ffe56aSColin Percival echo -n "Files on mirror (${RELNUM}-p${RELPATCHNUM})" 130948ffe56aSColin Percival echo " are older than the" 131048ffe56aSColin Percival echo -n "most recently seen updates" 131148ffe56aSColin Percival echo " (${RELNUM}-p${LASTRELPATCHNUM})." 131248ffe56aSColin Percival echo "Cowardly refusing to proceed any further." 131348ffe56aSColin Percival return 1 131448ffe56aSColin Percival fi 131548ffe56aSColin Percival fi 131648ffe56aSColin Percival} 131748ffe56aSColin Percival 131848ffe56aSColin Percival# Fetch metadata index file 131948ffe56aSColin Percivalfetch_metadata_index () { 132048ffe56aSColin Percival echo ${NDEBUG} "Fetching metadata index... " 132148ffe56aSColin Percival rm -f ${TINDEXHASH} 132248ffe56aSColin Percival fetch ${QUIETFLAG} http://${SERVERNAME}/${FETCHDIR}/t/${TINDEXHASH} 132348ffe56aSColin Percival 2>${QUIETREDIR} 132448ffe56aSColin Percival if ! [ -f ${TINDEXHASH} ]; then 132548ffe56aSColin Percival echo "failed." 132648ffe56aSColin Percival return 1 132748ffe56aSColin Percival fi 132848ffe56aSColin Percival if [ `${SHA256} -q ${TINDEXHASH}` != ${TINDEXHASH} ]; then 132948ffe56aSColin Percival echo "update metadata index corrupt." 133048ffe56aSColin Percival return 1 133148ffe56aSColin Percival fi 133248ffe56aSColin Percival echo "done." 133348ffe56aSColin Percival} 133448ffe56aSColin Percival 133548ffe56aSColin Percival# Print an error message about signed metadata being bogus. 133648ffe56aSColin Percivalfetch_metadata_bogus () { 133748ffe56aSColin Percival echo 133848ffe56aSColin Percival echo "The update metadata$1 is correctly signed, but" 133948ffe56aSColin Percival echo "failed an integrity check." 134048ffe56aSColin Percival echo "Cowardly refusing to proceed any further." 134148ffe56aSColin Percival return 1 134248ffe56aSColin Percival} 134348ffe56aSColin Percival 134448ffe56aSColin Percival# Construct tINDEX.new by merging the lines named in $1 from ${TINDEXHASH} 134548ffe56aSColin Percival# with the lines not named in $@ from tINDEX.present (if that file exists). 134648ffe56aSColin Percivalfetch_metadata_index_merge () { 134748ffe56aSColin Percival for METAFILE in $@; do 134848ffe56aSColin Percival if [ `grep -E "^${METAFILE}\|" ${TINDEXHASH} | wc -l` \ 134948ffe56aSColin Percival -ne 1 ]; then 135048ffe56aSColin Percival fetch_metadata_bogus " index" 135148ffe56aSColin Percival return 1 135248ffe56aSColin Percival fi 135348ffe56aSColin Percival 135448ffe56aSColin Percival grep -E "${METAFILE}\|" ${TINDEXHASH} 135548ffe56aSColin Percival done | 135648ffe56aSColin Percival sort > tINDEX.wanted 135748ffe56aSColin Percival 135848ffe56aSColin Percival if [ -f tINDEX.present ]; then 135948ffe56aSColin Percival join -t '|' -v 2 tINDEX.wanted tINDEX.present | 136048ffe56aSColin Percival sort -m - tINDEX.wanted > tINDEX.new 136148ffe56aSColin Percival rm tINDEX.wanted 136248ffe56aSColin Percival else 136348ffe56aSColin Percival mv tINDEX.wanted tINDEX.new 136448ffe56aSColin Percival fi 136548ffe56aSColin Percival} 136648ffe56aSColin Percival 136748ffe56aSColin Percival# Sanity check all the lines of tINDEX.new. Even if more metadata lines 136848ffe56aSColin Percival# are added by future versions of the server, this won't cause problems, 136948ffe56aSColin Percival# since the only lines which appear in tINDEX.new are the ones which we 137048ffe56aSColin Percival# specifically grepped out of ${TINDEXHASH}. 137148ffe56aSColin Percivalfetch_metadata_index_sanity () { 137248ffe56aSColin Percival if grep -qvE '^[0-9A-Z.-]+\|[0-9a-f]{64}$' tINDEX.new; then 137348ffe56aSColin Percival fetch_metadata_bogus " index" 137448ffe56aSColin Percival return 1 137548ffe56aSColin Percival fi 137648ffe56aSColin Percival} 137748ffe56aSColin Percival 137848ffe56aSColin Percival# Sanity check the metadata file $1. 137948ffe56aSColin Percivalfetch_metadata_sanity () { 138048ffe56aSColin Percival # Some aliases to save space later: ${P} is a character which can 138148ffe56aSColin Percival # appear in a path; ${M} is the four numeric metadata fields; and 138248ffe56aSColin Percival # ${H} is a sha256 hash. 13837c06c7c5SKris Moore P="[-+./:=,%@_[~[:alnum:]]" 138448ffe56aSColin Percival M="[0-9]+\|[0-9]+\|[0-9]+\|[0-9]+" 138548ffe56aSColin Percival H="[0-9a-f]{64}" 138648ffe56aSColin Percival 138748ffe56aSColin Percival # Check that the first four fields make sense. 138848ffe56aSColin Percival if gunzip -c < files/$1.gz | 1389823c0d5fSXin LI grep -qvE "^[a-z]+\|[0-9a-z-]+\|${P}+\|[fdL-]\|"; then 139048ffe56aSColin Percival fetch_metadata_bogus "" 139148ffe56aSColin Percival return 1 139248ffe56aSColin Percival fi 139348ffe56aSColin Percival 139448ffe56aSColin Percival # Remove the first three fields. 139548ffe56aSColin Percival gunzip -c < files/$1.gz | 139648ffe56aSColin Percival cut -f 4- -d '|' > sanitycheck.tmp 139748ffe56aSColin Percival 139848ffe56aSColin Percival # Sanity check entries with type 'f' 139948ffe56aSColin Percival if grep -E '^f' sanitycheck.tmp | 140048ffe56aSColin Percival grep -qvE "^f\|${M}\|${H}\|${P}*\$"; then 140148ffe56aSColin Percival fetch_metadata_bogus "" 140248ffe56aSColin Percival return 1 140348ffe56aSColin Percival fi 140448ffe56aSColin Percival 140548ffe56aSColin Percival # Sanity check entries with type 'd' 140648ffe56aSColin Percival if grep -E '^d' sanitycheck.tmp | 140748ffe56aSColin Percival grep -qvE "^d\|${M}\|\|\$"; then 140848ffe56aSColin Percival fetch_metadata_bogus "" 140948ffe56aSColin Percival return 1 141048ffe56aSColin Percival fi 141148ffe56aSColin Percival 141248ffe56aSColin Percival # Sanity check entries with type 'L' 141348ffe56aSColin Percival if grep -E '^L' sanitycheck.tmp | 141448ffe56aSColin Percival grep -qvE "^L\|${M}\|${P}*\|\$"; then 141548ffe56aSColin Percival fetch_metadata_bogus "" 141648ffe56aSColin Percival return 1 141748ffe56aSColin Percival fi 141848ffe56aSColin Percival 141948ffe56aSColin Percival # Sanity check entries with type '-' 142048ffe56aSColin Percival if grep -E '^-' sanitycheck.tmp | 142148ffe56aSColin Percival grep -qvE "^-\|\|\|\|\|\|"; then 142248ffe56aSColin Percival fetch_metadata_bogus "" 142348ffe56aSColin Percival return 1 142448ffe56aSColin Percival fi 142548ffe56aSColin Percival 142648ffe56aSColin Percival # Clean up 142748ffe56aSColin Percival rm sanitycheck.tmp 142848ffe56aSColin Percival} 142948ffe56aSColin Percival 143048ffe56aSColin Percival# Fetch the metadata index and metadata files listed in $@, 143148ffe56aSColin Percival# taking advantage of metadata patches where possible. 143248ffe56aSColin Percivalfetch_metadata () { 143348ffe56aSColin Percival fetch_metadata_index || return 1 143448ffe56aSColin Percival fetch_metadata_index_merge $@ || return 1 143548ffe56aSColin Percival fetch_metadata_index_sanity || return 1 143648ffe56aSColin Percival 143748ffe56aSColin Percival # Generate a list of wanted metadata patches 143848ffe56aSColin Percival join -t '|' -o 1.2,2.2 tINDEX.present tINDEX.new | 143948ffe56aSColin Percival fetch_make_patchlist > patchlist 144048ffe56aSColin Percival 144148ffe56aSColin Percival if [ -s patchlist ]; then 144248ffe56aSColin Percival # Attempt to fetch metadata patches 144348ffe56aSColin Percival echo -n "Fetching `wc -l < patchlist | tr -d ' '` " 144448ffe56aSColin Percival echo ${NDEBUG} "metadata patches.${DDSTATS}" 144548ffe56aSColin Percival tr '|' '-' < patchlist | 144648ffe56aSColin Percival lam -s "${FETCHDIR}/tp/" - -s ".gz" | 144748ffe56aSColin Percival xargs ${XARGST} ${PHTTPGET} ${SERVERNAME} \ 144848ffe56aSColin Percival 2>${STATSREDIR} | fetch_progress 144948ffe56aSColin Percival echo "done." 145048ffe56aSColin Percival 145148ffe56aSColin Percival # Attempt to apply metadata patches 145248ffe56aSColin Percival echo -n "Applying metadata patches... " 145348ffe56aSColin Percival tr '|' ' ' < patchlist | 145448ffe56aSColin Percival while read X Y; do 145548ffe56aSColin Percival if [ ! -f "${X}-${Y}.gz" ]; then continue; fi 145648ffe56aSColin Percival gunzip -c < ${X}-${Y}.gz > diff 145748ffe56aSColin Percival gunzip -c < files/${X}.gz > diff-OLD 145848ffe56aSColin Percival 145948ffe56aSColin Percival # Figure out which lines are being added and removed 146048ffe56aSColin Percival grep -E '^-' diff | 146148ffe56aSColin Percival cut -c 2- | 146248ffe56aSColin Percival while read PREFIX; do 146348ffe56aSColin Percival look "${PREFIX}" diff-OLD 146448ffe56aSColin Percival done | 146548ffe56aSColin Percival sort > diff-rm 146648ffe56aSColin Percival grep -E '^\+' diff | 146748ffe56aSColin Percival cut -c 2- > diff-add 146848ffe56aSColin Percival 146948ffe56aSColin Percival # Generate the new file 147048ffe56aSColin Percival comm -23 diff-OLD diff-rm | 147148ffe56aSColin Percival sort - diff-add > diff-NEW 147248ffe56aSColin Percival 147348ffe56aSColin Percival if [ `${SHA256} -q diff-NEW` = ${Y} ]; then 147448ffe56aSColin Percival mv diff-NEW files/${Y} 147548ffe56aSColin Percival gzip -n files/${Y} 147648ffe56aSColin Percival else 147748ffe56aSColin Percival mv diff-NEW ${Y}.bad 147848ffe56aSColin Percival fi 147948ffe56aSColin Percival rm -f ${X}-${Y}.gz diff 148048ffe56aSColin Percival rm -f diff-OLD diff-NEW diff-add diff-rm 148148ffe56aSColin Percival done 2>${QUIETREDIR} 148248ffe56aSColin Percival echo "done." 148348ffe56aSColin Percival fi 148448ffe56aSColin Percival 148548ffe56aSColin Percival # Update metadata without patches 148648ffe56aSColin Percival cut -f 2 -d '|' < tINDEX.new | 148748ffe56aSColin Percival while read Y; do 148848ffe56aSColin Percival if [ ! -f "files/${Y}.gz" ]; then 148948ffe56aSColin Percival echo ${Y}; 149048ffe56aSColin Percival fi 1491bce02f98SColin Percival done | 1492bce02f98SColin Percival sort -u > filelist 149348ffe56aSColin Percival 149448ffe56aSColin Percival if [ -s filelist ]; then 149548ffe56aSColin Percival echo -n "Fetching `wc -l < filelist | tr -d ' '` " 149648ffe56aSColin Percival echo ${NDEBUG} "metadata files... " 149748ffe56aSColin Percival lam -s "${FETCHDIR}/m/" - -s ".gz" < filelist | 149848ffe56aSColin Percival xargs ${XARGST} ${PHTTPGET} ${SERVERNAME} \ 149948ffe56aSColin Percival 2>${QUIETREDIR} 150048ffe56aSColin Percival 150148ffe56aSColin Percival while read Y; do 150248ffe56aSColin Percival if ! [ -f ${Y}.gz ]; then 150348ffe56aSColin Percival echo "failed." 150448ffe56aSColin Percival return 1 150548ffe56aSColin Percival fi 150648ffe56aSColin Percival if [ `gunzip -c < ${Y}.gz | 150748ffe56aSColin Percival ${SHA256} -q` = ${Y} ]; then 150848ffe56aSColin Percival mv ${Y}.gz files/${Y}.gz 150948ffe56aSColin Percival else 151048ffe56aSColin Percival echo "metadata is corrupt." 151148ffe56aSColin Percival return 1 151248ffe56aSColin Percival fi 151348ffe56aSColin Percival done < filelist 151448ffe56aSColin Percival echo "done." 151548ffe56aSColin Percival fi 151648ffe56aSColin Percival 151748ffe56aSColin Percival# Sanity-check the metadata files. 151848ffe56aSColin Percival cut -f 2 -d '|' tINDEX.new > filelist 151948ffe56aSColin Percival while read X; do 152048ffe56aSColin Percival fetch_metadata_sanity ${X} || return 1 152148ffe56aSColin Percival done < filelist 152248ffe56aSColin Percival 152348ffe56aSColin Percival# Remove files which are no longer needed 152448ffe56aSColin Percival cut -f 2 -d '|' tINDEX.present | 152548ffe56aSColin Percival sort > oldfiles 152648ffe56aSColin Percival cut -f 2 -d '|' tINDEX.new | 152748ffe56aSColin Percival sort | 152848ffe56aSColin Percival comm -13 - oldfiles | 152948ffe56aSColin Percival lam -s "files/" - -s ".gz" | 153048ffe56aSColin Percival xargs rm -f 153148ffe56aSColin Percival rm patchlist filelist oldfiles 153248ffe56aSColin Percival rm ${TINDEXHASH} 153348ffe56aSColin Percival 153448ffe56aSColin Percival# We're done! 153548ffe56aSColin Percival mv tINDEX.new tINDEX.present 153648ffe56aSColin Percival mv tag.new tag 153748ffe56aSColin Percival 153848ffe56aSColin Percival return 0 153948ffe56aSColin Percival} 154048ffe56aSColin Percival 1541db6b0a61SColin Percival# Extract a subset of a downloaded metadata file containing only the parts 1542db6b0a61SColin Percival# which are listed in COMPONENTS. 1543db6b0a61SColin Percivalfetch_filter_metadata_components () { 1544db6b0a61SColin Percival METAHASH=`look "$1|" tINDEX.present | cut -f 2 -d '|'` 1545db6b0a61SColin Percival gunzip -c < files/${METAHASH}.gz > $1.all 1546db6b0a61SColin Percival 1547db6b0a61SColin Percival # Fish out the lines belonging to components we care about. 1548db6b0a61SColin Percival for C in ${COMPONENTS}; do 1549db6b0a61SColin Percival look "`echo ${C} | tr '/' '|'`|" $1.all 1550db6b0a61SColin Percival done > $1 1551db6b0a61SColin Percival 1552db6b0a61SColin Percival # Remove temporary file. 1553db6b0a61SColin Percival rm $1.all 1554db6b0a61SColin Percival} 1555db6b0a61SColin Percival 1556b698a3abSColin Percival# Generate a filtered version of the metadata file $1 from the downloaded 155748ffe56aSColin Percival# file, by fishing out the lines corresponding to components we're trying 155848ffe56aSColin Percival# to keep updated, and then removing lines corresponding to paths we want 155948ffe56aSColin Percival# to ignore. 156048ffe56aSColin Percivalfetch_filter_metadata () { 156148ffe56aSColin Percival # Fish out the lines belonging to components we care about. 1562db6b0a61SColin Percival fetch_filter_metadata_components $1 1563db6b0a61SColin Percival 156448ffe56aSColin Percival # Canonicalize directory names by removing any trailing / in 156548ffe56aSColin Percival # order to avoid listing directories multiple times if they 156648ffe56aSColin Percival # belong to multiple components. Turning "/" into "" doesn't 156748ffe56aSColin Percival # matter, since we add a leading "/" when we use paths later. 1568db6b0a61SColin Percival cut -f 3- -d '|' $1 | 156948ffe56aSColin Percival sed -e 's,/|d|,|d|,' | 15707e654612SColin Percival sed -e 's,/|-|,|-|,' | 157148ffe56aSColin Percival sort -u > $1.tmp 157248ffe56aSColin Percival 157348ffe56aSColin Percival # Figure out which lines to ignore and remove them. 157448ffe56aSColin Percival for X in ${IGNOREPATHS}; do 157548ffe56aSColin Percival grep -E "^${X}" $1.tmp 157648ffe56aSColin Percival done | 157748ffe56aSColin Percival sort -u | 157848ffe56aSColin Percival comm -13 - $1.tmp > $1 157948ffe56aSColin Percival 158048ffe56aSColin Percival # Remove temporary files. 1581db6b0a61SColin Percival rm $1.tmp 158248ffe56aSColin Percival} 158348ffe56aSColin Percival 1584db6b0a61SColin Percival# Filter the metadata file $1 by adding lines with "/boot/$2" 1585bce02f98SColin Percival# replaced by ${KERNELDIR} (which is `sysctl -n kern.bootfile` minus the 1586db6b0a61SColin Percival# trailing "/kernel"); and if "/boot/$2" does not exist, remove 1587bce02f98SColin Percival# the original lines which start with that. 1588bce02f98SColin Percival# Put another way: Deal with the fact that the FOO kernel is sometimes 1589bce02f98SColin Percival# installed in /boot/FOO/ and is sometimes installed elsewhere. 159048ffe56aSColin Percivalfetch_filter_kernel_names () { 1591db6b0a61SColin Percival grep ^/boot/$2 $1 | 1592db6b0a61SColin Percival sed -e "s,/boot/$2,${KERNELDIR},g" | 159348ffe56aSColin Percival sort - $1 > $1.tmp 159448ffe56aSColin Percival mv $1.tmp $1 1595bce02f98SColin Percival 1596db6b0a61SColin Percival if ! [ -d /boot/$2 ]; then 1597db6b0a61SColin Percival grep -v ^/boot/$2 $1 > $1.tmp 1598bce02f98SColin Percival mv $1.tmp $1 1599bce02f98SColin Percival fi 160048ffe56aSColin Percival} 160148ffe56aSColin Percival 160248ffe56aSColin Percival# For all paths appearing in $1 or $3, inspect the system 160348ffe56aSColin Percival# and generate $2 describing what is currently installed. 160448ffe56aSColin Percivalfetch_inspect_system () { 160548ffe56aSColin Percival # No errors yet... 160648ffe56aSColin Percival rm -f .err 160748ffe56aSColin Percival 160848ffe56aSColin Percival # Tell the user why his disk is suddenly making lots of noise 160948ffe56aSColin Percival echo -n "Inspecting system... " 161048ffe56aSColin Percival 161148ffe56aSColin Percival # Generate list of files to inspect 161248ffe56aSColin Percival cat $1 $3 | 161348ffe56aSColin Percival cut -f 1 -d '|' | 161448ffe56aSColin Percival sort -u > filelist 161548ffe56aSColin Percival 161648ffe56aSColin Percival # Examine each file and output lines of the form 161748ffe56aSColin Percival # /path/to/file|type|device-inum|user|group|perm|flags|value 161848ffe56aSColin Percival # sorted by device and inode number. 161948ffe56aSColin Percival while read F; do 162048ffe56aSColin Percival # If the symlink/file/directory does not exist, record this. 162148ffe56aSColin Percival if ! [ -e ${BASEDIR}/${F} ]; then 162248ffe56aSColin Percival echo "${F}|-||||||" 162348ffe56aSColin Percival continue 162448ffe56aSColin Percival fi 162548ffe56aSColin Percival if ! [ -r ${BASEDIR}/${F} ]; then 162648ffe56aSColin Percival echo "Cannot read file: ${BASEDIR}/${F}" \ 162748ffe56aSColin Percival >/dev/stderr 162848ffe56aSColin Percival touch .err 162948ffe56aSColin Percival return 1 163048ffe56aSColin Percival fi 163148ffe56aSColin Percival 163248ffe56aSColin Percival # Otherwise, output an index line. 163348ffe56aSColin Percival if [ -L ${BASEDIR}/${F} ]; then 163448ffe56aSColin Percival echo -n "${F}|L|" 163548ffe56aSColin Percival stat -n -f '%d-%i|%u|%g|%Mp%Lp|%Of|' ${BASEDIR}/${F}; 163648ffe56aSColin Percival readlink ${BASEDIR}/${F}; 163748ffe56aSColin Percival elif [ -f ${BASEDIR}/${F} ]; then 163848ffe56aSColin Percival echo -n "${F}|f|" 163948ffe56aSColin Percival stat -n -f '%d-%i|%u|%g|%Mp%Lp|%Of|' ${BASEDIR}/${F}; 164048ffe56aSColin Percival sha256 -q ${BASEDIR}/${F}; 164148ffe56aSColin Percival elif [ -d ${BASEDIR}/${F} ]; then 164248ffe56aSColin Percival echo -n "${F}|d|" 164348ffe56aSColin Percival stat -f '%d-%i|%u|%g|%Mp%Lp|%Of|' ${BASEDIR}/${F}; 164448ffe56aSColin Percival else 164548ffe56aSColin Percival echo "Unknown file type: ${BASEDIR}/${F}" \ 164648ffe56aSColin Percival >/dev/stderr 164748ffe56aSColin Percival touch .err 164848ffe56aSColin Percival return 1 164948ffe56aSColin Percival fi 165048ffe56aSColin Percival done < filelist | 165148ffe56aSColin Percival sort -k 3,3 -t '|' > $2.tmp 165248ffe56aSColin Percival rm filelist 165348ffe56aSColin Percival 16546dcc68c8SBenedict Reuschling # Check if an error occurred during system inspection 165548ffe56aSColin Percival if [ -f .err ]; then 165648ffe56aSColin Percival return 1 165748ffe56aSColin Percival fi 165848ffe56aSColin Percival 165948ffe56aSColin Percival # Convert to the form 166048ffe56aSColin Percival # /path/to/file|type|user|group|perm|flags|value|hlink 166148ffe56aSColin Percival # by resolving identical device and inode numbers into hard links. 166248ffe56aSColin Percival cut -f 1,3 -d '|' $2.tmp | 166348ffe56aSColin Percival sort -k 1,1 -t '|' | 166448ffe56aSColin Percival sort -s -u -k 2,2 -t '|' | 166548ffe56aSColin Percival join -1 2 -2 3 -t '|' - $2.tmp | 166648ffe56aSColin Percival awk -F \| -v OFS=\| \ 166748ffe56aSColin Percival '{ 166848ffe56aSColin Percival if (($2 == $3) || ($4 == "-")) 166948ffe56aSColin Percival print $3,$4,$5,$6,$7,$8,$9,"" 167048ffe56aSColin Percival else 167148ffe56aSColin Percival print $3,$4,$5,$6,$7,$8,$9,$2 167248ffe56aSColin Percival }' | 167348ffe56aSColin Percival sort > $2 167448ffe56aSColin Percival rm $2.tmp 167548ffe56aSColin Percival 167648ffe56aSColin Percival # We're finished looking around 167748ffe56aSColin Percival echo "done." 167848ffe56aSColin Percival} 167948ffe56aSColin Percival 1680db6b0a61SColin Percival# For any paths matching ${MERGECHANGES}, compare $1 and $2 and find any 1681db6b0a61SColin Percival# files which differ; generate $3 containing these paths and the old hashes. 1682db6b0a61SColin Percivalfetch_filter_mergechanges () { 1683db6b0a61SColin Percival # Pull out the paths and hashes of the files matching ${MERGECHANGES}. 1684db6b0a61SColin Percival for F in $1 $2; do 1685db6b0a61SColin Percival for X in ${MERGECHANGES}; do 1686db6b0a61SColin Percival grep -E "^${X}" ${F} 1687db6b0a61SColin Percival done | 1688db6b0a61SColin Percival cut -f 1,2,7 -d '|' | 1689db6b0a61SColin Percival sort > ${F}-values 1690db6b0a61SColin Percival done 1691db6b0a61SColin Percival 1692db6b0a61SColin Percival # Any line in $2-values which doesn't appear in $1-values and is a 1693db6b0a61SColin Percival # file means that we should list the path in $3. 1694db6b0a61SColin Percival comm -13 $1-values $2-values | 1695db6b0a61SColin Percival fgrep '|f|' | 1696db6b0a61SColin Percival cut -f 1 -d '|' > $2-paths 1697db6b0a61SColin Percival 1698db6b0a61SColin Percival # For each path, pull out one (and only one!) entry from $1-values. 1699db6b0a61SColin Percival # Note that we cannot distinguish which "old" version the user made 1700db6b0a61SColin Percival # changes to; but hopefully any changes which occur due to security 1701db6b0a61SColin Percival # updates will exist in both the "new" version and the version which 1702db6b0a61SColin Percival # the user has installed, so the merging will still work. 1703db6b0a61SColin Percival while read X; do 1704db6b0a61SColin Percival look "${X}|" $1-values | 1705db6b0a61SColin Percival head -1 1706db6b0a61SColin Percival done < $2-paths > $3 1707db6b0a61SColin Percival 1708db6b0a61SColin Percival # Clean up 1709db6b0a61SColin Percival rm $1-values $2-values $2-paths 1710db6b0a61SColin Percival} 1711db6b0a61SColin Percival 171248ffe56aSColin Percival# For any paths matching ${UPDATEIFUNMODIFIED}, remove lines from $[123] 1713db6b0a61SColin Percival# which correspond to lines in $2 with hashes not matching $1 or $3, unless 1714db6b0a61SColin Percival# the paths are listed in $4. For entries in $2 marked "not present" 1715db6b0a61SColin Percival# (aka. type -), remove lines from $[123] unless there is a corresponding 1716db6b0a61SColin Percival# entry in $1. 171748ffe56aSColin Percivalfetch_filter_unmodified_notpresent () { 171848ffe56aSColin Percival # Figure out which lines of $1 and $3 correspond to bits which 171948ffe56aSColin Percival # should only be updated if they haven't changed, and fish out 172048ffe56aSColin Percival # the (path, type, value) tuples. 172148ffe56aSColin Percival # NOTE: We don't consider a file to be "modified" if it matches 172248ffe56aSColin Percival # the hash from $3. 172348ffe56aSColin Percival for X in ${UPDATEIFUNMODIFIED}; do 172448ffe56aSColin Percival grep -E "^${X}" $1 172548ffe56aSColin Percival grep -E "^${X}" $3 172648ffe56aSColin Percival done | 172748ffe56aSColin Percival cut -f 1,2,7 -d '|' | 172848ffe56aSColin Percival sort > $1-values 172948ffe56aSColin Percival 173048ffe56aSColin Percival # Do the same for $2. 173148ffe56aSColin Percival for X in ${UPDATEIFUNMODIFIED}; do 173248ffe56aSColin Percival grep -E "^${X}" $2 173348ffe56aSColin Percival done | 173448ffe56aSColin Percival cut -f 1,2,7 -d '|' | 173548ffe56aSColin Percival sort > $2-values 173648ffe56aSColin Percival 173748ffe56aSColin Percival # Any entry in $2-values which is not in $1-values corresponds to 1738db6b0a61SColin Percival # a path which we need to remove from $1, $2, and $3, unless it 1739db6b0a61SColin Percival # that path appears in $4. 1740db6b0a61SColin Percival comm -13 $1-values $2-values | 1741db6b0a61SColin Percival sort -t '|' -k 1,1 > mlines.tmp 1742db6b0a61SColin Percival cut -f 1 -d '|' $4 | 1743db6b0a61SColin Percival sort | 1744db6b0a61SColin Percival join -v 2 -t '|' - mlines.tmp | 1745db6b0a61SColin Percival sort > mlines 1746db6b0a61SColin Percival rm $1-values $2-values mlines.tmp 174748ffe56aSColin Percival 174848ffe56aSColin Percival # Any lines in $2 which are not in $1 AND are "not present" lines 174948ffe56aSColin Percival # also belong in mlines. 175048ffe56aSColin Percival comm -13 $1 $2 | 175148ffe56aSColin Percival cut -f 1,2,7 -d '|' | 175248ffe56aSColin Percival fgrep '|-|' >> mlines 175348ffe56aSColin Percival 175448ffe56aSColin Percival # Remove lines from $1, $2, and $3 175548ffe56aSColin Percival for X in $1 $2 $3; do 175648ffe56aSColin Percival sort -t '|' -k 1,1 ${X} > ${X}.tmp 175748ffe56aSColin Percival cut -f 1 -d '|' < mlines | 175848ffe56aSColin Percival sort | 175948ffe56aSColin Percival join -v 2 -t '|' - ${X}.tmp | 176048ffe56aSColin Percival sort > ${X} 176148ffe56aSColin Percival rm ${X}.tmp 176248ffe56aSColin Percival done 176348ffe56aSColin Percival 176448ffe56aSColin Percival # Store a list of the modified files, for future reference 176548ffe56aSColin Percival fgrep -v '|-|' mlines | 176648ffe56aSColin Percival cut -f 1 -d '|' > modifiedfiles 176748ffe56aSColin Percival rm mlines 176848ffe56aSColin Percival} 176948ffe56aSColin Percival 177048ffe56aSColin Percival# For each entry in $1 of type -, remove any corresponding 177148ffe56aSColin Percival# entry from $2 if ${ALLOWADD} != "yes". Remove all entries 177248ffe56aSColin Percival# of type - from $1. 177348ffe56aSColin Percivalfetch_filter_allowadd () { 177448ffe56aSColin Percival cut -f 1,2 -d '|' < $1 | 177548ffe56aSColin Percival fgrep '|-' | 177648ffe56aSColin Percival cut -f 1 -d '|' > filesnotpresent 177748ffe56aSColin Percival 177848ffe56aSColin Percival if [ ${ALLOWADD} != "yes" ]; then 177948ffe56aSColin Percival sort < $2 | 178048ffe56aSColin Percival join -v 1 -t '|' - filesnotpresent | 178148ffe56aSColin Percival sort > $2.tmp 178248ffe56aSColin Percival mv $2.tmp $2 178348ffe56aSColin Percival fi 178448ffe56aSColin Percival 178548ffe56aSColin Percival sort < $1 | 178648ffe56aSColin Percival join -v 1 -t '|' - filesnotpresent | 178748ffe56aSColin Percival sort > $1.tmp 178848ffe56aSColin Percival mv $1.tmp $1 178948ffe56aSColin Percival rm filesnotpresent 179048ffe56aSColin Percival} 179148ffe56aSColin Percival 179248ffe56aSColin Percival# If ${ALLOWDELETE} != "yes", then remove any entries from $1 179348ffe56aSColin Percival# which don't correspond to entries in $2. 179448ffe56aSColin Percivalfetch_filter_allowdelete () { 179548ffe56aSColin Percival # Produce a lists ${PATH}|${TYPE} 179648ffe56aSColin Percival for X in $1 $2; do 179748ffe56aSColin Percival cut -f 1-2 -d '|' < ${X} | 179848ffe56aSColin Percival sort -u > ${X}.nodes 179948ffe56aSColin Percival done 180048ffe56aSColin Percival 180148ffe56aSColin Percival # Figure out which lines need to be removed from $1. 180248ffe56aSColin Percival if [ ${ALLOWDELETE} != "yes" ]; then 180348ffe56aSColin Percival comm -23 $1.nodes $2.nodes > $1.badnodes 180448ffe56aSColin Percival else 180548ffe56aSColin Percival : > $1.badnodes 180648ffe56aSColin Percival fi 180748ffe56aSColin Percival 180848ffe56aSColin Percival # Remove the relevant lines from $1 180948ffe56aSColin Percival while read X; do 181048ffe56aSColin Percival look "${X}|" $1 181148ffe56aSColin Percival done < $1.badnodes | 181248ffe56aSColin Percival comm -13 - $1 > $1.tmp 181348ffe56aSColin Percival mv $1.tmp $1 181448ffe56aSColin Percival 181548ffe56aSColin Percival rm $1.badnodes $1.nodes $2.nodes 181648ffe56aSColin Percival} 181748ffe56aSColin Percival 181848ffe56aSColin Percival# If ${KEEPMODIFIEDMETADATA} == "yes", then for each entry in $2 181948ffe56aSColin Percival# with metadata not matching any entry in $1, replace the corresponding 182048ffe56aSColin Percival# line of $3 with one having the same metadata as the entry in $2. 182148ffe56aSColin Percivalfetch_filter_modified_metadata () { 182248ffe56aSColin Percival # Fish out the metadata from $1 and $2 182348ffe56aSColin Percival for X in $1 $2; do 182448ffe56aSColin Percival cut -f 1-6 -d '|' < ${X} > ${X}.metadata 182548ffe56aSColin Percival done 182648ffe56aSColin Percival 182748ffe56aSColin Percival # Find the metadata we need to keep 182848ffe56aSColin Percival if [ ${KEEPMODIFIEDMETADATA} = "yes" ]; then 182948ffe56aSColin Percival comm -13 $1.metadata $2.metadata > keepmeta 183048ffe56aSColin Percival else 183148ffe56aSColin Percival : > keepmeta 183248ffe56aSColin Percival fi 183348ffe56aSColin Percival 183448ffe56aSColin Percival # Extract the lines which we need to remove from $3, and 183548ffe56aSColin Percival # construct the lines which we need to add to $3. 183648ffe56aSColin Percival : > $3.remove 183748ffe56aSColin Percival : > $3.add 183848ffe56aSColin Percival while read LINE; do 183948ffe56aSColin Percival NODE=`echo "${LINE}" | cut -f 1-2 -d '|'` 184048ffe56aSColin Percival look "${NODE}|" $3 >> $3.remove 184148ffe56aSColin Percival look "${NODE}|" $3 | 184248ffe56aSColin Percival cut -f 7- -d '|' | 184348ffe56aSColin Percival lam -s "${LINE}|" - >> $3.add 184448ffe56aSColin Percival done < keepmeta 184548ffe56aSColin Percival 184648ffe56aSColin Percival # Remove the specified lines and add the new lines. 184748ffe56aSColin Percival sort $3.remove | 184848ffe56aSColin Percival comm -13 - $3 | 184948ffe56aSColin Percival sort -u - $3.add > $3.tmp 185048ffe56aSColin Percival mv $3.tmp $3 185148ffe56aSColin Percival 185248ffe56aSColin Percival rm keepmeta $1.metadata $2.metadata $3.add $3.remove 185348ffe56aSColin Percival} 185448ffe56aSColin Percival 185548ffe56aSColin Percival# Remove lines from $1 and $2 which are identical; 185648ffe56aSColin Percival# no need to update a file if it isn't changing. 185748ffe56aSColin Percivalfetch_filter_uptodate () { 185848ffe56aSColin Percival comm -23 $1 $2 > $1.tmp 185948ffe56aSColin Percival comm -13 $1 $2 > $2.tmp 186048ffe56aSColin Percival 186148ffe56aSColin Percival mv $1.tmp $1 186248ffe56aSColin Percival mv $2.tmp $2 186348ffe56aSColin Percival} 186448ffe56aSColin Percival 1865db6b0a61SColin Percival# Fetch any "clean" old versions of files we need for merging changes. 1866db6b0a61SColin Percivalfetch_files_premerge () { 1867db6b0a61SColin Percival # We only need to do anything if $1 is non-empty. 1868db6b0a61SColin Percival if [ -s $1 ]; then 1869db6b0a61SColin Percival # Tell the user what we're doing 1870db6b0a61SColin Percival echo -n "Fetching files from ${OLDRELNUM} for merging... " 1871db6b0a61SColin Percival 1872db6b0a61SColin Percival # List of files wanted 1873db6b0a61SColin Percival fgrep '|f|' < $1 | 1874db6b0a61SColin Percival cut -f 3 -d '|' | 1875db6b0a61SColin Percival sort -u > files.wanted 1876db6b0a61SColin Percival 1877db6b0a61SColin Percival # Only fetch the files we don't already have 1878db6b0a61SColin Percival while read Y; do 1879db6b0a61SColin Percival if [ ! -f "files/${Y}.gz" ]; then 1880db6b0a61SColin Percival echo ${Y}; 1881db6b0a61SColin Percival fi 1882db6b0a61SColin Percival done < files.wanted > filelist 1883db6b0a61SColin Percival 1884db6b0a61SColin Percival # Actually fetch them 1885db6b0a61SColin Percival lam -s "${OLDFETCHDIR}/f/" - -s ".gz" < filelist | 1886db6b0a61SColin Percival xargs ${XARGST} ${PHTTPGET} ${SERVERNAME} \ 1887db6b0a61SColin Percival 2>${QUIETREDIR} 1888db6b0a61SColin Percival 1889db6b0a61SColin Percival # Make sure we got them all, and move them into /files/ 1890db6b0a61SColin Percival while read Y; do 1891db6b0a61SColin Percival if ! [ -f ${Y}.gz ]; then 1892db6b0a61SColin Percival echo "failed." 1893db6b0a61SColin Percival return 1 1894db6b0a61SColin Percival fi 1895db6b0a61SColin Percival if [ `gunzip -c < ${Y}.gz | 1896db6b0a61SColin Percival ${SHA256} -q` = ${Y} ]; then 1897db6b0a61SColin Percival mv ${Y}.gz files/${Y}.gz 1898db6b0a61SColin Percival else 1899db6b0a61SColin Percival echo "${Y} has incorrect hash." 1900db6b0a61SColin Percival return 1 1901db6b0a61SColin Percival fi 1902db6b0a61SColin Percival done < filelist 1903db6b0a61SColin Percival echo "done." 1904db6b0a61SColin Percival 1905db6b0a61SColin Percival # Clean up 1906db6b0a61SColin Percival rm filelist files.wanted 1907db6b0a61SColin Percival fi 1908db6b0a61SColin Percival} 1909db6b0a61SColin Percival 191048ffe56aSColin Percival# Prepare to fetch files: Generate a list of the files we need, 191148ffe56aSColin Percival# copy the unmodified files we have into /files/, and generate 191248ffe56aSColin Percival# a list of patches to download. 191348ffe56aSColin Percivalfetch_files_prepare () { 191448ffe56aSColin Percival # Tell the user why his disk is suddenly making lots of noise 191548ffe56aSColin Percival echo -n "Preparing to download files... " 191648ffe56aSColin Percival 191748ffe56aSColin Percival # Reduce indices to ${PATH}|${HASH} pairs 191848ffe56aSColin Percival for X in $1 $2 $3; do 191948ffe56aSColin Percival cut -f 1,2,7 -d '|' < ${X} | 192048ffe56aSColin Percival fgrep '|f|' | 192148ffe56aSColin Percival cut -f 1,3 -d '|' | 192248ffe56aSColin Percival sort > ${X}.hashes 192348ffe56aSColin Percival done 192448ffe56aSColin Percival 192548ffe56aSColin Percival # List of files wanted 192648ffe56aSColin Percival cut -f 2 -d '|' < $3.hashes | 19272328d598SColin Percival sort -u | 19282328d598SColin Percival while read HASH; do 19292328d598SColin Percival if ! [ -f files/${HASH}.gz ]; then 19302328d598SColin Percival echo ${HASH} 19312328d598SColin Percival fi 19322328d598SColin Percival done > files.wanted 193348ffe56aSColin Percival 193448ffe56aSColin Percival # Generate a list of unmodified files 193548ffe56aSColin Percival comm -12 $1.hashes $2.hashes | 193648ffe56aSColin Percival sort -k 1,1 -t '|' > unmodified.files 193748ffe56aSColin Percival 193848ffe56aSColin Percival # Copy all files into /files/. We only need the unmodified files 193948ffe56aSColin Percival # for use in patching; but we'll want all of them if the user asks 194048ffe56aSColin Percival # to rollback the updates later. 1941210b8123SColin Percival while read LINE; do 1942210b8123SColin Percival F=`echo "${LINE}" | cut -f 1 -d '|'` 1943210b8123SColin Percival HASH=`echo "${LINE}" | cut -f 2 -d '|'` 1944210b8123SColin Percival 1945210b8123SColin Percival # Skip files we already have. 1946210b8123SColin Percival if [ -f files/${HASH}.gz ]; then 1947210b8123SColin Percival continue 1948210b8123SColin Percival fi 1949210b8123SColin Percival 1950210b8123SColin Percival # Make sure the file hasn't changed. 195148ffe56aSColin Percival cp "${BASEDIR}/${F}" tmpfile 1952210b8123SColin Percival if [ `sha256 -q tmpfile` != ${HASH} ]; then 1953210b8123SColin Percival echo 1954210b8123SColin Percival echo "File changed while FreeBSD Update running: ${F}" 1955210b8123SColin Percival return 1 1956210b8123SColin Percival fi 1957210b8123SColin Percival 1958210b8123SColin Percival # Place the file into storage. 1959210b8123SColin Percival gzip -c < tmpfile > files/${HASH}.gz 196048ffe56aSColin Percival rm tmpfile 1961210b8123SColin Percival done < $2.hashes 196248ffe56aSColin Percival 196348ffe56aSColin Percival # Produce a list of patches to download 196448ffe56aSColin Percival sort -k 1,1 -t '|' $3.hashes | 196548ffe56aSColin Percival join -t '|' -o 2.2,1.2 - unmodified.files | 196648ffe56aSColin Percival fetch_make_patchlist > patchlist 196748ffe56aSColin Percival 196848ffe56aSColin Percival # Garbage collect 196948ffe56aSColin Percival rm unmodified.files $1.hashes $2.hashes $3.hashes 197048ffe56aSColin Percival 197148ffe56aSColin Percival # We don't need the list of possible old files any more. 197248ffe56aSColin Percival rm $1 197348ffe56aSColin Percival 197448ffe56aSColin Percival # We're finished making noise 197548ffe56aSColin Percival echo "done." 197648ffe56aSColin Percival} 197748ffe56aSColin Percival 197848ffe56aSColin Percival# Fetch files. 197948ffe56aSColin Percivalfetch_files () { 198048ffe56aSColin Percival # Attempt to fetch patches 198148ffe56aSColin Percival if [ -s patchlist ]; then 198248ffe56aSColin Percival echo -n "Fetching `wc -l < patchlist | tr -d ' '` " 198348ffe56aSColin Percival echo ${NDEBUG} "patches.${DDSTATS}" 198448ffe56aSColin Percival tr '|' '-' < patchlist | 1985db6b0a61SColin Percival lam -s "${PATCHDIR}/" - | 198648ffe56aSColin Percival xargs ${XARGST} ${PHTTPGET} ${SERVERNAME} \ 198748ffe56aSColin Percival 2>${STATSREDIR} | fetch_progress 198848ffe56aSColin Percival echo "done." 198948ffe56aSColin Percival 199048ffe56aSColin Percival # Attempt to apply patches 199148ffe56aSColin Percival echo -n "Applying patches... " 199248ffe56aSColin Percival tr '|' ' ' < patchlist | 199348ffe56aSColin Percival while read X Y; do 199448ffe56aSColin Percival if [ ! -f "${X}-${Y}" ]; then continue; fi 199548ffe56aSColin Percival gunzip -c < files/${X}.gz > OLD 199648ffe56aSColin Percival 199748ffe56aSColin Percival bspatch OLD NEW ${X}-${Y} 199848ffe56aSColin Percival 199948ffe56aSColin Percival if [ `${SHA256} -q NEW` = ${Y} ]; then 200048ffe56aSColin Percival mv NEW files/${Y} 200148ffe56aSColin Percival gzip -n files/${Y} 200248ffe56aSColin Percival fi 200348ffe56aSColin Percival rm -f diff OLD NEW ${X}-${Y} 200448ffe56aSColin Percival done 2>${QUIETREDIR} 200548ffe56aSColin Percival echo "done." 200648ffe56aSColin Percival fi 200748ffe56aSColin Percival 200848ffe56aSColin Percival # Download files which couldn't be generate via patching 200948ffe56aSColin Percival while read Y; do 201048ffe56aSColin Percival if [ ! -f "files/${Y}.gz" ]; then 201148ffe56aSColin Percival echo ${Y}; 201248ffe56aSColin Percival fi 201348ffe56aSColin Percival done < files.wanted > filelist 201448ffe56aSColin Percival 201548ffe56aSColin Percival if [ -s filelist ]; then 201648ffe56aSColin Percival echo -n "Fetching `wc -l < filelist | tr -d ' '` " 201748ffe56aSColin Percival echo ${NDEBUG} "files... " 201848ffe56aSColin Percival lam -s "${FETCHDIR}/f/" - -s ".gz" < filelist | 201948ffe56aSColin Percival xargs ${XARGST} ${PHTTPGET} ${SERVERNAME} \ 2020d6e1e31aSConrad Meyer 2>${STATSREDIR} | fetch_progress 202148ffe56aSColin Percival 202248ffe56aSColin Percival while read Y; do 202348ffe56aSColin Percival if ! [ -f ${Y}.gz ]; then 202448ffe56aSColin Percival echo "failed." 202548ffe56aSColin Percival return 1 202648ffe56aSColin Percival fi 202748ffe56aSColin Percival if [ `gunzip -c < ${Y}.gz | 202848ffe56aSColin Percival ${SHA256} -q` = ${Y} ]; then 202948ffe56aSColin Percival mv ${Y}.gz files/${Y}.gz 203048ffe56aSColin Percival else 203148ffe56aSColin Percival echo "${Y} has incorrect hash." 203248ffe56aSColin Percival return 1 203348ffe56aSColin Percival fi 203448ffe56aSColin Percival done < filelist 203548ffe56aSColin Percival echo "done." 203648ffe56aSColin Percival fi 203748ffe56aSColin Percival 203848ffe56aSColin Percival # Clean up 203948ffe56aSColin Percival rm files.wanted filelist patchlist 204048ffe56aSColin Percival} 204148ffe56aSColin Percival 204248ffe56aSColin Percival# Create and populate install manifest directory; and report what updates 204348ffe56aSColin Percival# are available. 204448ffe56aSColin Percivalfetch_create_manifest () { 204548ffe56aSColin Percival # If we have an existing install manifest, nuke it. 204648ffe56aSColin Percival if [ -L "${BDHASH}-install" ]; then 204748ffe56aSColin Percival rm -r ${BDHASH}-install/ 204848ffe56aSColin Percival rm ${BDHASH}-install 204948ffe56aSColin Percival fi 205048ffe56aSColin Percival 205148ffe56aSColin Percival # Report to the user if any updates were avoided due to local changes 205248ffe56aSColin Percival if [ -s modifiedfiles ]; then 2053fc24ba59SEd Maste cat - modifiedfiles <<- EOF | ${PAGER} 2054b882e02bSEnji Cooper The following files are affected by updates. No changes have 2055b882e02bSEnji Cooper been downloaded, however, because the files have been modified 2056b882e02bSEnji Cooper locally: 2057fc24ba59SEd Maste EOF 2058fc24ba59SEd Maste fi 205948ffe56aSColin Percival rm modifiedfiles 206048ffe56aSColin Percival 206148ffe56aSColin Percival # If no files will be updated, tell the user and exit 206248ffe56aSColin Percival if ! [ -s INDEX-PRESENT ] && 206348ffe56aSColin Percival ! [ -s INDEX-NEW ]; then 206448ffe56aSColin Percival rm INDEX-PRESENT INDEX-NEW 206548ffe56aSColin Percival echo 206648ffe56aSColin Percival echo -n "No updates needed to update system to " 206748ffe56aSColin Percival echo "${RELNUM}-p${RELPATCHNUM}." 206848ffe56aSColin Percival return 206948ffe56aSColin Percival fi 207048ffe56aSColin Percival 207148ffe56aSColin Percival # Divide files into (a) removed files, (b) added files, and 207248ffe56aSColin Percival # (c) updated files. 207348ffe56aSColin Percival cut -f 1 -d '|' < INDEX-PRESENT | 207448ffe56aSColin Percival sort > INDEX-PRESENT.flist 207548ffe56aSColin Percival cut -f 1 -d '|' < INDEX-NEW | 207648ffe56aSColin Percival sort > INDEX-NEW.flist 207748ffe56aSColin Percival comm -23 INDEX-PRESENT.flist INDEX-NEW.flist > files.removed 207848ffe56aSColin Percival comm -13 INDEX-PRESENT.flist INDEX-NEW.flist > files.added 207948ffe56aSColin Percival comm -12 INDEX-PRESENT.flist INDEX-NEW.flist > files.updated 208048ffe56aSColin Percival rm INDEX-PRESENT.flist INDEX-NEW.flist 208148ffe56aSColin Percival 208248ffe56aSColin Percival # Report removed files, if any 208348ffe56aSColin Percival if [ -s files.removed ]; then 2084fc24ba59SEd Maste cat - files.removed <<- EOF | ${PAGER} 2085fc24ba59SEd Maste The following files will be removed as part of updating to 2086fc24ba59SEd Maste ${RELNUM}-p${RELPATCHNUM}: 2087fc24ba59SEd Maste EOF 2088fc24ba59SEd Maste fi 208948ffe56aSColin Percival rm files.removed 209048ffe56aSColin Percival 209148ffe56aSColin Percival # Report added files, if any 209248ffe56aSColin Percival if [ -s files.added ]; then 2093fc24ba59SEd Maste cat - files.added <<- EOF | ${PAGER} 2094fc24ba59SEd Maste The following files will be added as part of updating to 2095fc24ba59SEd Maste ${RELNUM}-p${RELPATCHNUM}: 2096fc24ba59SEd Maste EOF 2097fc24ba59SEd Maste fi 209848ffe56aSColin Percival rm files.added 209948ffe56aSColin Percival 210048ffe56aSColin Percival # Report updated files, if any 210148ffe56aSColin Percival if [ -s files.updated ]; then 2102fc24ba59SEd Maste cat - files.updated <<- EOF | ${PAGER} 2103fc24ba59SEd Maste The following files will be updated as part of updating to 2104fc24ba59SEd Maste ${RELNUM}-p${RELPATCHNUM}: 2105fc24ba59SEd Maste EOF 2106fc24ba59SEd Maste fi 210748ffe56aSColin Percival rm files.updated 210848ffe56aSColin Percival 210948ffe56aSColin Percival # Create a directory for the install manifest. 211048ffe56aSColin Percival MDIR=`mktemp -d install.XXXXXX` || return 1 211148ffe56aSColin Percival 211248ffe56aSColin Percival # Populate it 211348ffe56aSColin Percival mv INDEX-PRESENT ${MDIR}/INDEX-OLD 211448ffe56aSColin Percival mv INDEX-NEW ${MDIR}/INDEX-NEW 211548ffe56aSColin Percival 211648ffe56aSColin Percival # Link it into place 211748ffe56aSColin Percival ln -s ${MDIR} ${BDHASH}-install 211848ffe56aSColin Percival} 211948ffe56aSColin Percival 212048ffe56aSColin Percival# Warn about any upcoming EoL 212148ffe56aSColin Percivalfetch_warn_eol () { 212248ffe56aSColin Percival # What's the current time? 212348ffe56aSColin Percival NOWTIME=`date "+%s"` 212448ffe56aSColin Percival 212548ffe56aSColin Percival # When did we last warn about the EoL date? 212648ffe56aSColin Percival if [ -f lasteolwarn ]; then 212748ffe56aSColin Percival LASTWARN=`cat lasteolwarn` 212848ffe56aSColin Percival else 212948ffe56aSColin Percival LASTWARN=`expr ${NOWTIME} - 63072000` 213048ffe56aSColin Percival fi 213148ffe56aSColin Percival 213248ffe56aSColin Percival # If the EoL time is past, warn. 213348ffe56aSColin Percival if [ ${EOLTIME} -lt ${NOWTIME} ]; then 213448ffe56aSColin Percival echo 213548ffe56aSColin Percival cat <<-EOF 2136b698a3abSColin Percival WARNING: `uname -sr` HAS PASSED ITS END-OF-LIFE DATE. 213748ffe56aSColin Percival Any security issues discovered after `date -r ${EOLTIME}` 213848ffe56aSColin Percival will not have been corrected. 213948ffe56aSColin Percival EOF 214048ffe56aSColin Percival return 1 214148ffe56aSColin Percival fi 214248ffe56aSColin Percival 214348ffe56aSColin Percival # Figure out how long it has been since we last warned about the 214448ffe56aSColin Percival # upcoming EoL, and how much longer we have left. 214548ffe56aSColin Percival SINCEWARN=`expr ${NOWTIME} - ${LASTWARN}` 214648ffe56aSColin Percival TIMELEFT=`expr ${EOLTIME} - ${NOWTIME}` 214748ffe56aSColin Percival 214889b14566SColin Percival # Don't warn if the EoL is more than 3 months away 214989b14566SColin Percival if [ ${TIMELEFT} -gt 7884000 ]; then 215048ffe56aSColin Percival return 0 215148ffe56aSColin Percival fi 215248ffe56aSColin Percival 215348ffe56aSColin Percival # Don't warn if the time remaining is more than 3 times the time 215448ffe56aSColin Percival # since the last warning. 215548ffe56aSColin Percival if [ ${TIMELEFT} -gt `expr ${SINCEWARN} \* 3` ]; then 215648ffe56aSColin Percival return 0 215748ffe56aSColin Percival fi 215848ffe56aSColin Percival 215948ffe56aSColin Percival # Figure out what time units to use. 216048ffe56aSColin Percival if [ ${TIMELEFT} -lt 604800 ]; then 216148ffe56aSColin Percival UNIT="day" 216248ffe56aSColin Percival SIZE=86400 216348ffe56aSColin Percival elif [ ${TIMELEFT} -lt 2678400 ]; then 216448ffe56aSColin Percival UNIT="week" 216548ffe56aSColin Percival SIZE=604800 216648ffe56aSColin Percival else 216748ffe56aSColin Percival UNIT="month" 216848ffe56aSColin Percival SIZE=2678400 216948ffe56aSColin Percival fi 217048ffe56aSColin Percival 217148ffe56aSColin Percival # Compute the right number of units 217248ffe56aSColin Percival NUM=`expr ${TIMELEFT} / ${SIZE}` 217348ffe56aSColin Percival if [ ${NUM} != 1 ]; then 217448ffe56aSColin Percival UNIT="${UNIT}s" 217548ffe56aSColin Percival fi 217648ffe56aSColin Percival 217748ffe56aSColin Percival # Print the warning 217848ffe56aSColin Percival echo 217948ffe56aSColin Percival cat <<-EOF 218048ffe56aSColin Percival WARNING: `uname -sr` is approaching its End-of-Life date. 218148ffe56aSColin Percival It is strongly recommended that you upgrade to a newer 218248ffe56aSColin Percival release within the next ${NUM} ${UNIT}. 218348ffe56aSColin Percival EOF 218448ffe56aSColin Percival 218548ffe56aSColin Percival # Update the stored time of last warning 218648ffe56aSColin Percival echo ${NOWTIME} > lasteolwarn 218748ffe56aSColin Percival} 218848ffe56aSColin Percival 218948ffe56aSColin Percival# Do the actual work involved in "fetch" / "cron". 219048ffe56aSColin Percivalfetch_run () { 219148ffe56aSColin Percival workdir_init || return 1 219248ffe56aSColin Percival 219348ffe56aSColin Percival # Prepare the mirror list. 219448ffe56aSColin Percival fetch_pick_server_init && fetch_pick_server 219548ffe56aSColin Percival 219648ffe56aSColin Percival # Try to fetch the public key until we run out of servers. 219748ffe56aSColin Percival while ! fetch_key; do 219848ffe56aSColin Percival fetch_pick_server || return 1 219948ffe56aSColin Percival done 220048ffe56aSColin Percival 220148ffe56aSColin Percival # Try to fetch the metadata index signature ("tag") until we run 220248ffe56aSColin Percival # out of available servers; and sanity check the downloaded tag. 220348ffe56aSColin Percival while ! fetch_tag; do 220448ffe56aSColin Percival fetch_pick_server || return 1 220548ffe56aSColin Percival done 220648ffe56aSColin Percival fetch_tagsanity || return 1 220748ffe56aSColin Percival 220848ffe56aSColin Percival # Fetch the latest INDEX-NEW and INDEX-OLD files. 220948ffe56aSColin Percival fetch_metadata INDEX-NEW INDEX-OLD || return 1 221048ffe56aSColin Percival 221148ffe56aSColin Percival # Generate filtered INDEX-NEW and INDEX-OLD files containing only 221248ffe56aSColin Percival # the lines which (a) belong to components we care about, and (b) 221348ffe56aSColin Percival # don't correspond to paths we're explicitly ignoring. 221448ffe56aSColin Percival fetch_filter_metadata INDEX-NEW || return 1 221548ffe56aSColin Percival fetch_filter_metadata INDEX-OLD || return 1 221648ffe56aSColin Percival 2217db6b0a61SColin Percival # Translate /boot/${KERNCONF} into ${KERNELDIR} 2218db6b0a61SColin Percival fetch_filter_kernel_names INDEX-NEW ${KERNCONF} 2219db6b0a61SColin Percival fetch_filter_kernel_names INDEX-OLD ${KERNCONF} 222048ffe56aSColin Percival 222148ffe56aSColin Percival # For all paths appearing in INDEX-OLD or INDEX-NEW, inspect the 222248ffe56aSColin Percival # system and generate an INDEX-PRESENT file. 222348ffe56aSColin Percival fetch_inspect_system INDEX-OLD INDEX-PRESENT INDEX-NEW || return 1 222448ffe56aSColin Percival 222548ffe56aSColin Percival # Based on ${UPDATEIFUNMODIFIED}, remove lines from INDEX-* which 222648ffe56aSColin Percival # correspond to lines in INDEX-PRESENT with hashes not appearing 222748ffe56aSColin Percival # in INDEX-OLD or INDEX-NEW. Also remove lines where the entry in 222848ffe56aSColin Percival # INDEX-PRESENT has type - and there isn't a corresponding entry in 222948ffe56aSColin Percival # INDEX-OLD with type -. 2230db6b0a61SColin Percival fetch_filter_unmodified_notpresent \ 2231db6b0a61SColin Percival INDEX-OLD INDEX-PRESENT INDEX-NEW /dev/null 223248ffe56aSColin Percival 223348ffe56aSColin Percival # For each entry in INDEX-PRESENT of type -, remove any corresponding 223448ffe56aSColin Percival # entry from INDEX-NEW if ${ALLOWADD} != "yes". Remove all entries 223548ffe56aSColin Percival # of type - from INDEX-PRESENT. 223648ffe56aSColin Percival fetch_filter_allowadd INDEX-PRESENT INDEX-NEW 223748ffe56aSColin Percival 223848ffe56aSColin Percival # If ${ALLOWDELETE} != "yes", then remove any entries from 223948ffe56aSColin Percival # INDEX-PRESENT which don't correspond to entries in INDEX-NEW. 224048ffe56aSColin Percival fetch_filter_allowdelete INDEX-PRESENT INDEX-NEW 224148ffe56aSColin Percival 224248ffe56aSColin Percival # If ${KEEPMODIFIEDMETADATA} == "yes", then for each entry in 224348ffe56aSColin Percival # INDEX-PRESENT with metadata not matching any entry in INDEX-OLD, 224448ffe56aSColin Percival # replace the corresponding line of INDEX-NEW with one having the 224548ffe56aSColin Percival # same metadata as the entry in INDEX-PRESENT. 224648ffe56aSColin Percival fetch_filter_modified_metadata INDEX-OLD INDEX-PRESENT INDEX-NEW 224748ffe56aSColin Percival 224848ffe56aSColin Percival # Remove lines from INDEX-PRESENT and INDEX-NEW which are identical; 224948ffe56aSColin Percival # no need to update a file if it isn't changing. 225048ffe56aSColin Percival fetch_filter_uptodate INDEX-PRESENT INDEX-NEW 225148ffe56aSColin Percival 225248ffe56aSColin Percival # Prepare to fetch files: Generate a list of the files we need, 225348ffe56aSColin Percival # copy the unmodified files we have into /files/, and generate 225448ffe56aSColin Percival # a list of patches to download. 2255210b8123SColin Percival fetch_files_prepare INDEX-OLD INDEX-PRESENT INDEX-NEW || return 1 225648ffe56aSColin Percival 225748ffe56aSColin Percival # Fetch files. 225848ffe56aSColin Percival fetch_files || return 1 225948ffe56aSColin Percival 226048ffe56aSColin Percival # Create and populate install manifest directory; and report what 226148ffe56aSColin Percival # updates are available. 226248ffe56aSColin Percival fetch_create_manifest || return 1 226348ffe56aSColin Percival 226448ffe56aSColin Percival # Warn about any upcoming EoL 226548ffe56aSColin Percival fetch_warn_eol || return 1 226648ffe56aSColin Percival} 226748ffe56aSColin Percival 2268db6b0a61SColin Percival# If StrictComponents is not "yes", generate a new components list 2269db6b0a61SColin Percival# with only the components which appear to be installed. 2270db6b0a61SColin Percivalupgrade_guess_components () { 2271db6b0a61SColin Percival if [ "${STRICTCOMPONENTS}" = "no" ]; then 2272db6b0a61SColin Percival # Generate filtered INDEX-ALL with only the components listed 2273db6b0a61SColin Percival # in COMPONENTS. 2274db6b0a61SColin Percival fetch_filter_metadata_components $1 || return 1 2275db6b0a61SColin Percival 2276db6b0a61SColin Percival # Tell the user why his disk is suddenly making lots of noise 2277db6b0a61SColin Percival echo -n "Inspecting system... " 2278db6b0a61SColin Percival 2279db6b0a61SColin Percival # Look at the files on disk, and assume that a component is 2280db6b0a61SColin Percival # supposed to be present if it is more than half-present. 2281db6b0a61SColin Percival cut -f 1-3 -d '|' < INDEX-ALL | 2282db6b0a61SColin Percival tr '|' ' ' | 2283db6b0a61SColin Percival while read C S F; do 2284db6b0a61SColin Percival if [ -e ${BASEDIR}/${F} ]; then 2285db6b0a61SColin Percival echo "+ ${C}|${S}" 2286db6b0a61SColin Percival fi 2287db6b0a61SColin Percival echo "= ${C}|${S}" 2288db6b0a61SColin Percival done | 2289db6b0a61SColin Percival sort | 2290db6b0a61SColin Percival uniq -c | 2291db6b0a61SColin Percival sed -E 's,^ +,,' > compfreq 2292db6b0a61SColin Percival grep ' = ' compfreq | 2293db6b0a61SColin Percival cut -f 1,3 -d ' ' | 2294db6b0a61SColin Percival sort -k 2,2 -t ' ' > compfreq.total 2295db6b0a61SColin Percival grep ' + ' compfreq | 2296db6b0a61SColin Percival cut -f 1,3 -d ' ' | 2297db6b0a61SColin Percival sort -k 2,2 -t ' ' > compfreq.present 2298db6b0a61SColin Percival join -t ' ' -1 2 -2 2 compfreq.present compfreq.total | 2299db6b0a61SColin Percival while read S P T; do 2300ae97aa98SEd Maste if [ ${T} -ne 0 -a ${P} -gt `expr ${T} / 2` ]; then 2301db6b0a61SColin Percival echo ${S} 2302db6b0a61SColin Percival fi 2303db6b0a61SColin Percival done > comp.present 2304db6b0a61SColin Percival cut -f 2 -d ' ' < compfreq.total > comp.total 2305db6b0a61SColin Percival rm INDEX-ALL compfreq compfreq.total compfreq.present 2306db6b0a61SColin Percival 2307db6b0a61SColin Percival # We're done making noise. 2308db6b0a61SColin Percival echo "done." 2309db6b0a61SColin Percival 2310db6b0a61SColin Percival # Sometimes the kernel isn't installed where INDEX-ALL 2311db6b0a61SColin Percival # thinks that it should be: In particular, it is often in 2312db6b0a61SColin Percival # /boot/kernel instead of /boot/GENERIC or /boot/SMP. To 2313db6b0a61SColin Percival # deal with this, if "kernel|X" is listed in comp.total 2314db6b0a61SColin Percival # (i.e., is a component which would be upgraded if it is 2315db6b0a61SColin Percival # found to be present) we will add it to comp.present. 2316db6b0a61SColin Percival # If "kernel|<anything>" is in comp.total but "kernel|X" is 2317db6b0a61SColin Percival # not, we print a warning -- the user is running a kernel 2318db6b0a61SColin Percival # which isn't part of the release. 2319db6b0a61SColin Percival KCOMP=`echo ${KERNCONF} | tr 'A-Z' 'a-z'` 2320db6b0a61SColin Percival grep -E "^kernel\|${KCOMP}\$" comp.total >> comp.present 2321db6b0a61SColin Percival 2322db6b0a61SColin Percival if grep -qE "^kernel\|" comp.total && 2323db6b0a61SColin Percival ! grep -qE "^kernel\|${KCOMP}\$" comp.total; then 2324db6b0a61SColin Percival cat <<-EOF 2325db6b0a61SColin Percival 2326db6b0a61SColin PercivalWARNING: This system is running a "${KCOMP}" kernel, which is not a 2327db6b0a61SColin Percivalkernel configuration distributed as part of FreeBSD ${RELNUM}. 2328db6b0a61SColin PercivalThis kernel will not be updated: you MUST update the kernel manually 2329db6b0a61SColin Percivalbefore running "$0 install". 2330db6b0a61SColin Percival EOF 2331db6b0a61SColin Percival fi 2332db6b0a61SColin Percival 2333db6b0a61SColin Percival # Re-sort the list of installed components and generate 2334db6b0a61SColin Percival # the list of non-installed components. 2335db6b0a61SColin Percival sort -u < comp.present > comp.present.tmp 2336db6b0a61SColin Percival mv comp.present.tmp comp.present 2337db6b0a61SColin Percival comm -13 comp.present comp.total > comp.absent 2338db6b0a61SColin Percival 2339db6b0a61SColin Percival # Ask the user to confirm that what we have is correct. To 2340db6b0a61SColin Percival # reduce user confusion, translate "X|Y" back to "X/Y" (as 2341db6b0a61SColin Percival # subcomponents must be listed in the configuration file). 2342db6b0a61SColin Percival echo 2343db6b0a61SColin Percival echo -n "The following components of FreeBSD " 2344db6b0a61SColin Percival echo "seem to be installed:" 2345db6b0a61SColin Percival tr '|' '/' < comp.present | 2346db6b0a61SColin Percival fmt -72 2347db6b0a61SColin Percival echo 2348db6b0a61SColin Percival echo -n "The following components of FreeBSD " 2349db6b0a61SColin Percival echo "do not seem to be installed:" 2350db6b0a61SColin Percival tr '|' '/' < comp.absent | 2351db6b0a61SColin Percival fmt -72 2352db6b0a61SColin Percival echo 2353db6b0a61SColin Percival continuep || return 1 2354db6b0a61SColin Percival echo 2355db6b0a61SColin Percival 2356db6b0a61SColin Percival # Suck the generated list of components into ${COMPONENTS}. 2357db6b0a61SColin Percival # Note that comp.present.tmp is used due to issues with 2358db6b0a61SColin Percival # pipelines and setting variables. 2359db6b0a61SColin Percival COMPONENTS="" 2360db6b0a61SColin Percival tr '|' '/' < comp.present > comp.present.tmp 2361db6b0a61SColin Percival while read C; do 2362db6b0a61SColin Percival COMPONENTS="${COMPONENTS} ${C}" 2363db6b0a61SColin Percival done < comp.present.tmp 2364db6b0a61SColin Percival 2365db6b0a61SColin Percival # Delete temporary files 2366db6b0a61SColin Percival rm comp.present comp.present.tmp comp.absent comp.total 2367db6b0a61SColin Percival fi 2368db6b0a61SColin Percival} 2369db6b0a61SColin Percival 2370db6b0a61SColin Percival# If StrictComponents is not "yes", COMPONENTS contains an entry 2371db6b0a61SColin Percival# corresponding to the currently running kernel, and said kernel 2372db6b0a61SColin Percival# does not exist in the new release, add "kernel/generic" to the 2373db6b0a61SColin Percival# list of components. 2374db6b0a61SColin Percivalupgrade_guess_new_kernel () { 2375db6b0a61SColin Percival if [ "${STRICTCOMPONENTS}" = "no" ]; then 2376db6b0a61SColin Percival # Grab the unfiltered metadata file. 2377db6b0a61SColin Percival METAHASH=`look "$1|" tINDEX.present | cut -f 2 -d '|'` 2378db6b0a61SColin Percival gunzip -c < files/${METAHASH}.gz > $1.all 2379db6b0a61SColin Percival 2380db6b0a61SColin Percival # If "kernel/${KCOMP}" is in ${COMPONENTS} and that component 2381db6b0a61SColin Percival # isn't in $1.all, we need to add kernel/generic. 2382db6b0a61SColin Percival for C in ${COMPONENTS}; do 2383db6b0a61SColin Percival if [ ${C} = "kernel/${KCOMP}" ] && 2384db6b0a61SColin Percival ! grep -qE "^kernel\|${KCOMP}\|" $1.all; then 2385db6b0a61SColin Percival COMPONENTS="${COMPONENTS} kernel/generic" 2386db6b0a61SColin Percival NKERNCONF="GENERIC" 2387db6b0a61SColin Percival cat <<-EOF 2388db6b0a61SColin Percival 2389db6b0a61SColin PercivalWARNING: This system is running a "${KCOMP}" kernel, which is not a 2390db6b0a61SColin Percivalkernel configuration distributed as part of FreeBSD ${RELNUM}. 2391db6b0a61SColin PercivalAs part of upgrading to FreeBSD ${RELNUM}, this kernel will be 2392db6b0a61SColin Percivalreplaced with a "generic" kernel. 2393db6b0a61SColin Percival EOF 2394db6b0a61SColin Percival continuep || return 1 2395db6b0a61SColin Percival fi 2396db6b0a61SColin Percival done 2397db6b0a61SColin Percival 2398db6b0a61SColin Percival # Don't need this any more... 2399db6b0a61SColin Percival rm $1.all 2400db6b0a61SColin Percival fi 2401db6b0a61SColin Percival} 2402db6b0a61SColin Percival 2403db6b0a61SColin Percival# Convert INDEX-OLD (last release) and INDEX-ALL (new release) into 2404db6b0a61SColin Percival# INDEX-OLD and INDEX-NEW files (in the sense of normal upgrades). 2405db6b0a61SColin Percivalupgrade_oldall_to_oldnew () { 2406db6b0a61SColin Percival # For each ${F}|... which appears in INDEX-ALL but does not appear 2407db6b0a61SColin Percival # in INDEX-OLD, add ${F}|-|||||| to INDEX-OLD. 2408db6b0a61SColin Percival cut -f 1 -d '|' < $1 | 2409db6b0a61SColin Percival sort -u > $1.paths 2410db6b0a61SColin Percival cut -f 1 -d '|' < $2 | 2411db6b0a61SColin Percival sort -u | 2412db6b0a61SColin Percival comm -13 $1.paths - | 2413db6b0a61SColin Percival lam - -s "|-||||||" | 2414db6b0a61SColin Percival sort - $1 > $1.tmp 2415db6b0a61SColin Percival mv $1.tmp $1 2416db6b0a61SColin Percival 2417db6b0a61SColin Percival # Remove lines from INDEX-OLD which also appear in INDEX-ALL 2418db6b0a61SColin Percival comm -23 $1 $2 > $1.tmp 2419db6b0a61SColin Percival mv $1.tmp $1 2420db6b0a61SColin Percival 2421db6b0a61SColin Percival # Remove lines from INDEX-ALL which have a file name not appearing 2422db6b0a61SColin Percival # anywhere in INDEX-OLD (since these must be files which haven't 2423db6b0a61SColin Percival # changed -- if they were new, there would be an entry of type "-"). 2424db6b0a61SColin Percival cut -f 1 -d '|' < $1 | 2425db6b0a61SColin Percival sort -u > $1.paths 2426db6b0a61SColin Percival sort -k 1,1 -t '|' < $2 | 2427db6b0a61SColin Percival join -t '|' - $1.paths | 2428db6b0a61SColin Percival sort > $2.tmp 2429db6b0a61SColin Percival rm $1.paths 2430db6b0a61SColin Percival mv $2.tmp $2 2431db6b0a61SColin Percival 2432db6b0a61SColin Percival # Rename INDEX-ALL to INDEX-NEW. 2433db6b0a61SColin Percival mv $2 $3 2434db6b0a61SColin Percival} 2435db6b0a61SColin Percival 24367449d2f5SColin Percival# Helper for upgrade_merge: Return zero true iff the two files differ only 24376d514f10SDag-Erling Smørgrav# in the contents of their RCS tags. 24387449d2f5SColin Percivalsamef () { 24397449d2f5SColin Percival X=`sed -E 's/\\$FreeBSD.*\\$/\$FreeBSD\$/' < $1 | ${SHA256}` 24407449d2f5SColin Percival Y=`sed -E 's/\\$FreeBSD.*\\$/\$FreeBSD\$/' < $2 | ${SHA256}` 24417449d2f5SColin Percival 24427449d2f5SColin Percival if [ $X = $Y ]; then 24437449d2f5SColin Percival return 0; 24447449d2f5SColin Percival else 24457449d2f5SColin Percival return 1; 24467449d2f5SColin Percival fi 24477449d2f5SColin Percival} 24487449d2f5SColin Percival 2449db6b0a61SColin Percival# From the list of "old" files in $1, merge changes in $2 with those in $3, 2450db6b0a61SColin Percival# and update $3 to reflect the hashes of merged files. 2451db6b0a61SColin Percivalupgrade_merge () { 2452db6b0a61SColin Percival # We only need to do anything if $1 is non-empty. 2453db6b0a61SColin Percival if [ -s $1 ]; then 2454db6b0a61SColin Percival cut -f 1 -d '|' $1 | 2455db6b0a61SColin Percival sort > $1-paths 2456db6b0a61SColin Percival 2457db6b0a61SColin Percival # Create staging area for merging files 2458db6b0a61SColin Percival rm -rf merge/ 2459db6b0a61SColin Percival while read F; do 2460db6b0a61SColin Percival D=`dirname ${F}` 2461db6b0a61SColin Percival mkdir -p merge/old/${D} 2462db6b0a61SColin Percival mkdir -p merge/${OLDRELNUM}/${D} 2463db6b0a61SColin Percival mkdir -p merge/${RELNUM}/${D} 2464db6b0a61SColin Percival mkdir -p merge/new/${D} 2465db6b0a61SColin Percival done < $1-paths 2466db6b0a61SColin Percival 2467db6b0a61SColin Percival # Copy in files 2468db6b0a61SColin Percival while read F; do 2469db6b0a61SColin Percival # Currently installed file 2470db6b0a61SColin Percival V=`look "${F}|" $2 | cut -f 7 -d '|'` 2471db6b0a61SColin Percival gunzip < files/${V}.gz > merge/old/${F} 2472db6b0a61SColin Percival 2473db6b0a61SColin Percival # Old release 2474db6b0a61SColin Percival if look "${F}|" $1 | fgrep -q "|f|"; then 2475db6b0a61SColin Percival V=`look "${F}|" $1 | cut -f 3 -d '|'` 2476db6b0a61SColin Percival gunzip < files/${V}.gz \ 2477db6b0a61SColin Percival > merge/${OLDRELNUM}/${F} 2478db6b0a61SColin Percival fi 2479db6b0a61SColin Percival 2480db6b0a61SColin Percival # New release 2481db6b0a61SColin Percival if look "${F}|" $3 | cut -f 1,2,7 -d '|' | 2482db6b0a61SColin Percival fgrep -q "|f|"; then 2483db6b0a61SColin Percival V=`look "${F}|" $3 | cut -f 7 -d '|'` 2484db6b0a61SColin Percival gunzip < files/${V}.gz \ 2485db6b0a61SColin Percival > merge/${RELNUM}/${F} 2486db6b0a61SColin Percival fi 2487db6b0a61SColin Percival done < $1-paths 2488db6b0a61SColin Percival 2489db6b0a61SColin Percival # Attempt to automatically merge changes 2490db6b0a61SColin Percival echo -n "Attempting to automatically merge " 2491db6b0a61SColin Percival echo -n "changes in files..." 2492db6b0a61SColin Percival : > failed.merges 2493db6b0a61SColin Percival while read F; do 2494db6b0a61SColin Percival # If the file doesn't exist in the new release, 2495db6b0a61SColin Percival # the result of "merging changes" is having the file 2496db6b0a61SColin Percival # not exist. 2497db6b0a61SColin Percival if ! [ -f merge/${RELNUM}/${F} ]; then 2498db6b0a61SColin Percival continue 2499db6b0a61SColin Percival fi 2500db6b0a61SColin Percival 2501db6b0a61SColin Percival # If the file didn't exist in the old release, we're 2502db6b0a61SColin Percival # going to throw away the existing file and hope that 2503db6b0a61SColin Percival # the version from the new release is what we want. 2504db6b0a61SColin Percival if ! [ -f merge/${OLDRELNUM}/${F} ]; then 2505db6b0a61SColin Percival cp merge/${RELNUM}/${F} merge/new/${F} 2506db6b0a61SColin Percival continue 2507db6b0a61SColin Percival fi 2508db6b0a61SColin Percival 2509db6b0a61SColin Percival # Some files need special treatment. 2510db6b0a61SColin Percival case ${F} in 2511db6b0a61SColin Percival /etc/spwd.db | /etc/pwd.db | /etc/login.conf.db) 2512db6b0a61SColin Percival # Don't merge these -- we're rebuild them 2513db6b0a61SColin Percival # after updates are installed. 2514db6b0a61SColin Percival cp merge/old/${F} merge/new/${F} 2515db6b0a61SColin Percival ;; 2516db6b0a61SColin Percival *) 2517073dd712SBaptiste Daroussin if ! diff3 -E -m -L "current version" \ 2518db6b0a61SColin Percival -L "${OLDRELNUM}" -L "${RELNUM}" \ 2519db6b0a61SColin Percival merge/old/${F} \ 2520db6b0a61SColin Percival merge/${OLDRELNUM}/${F} \ 2521db6b0a61SColin Percival merge/${RELNUM}/${F} \ 2522db6b0a61SColin Percival > merge/new/${F} 2>/dev/null; then 2523db6b0a61SColin Percival echo ${F} >> failed.merges 2524db6b0a61SColin Percival fi 2525db6b0a61SColin Percival ;; 2526db6b0a61SColin Percival esac 2527db6b0a61SColin Percival done < $1-paths 2528db6b0a61SColin Percival echo " done." 2529db6b0a61SColin Percival 2530db6b0a61SColin Percival # Ask the user to handle any files which didn't merge. 2531db6b0a61SColin Percival while read F; do 25327449d2f5SColin Percival # If the installed file differs from the version in 25336d514f10SDag-Erling Smørgrav # the old release only due to RCS tag expansion 25347449d2f5SColin Percival # then just use the version in the new release. 25357449d2f5SColin Percival if samef merge/old/${F} merge/${OLDRELNUM}/${F}; then 25367449d2f5SColin Percival cp merge/${RELNUM}/${F} merge/new/${F} 25377449d2f5SColin Percival continue 25387449d2f5SColin Percival fi 25397449d2f5SColin Percival 2540db6b0a61SColin Percival cat <<-EOF 2541db6b0a61SColin Percival 2542db6b0a61SColin PercivalThe following file could not be merged automatically: ${F} 2543db6b0a61SColin PercivalPress Enter to edit this file in ${EDITOR} and resolve the conflicts 2544db6b0a61SColin Percivalmanually... 2545db6b0a61SColin Percival EOF 2546ceb5f28bSEd Maste while true; do 2547db6b0a61SColin Percival read dummy </dev/tty 2548db6b0a61SColin Percival ${EDITOR} `pwd`/merge/new/${F} < /dev/tty 2549ceb5f28bSEd Maste 2550*e27ded83SEd Maste if ! grep -qE '^(<<<<<<<|=======|>>>>>>>)([[:space:]].*)?$' $(pwd)/merge/new/${F} ; then 2551ceb5f28bSEd Maste break 2552ceb5f28bSEd Maste fi 2553ceb5f28bSEd Maste cat <<-EOF 2554ceb5f28bSEd Maste 2555ceb5f28bSEd MasteMerge conflict markers remain in: ${F} 2556ceb5f28bSEd MasteThese must be resolved for the system to be functional. 2557ceb5f28bSEd Maste 2558ceb5f28bSEd MastePress Enter to return to editing this file. 2559ceb5f28bSEd Maste EOF 2560ceb5f28bSEd Maste done 2561db6b0a61SColin Percival done < failed.merges 2562db6b0a61SColin Percival rm failed.merges 2563db6b0a61SColin Percival 2564db6b0a61SColin Percival # Ask the user to confirm that he likes how the result 2565db6b0a61SColin Percival # of merging files. 2566db6b0a61SColin Percival while read F; do 25677449d2f5SColin Percival # Skip files which haven't changed except possibly 25686d514f10SDag-Erling Smørgrav # in their RCS tags. 25697449d2f5SColin Percival if [ -f merge/old/${F} ] && [ -f merge/new/${F} ] && 25707449d2f5SColin Percival samef merge/old/${F} merge/new/${F}; then 25717449d2f5SColin Percival continue 25727449d2f5SColin Percival fi 25737449d2f5SColin Percival 25747449d2f5SColin Percival # Skip files where the installed file differs from 25756d514f10SDag-Erling Smørgrav # the old file only due to RCS tags. 25767449d2f5SColin Percival if [ -f merge/old/${F} ] && 25777449d2f5SColin Percival [ -f merge/${OLDRELNUM}/${F} ] && 25787449d2f5SColin Percival samef merge/old/${F} merge/${OLDRELNUM}/${F}; then 2579db6b0a61SColin Percival continue 2580db6b0a61SColin Percival fi 2581db6b0a61SColin Percival 2582db6b0a61SColin Percival # Warn about files which are ceasing to exist. 2583db6b0a61SColin Percival if ! [ -f merge/new/${F} ]; then 2584db6b0a61SColin Percival cat <<-EOF 2585db6b0a61SColin Percival 2586db6b0a61SColin PercivalThe following file will be removed, as it no longer exists in 2587db6b0a61SColin PercivalFreeBSD ${RELNUM}: ${F} 2588db6b0a61SColin Percival EOF 2589db6b0a61SColin Percival continuep < /dev/tty || return 1 2590db6b0a61SColin Percival continue 2591db6b0a61SColin Percival fi 2592db6b0a61SColin Percival 2593db6b0a61SColin Percival # Print changes for the user's approval. 2594db6b0a61SColin Percival cat <<-EOF 2595db6b0a61SColin Percival 2596db6b0a61SColin PercivalThe following changes, which occurred between FreeBSD ${OLDRELNUM} and 2597db6b0a61SColin PercivalFreeBSD ${RELNUM} have been merged into ${F}: 2598db6b0a61SColin PercivalEOF 2599db6b0a61SColin Percival diff -U 5 -L "current version" -L "new version" \ 2600db6b0a61SColin Percival merge/old/${F} merge/new/${F} || true 2601db6b0a61SColin Percival continuep < /dev/tty || return 1 2602db6b0a61SColin Percival done < $1-paths 2603db6b0a61SColin Percival 2604db6b0a61SColin Percival # Store merged files. 2605db6b0a61SColin Percival while read F; do 2606c58b62efSColin Percival if [ -f merge/new/${F} ]; then 2607db6b0a61SColin Percival V=`${SHA256} -q merge/new/${F}` 2608db6b0a61SColin Percival 2609db6b0a61SColin Percival gzip -c < merge/new/${F} > files/${V}.gz 2610db6b0a61SColin Percival echo "${F}|${V}" 2611db6b0a61SColin Percival fi 2612db6b0a61SColin Percival done < $1-paths > newhashes 2613db6b0a61SColin Percival 2614db6b0a61SColin Percival # Pull lines out from $3 which need to be updated to 2615db6b0a61SColin Percival # reflect merged files. 2616db6b0a61SColin Percival while read F; do 2617db6b0a61SColin Percival look "${F}|" $3 2618db6b0a61SColin Percival done < $1-paths > $3-oldlines 2619db6b0a61SColin Percival 2620db6b0a61SColin Percival # Update lines to reflect merged files 2621db6b0a61SColin Percival join -t '|' -o 1.1,1.2,1.3,1.4,1.5,1.6,2.2,1.8 \ 2622db6b0a61SColin Percival $3-oldlines newhashes > $3-newlines 2623db6b0a61SColin Percival 2624db6b0a61SColin Percival # Remove old lines from $3 and add new lines. 2625db6b0a61SColin Percival sort $3-oldlines | 2626db6b0a61SColin Percival comm -13 - $3 | 2627db6b0a61SColin Percival sort - $3-newlines > $3.tmp 2628db6b0a61SColin Percival mv $3.tmp $3 2629db6b0a61SColin Percival 2630db6b0a61SColin Percival # Clean up 2631db6b0a61SColin Percival rm $1-paths newhashes $3-oldlines $3-newlines 2632db6b0a61SColin Percival rm -rf merge/ 2633db6b0a61SColin Percival fi 2634db6b0a61SColin Percival 2635db6b0a61SColin Percival # We're done with merging files. 2636db6b0a61SColin Percival rm $1 2637db6b0a61SColin Percival} 2638db6b0a61SColin Percival 2639db6b0a61SColin Percival# Do the work involved in fetching upgrades to a new release 2640db6b0a61SColin Percivalupgrade_run () { 2641db6b0a61SColin Percival workdir_init || return 1 2642db6b0a61SColin Percival 2643db6b0a61SColin Percival # Prepare the mirror list. 2644db6b0a61SColin Percival fetch_pick_server_init && fetch_pick_server 2645db6b0a61SColin Percival 2646db6b0a61SColin Percival # Try to fetch the public key until we run out of servers. 2647db6b0a61SColin Percival while ! fetch_key; do 2648db6b0a61SColin Percival fetch_pick_server || return 1 2649db6b0a61SColin Percival done 2650db6b0a61SColin Percival 2651db6b0a61SColin Percival # Try to fetch the metadata index signature ("tag") until we run 2652db6b0a61SColin Percival # out of available servers; and sanity check the downloaded tag. 2653db6b0a61SColin Percival while ! fetch_tag; do 2654db6b0a61SColin Percival fetch_pick_server || return 1 2655db6b0a61SColin Percival done 2656db6b0a61SColin Percival fetch_tagsanity || return 1 2657db6b0a61SColin Percival 2658db6b0a61SColin Percival # Fetch the INDEX-OLD and INDEX-ALL. 2659db6b0a61SColin Percival fetch_metadata INDEX-OLD INDEX-ALL || return 1 2660db6b0a61SColin Percival 2661db6b0a61SColin Percival # If StrictComponents is not "yes", generate a new components list 2662db6b0a61SColin Percival # with only the components which appear to be installed. 2663db6b0a61SColin Percival upgrade_guess_components INDEX-ALL || return 1 2664db6b0a61SColin Percival 2665db6b0a61SColin Percival # Generate filtered INDEX-OLD and INDEX-ALL files containing only 2666db6b0a61SColin Percival # the components we want and without anything marked as "Ignore". 2667db6b0a61SColin Percival fetch_filter_metadata INDEX-OLD || return 1 2668db6b0a61SColin Percival fetch_filter_metadata INDEX-ALL || return 1 2669db6b0a61SColin Percival 2670db6b0a61SColin Percival # Merge the INDEX-OLD and INDEX-ALL files into INDEX-OLD. 2671db6b0a61SColin Percival sort INDEX-OLD INDEX-ALL > INDEX-OLD.tmp 2672db6b0a61SColin Percival mv INDEX-OLD.tmp INDEX-OLD 2673db6b0a61SColin Percival rm INDEX-ALL 2674db6b0a61SColin Percival 2675db6b0a61SColin Percival # Adjust variables for fetching files from the new release. 2676db6b0a61SColin Percival OLDRELNUM=${RELNUM} 2677db6b0a61SColin Percival RELNUM=${TARGETRELEASE} 2678db6b0a61SColin Percival OLDFETCHDIR=${FETCHDIR} 2679db6b0a61SColin Percival FETCHDIR=${RELNUM}/${ARCH} 2680db6b0a61SColin Percival 2681db6b0a61SColin Percival # Try to fetch the NEW metadata index signature ("tag") until we run 2682db6b0a61SColin Percival # out of available servers; and sanity check the downloaded tag. 2683db6b0a61SColin Percival while ! fetch_tag; do 2684db6b0a61SColin Percival fetch_pick_server || return 1 2685db6b0a61SColin Percival done 2686db6b0a61SColin Percival 2687db6b0a61SColin Percival # Fetch the new INDEX-ALL. 2688db6b0a61SColin Percival fetch_metadata INDEX-ALL || return 1 2689db6b0a61SColin Percival 2690db6b0a61SColin Percival # If StrictComponents is not "yes", COMPONENTS contains an entry 2691db6b0a61SColin Percival # corresponding to the currently running kernel, and said kernel 2692db6b0a61SColin Percival # does not exist in the new release, add "kernel/generic" to the 2693db6b0a61SColin Percival # list of components. 2694db6b0a61SColin Percival upgrade_guess_new_kernel INDEX-ALL || return 1 2695db6b0a61SColin Percival 2696db6b0a61SColin Percival # Filter INDEX-ALL to contain only the components we want and without 2697db6b0a61SColin Percival # anything marked as "Ignore". 2698db6b0a61SColin Percival fetch_filter_metadata INDEX-ALL || return 1 2699db6b0a61SColin Percival 2700db6b0a61SColin Percival # Convert INDEX-OLD (last release) and INDEX-ALL (new release) into 2701db6b0a61SColin Percival # INDEX-OLD and INDEX-NEW files (in the sense of normal upgrades). 2702db6b0a61SColin Percival upgrade_oldall_to_oldnew INDEX-OLD INDEX-ALL INDEX-NEW 2703db6b0a61SColin Percival 2704db6b0a61SColin Percival # Translate /boot/${KERNCONF} or /boot/${NKERNCONF} into ${KERNELDIR} 2705db6b0a61SColin Percival fetch_filter_kernel_names INDEX-NEW ${NKERNCONF} 2706db6b0a61SColin Percival fetch_filter_kernel_names INDEX-OLD ${KERNCONF} 2707db6b0a61SColin Percival 2708db6b0a61SColin Percival # For all paths appearing in INDEX-OLD or INDEX-NEW, inspect the 2709db6b0a61SColin Percival # system and generate an INDEX-PRESENT file. 2710db6b0a61SColin Percival fetch_inspect_system INDEX-OLD INDEX-PRESENT INDEX-NEW || return 1 2711db6b0a61SColin Percival 2712db6b0a61SColin Percival # Based on ${MERGECHANGES}, generate a file tomerge-old with the 2713db6b0a61SColin Percival # paths and hashes of old versions of files to merge. 2714db6b0a61SColin Percival fetch_filter_mergechanges INDEX-OLD INDEX-PRESENT tomerge-old 2715db6b0a61SColin Percival 2716db6b0a61SColin Percival # Based on ${UPDATEIFUNMODIFIED}, remove lines from INDEX-* which 2717db6b0a61SColin Percival # correspond to lines in INDEX-PRESENT with hashes not appearing 2718db6b0a61SColin Percival # in INDEX-OLD or INDEX-NEW. Also remove lines where the entry in 2719db6b0a61SColin Percival # INDEX-PRESENT has type - and there isn't a corresponding entry in 2720db6b0a61SColin Percival # INDEX-OLD with type -. 2721db6b0a61SColin Percival fetch_filter_unmodified_notpresent \ 2722db6b0a61SColin Percival INDEX-OLD INDEX-PRESENT INDEX-NEW tomerge-old 2723db6b0a61SColin Percival 2724db6b0a61SColin Percival # For each entry in INDEX-PRESENT of type -, remove any corresponding 2725db6b0a61SColin Percival # entry from INDEX-NEW if ${ALLOWADD} != "yes". Remove all entries 2726db6b0a61SColin Percival # of type - from INDEX-PRESENT. 2727db6b0a61SColin Percival fetch_filter_allowadd INDEX-PRESENT INDEX-NEW 2728db6b0a61SColin Percival 2729db6b0a61SColin Percival # If ${ALLOWDELETE} != "yes", then remove any entries from 2730db6b0a61SColin Percival # INDEX-PRESENT which don't correspond to entries in INDEX-NEW. 2731db6b0a61SColin Percival fetch_filter_allowdelete INDEX-PRESENT INDEX-NEW 2732db6b0a61SColin Percival 2733db6b0a61SColin Percival # If ${KEEPMODIFIEDMETADATA} == "yes", then for each entry in 2734db6b0a61SColin Percival # INDEX-PRESENT with metadata not matching any entry in INDEX-OLD, 2735db6b0a61SColin Percival # replace the corresponding line of INDEX-NEW with one having the 2736db6b0a61SColin Percival # same metadata as the entry in INDEX-PRESENT. 2737db6b0a61SColin Percival fetch_filter_modified_metadata INDEX-OLD INDEX-PRESENT INDEX-NEW 2738db6b0a61SColin Percival 2739db6b0a61SColin Percival # Remove lines from INDEX-PRESENT and INDEX-NEW which are identical; 2740db6b0a61SColin Percival # no need to update a file if it isn't changing. 2741db6b0a61SColin Percival fetch_filter_uptodate INDEX-PRESENT INDEX-NEW 2742db6b0a61SColin Percival 2743db6b0a61SColin Percival # Fetch "clean" files from the old release for merging changes. 2744db6b0a61SColin Percival fetch_files_premerge tomerge-old 2745db6b0a61SColin Percival 2746db6b0a61SColin Percival # Prepare to fetch files: Generate a list of the files we need, 2747db6b0a61SColin Percival # copy the unmodified files we have into /files/, and generate 2748db6b0a61SColin Percival # a list of patches to download. 2749db6b0a61SColin Percival fetch_files_prepare INDEX-OLD INDEX-PRESENT INDEX-NEW || return 1 2750db6b0a61SColin Percival 2751db6b0a61SColin Percival # Fetch patches from to-${RELNUM}/${ARCH}/bp/ 2752db6b0a61SColin Percival PATCHDIR=to-${RELNUM}/${ARCH}/bp 2753db6b0a61SColin Percival fetch_files || return 1 2754db6b0a61SColin Percival 2755db6b0a61SColin Percival # Merge configuration file changes. 2756db6b0a61SColin Percival upgrade_merge tomerge-old INDEX-PRESENT INDEX-NEW || return 1 2757db6b0a61SColin Percival 2758db6b0a61SColin Percival # Create and populate install manifest directory; and report what 2759db6b0a61SColin Percival # updates are available. 2760db6b0a61SColin Percival fetch_create_manifest || return 1 2761db6b0a61SColin Percival 2762db6b0a61SColin Percival # Leave a note behind to tell the "install" command that the kernel 2763db6b0a61SColin Percival # needs to be installed before the world. 2764db6b0a61SColin Percival touch ${BDHASH}-install/kernelfirst 276585451f90SColin Percival 276685451f90SColin Percival # Remind the user that they need to run "freebsd-update install" 276785451f90SColin Percival # to install the downloaded bits, in case they didn't RTFM. 276885451f90SColin Percival echo "To install the downloaded upgrades, run \"$0 install\"." 2769db6b0a61SColin Percival} 2770db6b0a61SColin Percival 277148ffe56aSColin Percival# Make sure that all the file hashes mentioned in $@ have corresponding 277248ffe56aSColin Percival# gzipped files stored in /files/. 277348ffe56aSColin Percivalinstall_verify () { 277448ffe56aSColin Percival # Generate a list of hashes 277548ffe56aSColin Percival cat $@ | 277648ffe56aSColin Percival cut -f 2,7 -d '|' | 277748ffe56aSColin Percival grep -E '^f' | 277848ffe56aSColin Percival cut -f 2 -d '|' | 277948ffe56aSColin Percival sort -u > filelist 278048ffe56aSColin Percival 278148ffe56aSColin Percival # Make sure all the hashes exist 278248ffe56aSColin Percival while read HASH; do 278348ffe56aSColin Percival if ! [ -f files/${HASH}.gz ]; then 278448ffe56aSColin Percival echo -n "Update files missing -- " 278548ffe56aSColin Percival echo "this should never happen." 278648ffe56aSColin Percival echo "Re-run '$0 fetch'." 278748ffe56aSColin Percival return 1 278848ffe56aSColin Percival fi 278948ffe56aSColin Percival done < filelist 279048ffe56aSColin Percival 279148ffe56aSColin Percival # Clean up 279248ffe56aSColin Percival rm filelist 279348ffe56aSColin Percival} 279448ffe56aSColin Percival 279548ffe56aSColin Percival# Remove the system immutable flag from files 279648ffe56aSColin Percivalinstall_unschg () { 279748ffe56aSColin Percival # Generate file list 279848ffe56aSColin Percival cat $@ | 279948ffe56aSColin Percival cut -f 1 -d '|' > filelist 280048ffe56aSColin Percival 280148ffe56aSColin Percival # Remove flags 280248ffe56aSColin Percival while read F; do 2803e829ed67SColin Percival if ! [ -e ${BASEDIR}/${F} ]; then 280448ffe56aSColin Percival continue 28055a74378cSXin LI else 28065a74378cSXin LI echo ${BASEDIR}/${F} 280748ffe56aSColin Percival fi 28085a74378cSXin LI done < filelist | xargs chflags noschg || return 1 280948ffe56aSColin Percival 281048ffe56aSColin Percival # Clean up 281148ffe56aSColin Percival rm filelist 281248ffe56aSColin Percival} 281348ffe56aSColin Percival 281423d827efSSimon L. B. Nielsen# Decide which directory name to use for kernel backups. 281523d827efSSimon L. B. Nielsenbackup_kernel_finddir () { 281623d827efSSimon L. B. Nielsen CNT=0 281723d827efSSimon L. B. Nielsen while true ; do 281823d827efSSimon L. B. Nielsen # Pathname does not exist, so it is OK use that name 281923d827efSSimon L. B. Nielsen # for backup directory. 2820c4a0c62cSThomas Quinot if [ ! -e $BASEDIR/$BACKUPKERNELDIR ]; then 282123d827efSSimon L. B. Nielsen return 0 282223d827efSSimon L. B. Nielsen fi 282323d827efSSimon L. B. Nielsen 282423d827efSSimon L. B. Nielsen # If directory do exist, we only use if it has our 282523d827efSSimon L. B. Nielsen # marker file. 2826c4a0c62cSThomas Quinot if [ -d $BASEDIR/$BACKUPKERNELDIR -a \ 2827c4a0c62cSThomas Quinot -e $BASEDIR/$BACKUPKERNELDIR/.freebsd-update ]; then 282823d827efSSimon L. B. Nielsen return 0 282923d827efSSimon L. B. Nielsen fi 283023d827efSSimon L. B. Nielsen 283123d827efSSimon L. B. Nielsen # We could not use current directory name, so add counter to 283223d827efSSimon L. B. Nielsen # the end and try again. 283323d827efSSimon L. B. Nielsen CNT=$((CNT + 1)) 283423d827efSSimon L. B. Nielsen if [ $CNT -gt 9 ]; then 2835c4a0c62cSThomas Quinot echo "Could not find valid backup dir ($BASEDIR/$BACKUPKERNELDIR)" 283623d827efSSimon L. B. Nielsen exit 1 283723d827efSSimon L. B. Nielsen fi 283823d827efSSimon L. B. Nielsen BACKUPKERNELDIR="`echo $BACKUPKERNELDIR | sed -Ee 's/[0-9]\$//'`" 283923d827efSSimon L. B. Nielsen BACKUPKERNELDIR="${BACKUPKERNELDIR}${CNT}" 284023d827efSSimon L. B. Nielsen done 284123d827efSSimon L. B. Nielsen} 284223d827efSSimon L. B. Nielsen 284323d827efSSimon L. B. Nielsen# Backup the current kernel using hardlinks, if not disabled by user. 284423d827efSSimon L. B. Nielsen# Since we delete all files in the directory used for previous backups 284523d827efSSimon L. B. Nielsen# we create a marker file called ".freebsd-update" in the directory so 284623d827efSSimon L. B. Nielsen# we can determine on the next run that the directory was created by 284723d827efSSimon L. B. Nielsen# freebsd-update and we then do not accidentally remove user files in 284823d827efSSimon L. B. Nielsen# the unlikely case that the user has created a directory with a 284923d827efSSimon L. B. Nielsen# conflicting name. 285023d827efSSimon L. B. Nielsenbackup_kernel () { 285123d827efSSimon L. B. Nielsen # Only make kernel backup is so configured. 285223d827efSSimon L. B. Nielsen if [ $BACKUPKERNEL != yes ]; then 285323d827efSSimon L. B. Nielsen return 0 285423d827efSSimon L. B. Nielsen fi 285523d827efSSimon L. B. Nielsen 285623d827efSSimon L. B. Nielsen # Decide which directory name to use for kernel backups. 285723d827efSSimon L. B. Nielsen backup_kernel_finddir 285823d827efSSimon L. B. Nielsen 285923d827efSSimon L. B. Nielsen # Remove old kernel backup files. If $BACKUPKERNELDIR was 286023d827efSSimon L. B. Nielsen # "not ours", backup_kernel_finddir would have exited, so 286123d827efSSimon L. B. Nielsen # deleting the directory content is as safe as we can make it. 2862c4a0c62cSThomas Quinot if [ -d $BASEDIR/$BACKUPKERNELDIR ]; then 2863c4a0c62cSThomas Quinot rm -fr $BASEDIR/$BACKUPKERNELDIR 286423d827efSSimon L. B. Nielsen fi 286523d827efSSimon L. B. Nielsen 2866ab7d0151SJaakko Heinonen # Create directories for backup. 2867c4a0c62cSThomas Quinot mkdir -p $BASEDIR/$BACKUPKERNELDIR 2868c4a0c62cSThomas Quinot mtree -cdn -p "${BASEDIR}/${KERNELDIR}" | \ 2869c4a0c62cSThomas Quinot mtree -Ue -p "${BASEDIR}/${BACKUPKERNELDIR}" > /dev/null 287023d827efSSimon L. B. Nielsen 287123d827efSSimon L. B. Nielsen # Mark the directory as having been created by freebsd-update. 2872c4a0c62cSThomas Quinot touch $BASEDIR/$BACKUPKERNELDIR/.freebsd-update 287323d827efSSimon L. B. Nielsen if [ $? -ne 0 ]; then 287423d827efSSimon L. B. Nielsen echo "Could not create kernel backup directory" 287523d827efSSimon L. B. Nielsen exit 1 287623d827efSSimon L. B. Nielsen fi 287723d827efSSimon L. B. Nielsen 287823d827efSSimon L. B. Nielsen # Disable pathname expansion to be sure *.symbols is not 287923d827efSSimon L. B. Nielsen # expanded. 288023d827efSSimon L. B. Nielsen set -f 288123d827efSSimon L. B. Nielsen 288223d827efSSimon L. B. Nielsen # Use find to ignore symbol files, unless disabled by user. 288323d827efSSimon L. B. Nielsen if [ $BACKUPKERNELSYMBOLFILES = yes ]; then 288423d827efSSimon L. B. Nielsen FINDFILTER="" 288523d827efSSimon L. B. Nielsen else 28867e1ed2c7SEd Maste FINDFILTER="-a ! -name *.debug -a ! -name *.symbols" 288723d827efSSimon L. B. Nielsen fi 288823d827efSSimon L. B. Nielsen 288923d827efSSimon L. B. Nielsen # Backup all the kernel files using hardlinks. 2890c4a0c62cSThomas Quinot (cd ${BASEDIR}/${KERNELDIR} && find . -type f $FINDFILTER -exec \ 2891c4a0c62cSThomas Quinot cp -pl '{}' ${BASEDIR}/${BACKUPKERNELDIR}/'{}' \;) 289223d827efSSimon L. B. Nielsen 289323d827efSSimon L. B. Nielsen # Re-enable patchname expansion. 289423d827efSSimon L. B. Nielsen set +f 289523d827efSSimon L. B. Nielsen} 289623d827efSSimon L. B. Nielsen 289748ffe56aSColin Percival# Install new files 289848ffe56aSColin Percivalinstall_from_index () { 289948ffe56aSColin Percival # First pass: Do everything apart from setting file flags. We 290048ffe56aSColin Percival # can't set flags yet, because schg inhibits hard linking. 290148ffe56aSColin Percival sort -k 1,1 -t '|' $1 | 290248ffe56aSColin Percival tr '|' ' ' | 290348ffe56aSColin Percival while read FPATH TYPE OWNER GROUP PERM FLAGS HASH LINK; do 290448ffe56aSColin Percival case ${TYPE} in 290548ffe56aSColin Percival d) 290648ffe56aSColin Percival # Create a directory 290748ffe56aSColin Percival install -d -o ${OWNER} -g ${GROUP} \ 290848ffe56aSColin Percival -m ${PERM} ${BASEDIR}/${FPATH} 290948ffe56aSColin Percival ;; 291048ffe56aSColin Percival f) 291148ffe56aSColin Percival if [ -z "${LINK}" ]; then 291248ffe56aSColin Percival # Create a file, without setting flags. 291348ffe56aSColin Percival gunzip < files/${HASH}.gz > ${HASH} 291448ffe56aSColin Percival install -S -o ${OWNER} -g ${GROUP} \ 291548ffe56aSColin Percival -m ${PERM} ${HASH} ${BASEDIR}/${FPATH} 291648ffe56aSColin Percival rm ${HASH} 291748ffe56aSColin Percival else 291848ffe56aSColin Percival # Create a hard link. 2919e829ed67SColin Percival ln -f ${BASEDIR}/${LINK} ${BASEDIR}/${FPATH} 292048ffe56aSColin Percival fi 292148ffe56aSColin Percival ;; 292248ffe56aSColin Percival L) 292348ffe56aSColin Percival # Create a symlink 292448ffe56aSColin Percival ln -sfh ${HASH} ${BASEDIR}/${FPATH} 292548ffe56aSColin Percival ;; 292648ffe56aSColin Percival esac 292748ffe56aSColin Percival done 292848ffe56aSColin Percival 292948ffe56aSColin Percival # Perform a second pass, adding file flags. 293048ffe56aSColin Percival tr '|' ' ' < $1 | 293148ffe56aSColin Percival while read FPATH TYPE OWNER GROUP PERM FLAGS HASH LINK; do 293248ffe56aSColin Percival if [ ${TYPE} = "f" ] && 293348ffe56aSColin Percival ! [ ${FLAGS} = "0" ]; then 293448ffe56aSColin Percival chflags ${FLAGS} ${BASEDIR}/${FPATH} 293548ffe56aSColin Percival fi 293648ffe56aSColin Percival done 293748ffe56aSColin Percival} 293848ffe56aSColin Percival 293948ffe56aSColin Percival# Remove files which we want to delete 294048ffe56aSColin Percivalinstall_delete () { 294148ffe56aSColin Percival # Generate list of new files 294248ffe56aSColin Percival cut -f 1 -d '|' < $2 | 294348ffe56aSColin Percival sort > newfiles 294448ffe56aSColin Percival 294548ffe56aSColin Percival # Generate subindex of old files we want to nuke 294648ffe56aSColin Percival sort -k 1,1 -t '|' $1 | 294748ffe56aSColin Percival join -t '|' -v 1 - newfiles | 2948bce02f98SColin Percival sort -r -k 1,1 -t '|' | 294948ffe56aSColin Percival cut -f 1,2 -d '|' | 295048ffe56aSColin Percival tr '|' ' ' > killfiles 295148ffe56aSColin Percival 295248ffe56aSColin Percival # Remove the offending bits 295348ffe56aSColin Percival while read FPATH TYPE; do 295448ffe56aSColin Percival case ${TYPE} in 295548ffe56aSColin Percival d) 295648ffe56aSColin Percival rmdir ${BASEDIR}/${FPATH} 295748ffe56aSColin Percival ;; 295848ffe56aSColin Percival f) 295948ffe56aSColin Percival rm ${BASEDIR}/${FPATH} 296048ffe56aSColin Percival ;; 296148ffe56aSColin Percival L) 296248ffe56aSColin Percival rm ${BASEDIR}/${FPATH} 296348ffe56aSColin Percival ;; 296448ffe56aSColin Percival esac 296548ffe56aSColin Percival done < killfiles 296648ffe56aSColin Percival 296748ffe56aSColin Percival # Clean up 296848ffe56aSColin Percival rm newfiles killfiles 296948ffe56aSColin Percival} 297048ffe56aSColin Percival 29712b17527cSKyle Evans# Install new files, delete old files, and update generated files 2972db6b0a61SColin Percivalinstall_files () { 2973db6b0a61SColin Percival # If we haven't already dealt with the kernel, deal with it. 2974db6b0a61SColin Percival if ! [ -f $1/kerneldone ]; then 2975db6b0a61SColin Percival grep -E '^/boot/' $1/INDEX-OLD > INDEX-OLD 2976db6b0a61SColin Percival grep -E '^/boot/' $1/INDEX-NEW > INDEX-NEW 2977db6b0a61SColin Percival 297823d827efSSimon L. B. Nielsen # Backup current kernel before installing a new one 297923d827efSSimon L. B. Nielsen backup_kernel || return 1 298023d827efSSimon L. B. Nielsen 2981db6b0a61SColin Percival # Install new files 2982db6b0a61SColin Percival install_from_index INDEX-NEW || return 1 2983db6b0a61SColin Percival 2984db6b0a61SColin Percival # Remove files which need to be deleted 2985db6b0a61SColin Percival install_delete INDEX-OLD INDEX-NEW || return 1 2986db6b0a61SColin Percival 2987db6b0a61SColin Percival # Update linker.hints if necessary 2988db6b0a61SColin Percival if [ -s INDEX-OLD -o -s INDEX-NEW ]; then 2989c4a0c62cSThomas Quinot kldxref -R ${BASEDIR}/boot/ 2>/dev/null 299048ffe56aSColin Percival fi 2991db6b0a61SColin Percival 2992db6b0a61SColin Percival # We've finished updating the kernel. 2993db6b0a61SColin Percival touch $1/kerneldone 2994db6b0a61SColin Percival 2995db6b0a61SColin Percival # Do we need to ask for a reboot now? 2996db6b0a61SColin Percival if [ -f $1/kernelfirst ] && 2997db6b0a61SColin Percival [ -s INDEX-OLD -o -s INDEX-NEW ]; then 2998db6b0a61SColin Percival cat <<-EOF 2999db6b0a61SColin Percival 3000db6b0a61SColin PercivalKernel updates have been installed. Please reboot and run 3001db6b0a61SColin Percival"$0 install" again to finish installing updates. 3002db6b0a61SColin Percival EOF 3003db6b0a61SColin Percival exit 0 3004db6b0a61SColin Percival fi 3005db6b0a61SColin Percival fi 3006db6b0a61SColin Percival 3007db6b0a61SColin Percival # If we haven't already dealt with the world, deal with it. 3008db6b0a61SColin Percival if ! [ -f $1/worlddone ]; then 3009cd1ab228SColin Percival # Create any necessary directories first 3010cd1ab228SColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3011cd1ab228SColin Percival grep -E '^[^|]+\|d\|' > INDEX-NEW 3012cd1ab228SColin Percival install_from_index INDEX-NEW || return 1 3013cd1ab228SColin Percival 3014722d81b5SBrooks Davis # Install new runtime linker 3015722d81b5SBrooks Davis grep -vE '^/boot/' $1/INDEX-NEW | 3016722d81b5SBrooks Davis grep -vE '^[^|]+\|d\|' | 3017722d81b5SBrooks Davis grep -E '^/libexec/ld-elf[^|]*\.so\.[0-9]+\|' > INDEX-NEW 3018722d81b5SBrooks Davis install_from_index INDEX-NEW || return 1 3019722d81b5SBrooks Davis 3020db6b0a61SColin Percival # Install new shared libraries next 3021db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3022cd1ab228SColin Percival grep -vE '^[^|]+\|d\|' | 3023722d81b5SBrooks Davis grep -vE '^/libexec/ld-elf[^|]*\.so\.[0-9]+\|' | 30249546dbd1SColin Percival grep -E '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' > INDEX-NEW 3025db6b0a61SColin Percival install_from_index INDEX-NEW || return 1 3026db6b0a61SColin Percival 3027db6b0a61SColin Percival # Deal with everything else 3028db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-OLD | 3029cd1ab228SColin Percival grep -vE '^[^|]+\|d\|' | 3030722d81b5SBrooks Davis grep -vE '^/libexec/ld-elf[^|]*\.so\.[0-9]+\|' | 30319546dbd1SColin Percival grep -vE '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' > INDEX-OLD 3032db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3033cd1ab228SColin Percival grep -vE '^[^|]+\|d\|' | 3034722d81b5SBrooks Davis grep -vE '^/libexec/ld-elf[^|]*\.so\.[0-9]+\|' | 30359546dbd1SColin Percival grep -vE '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' > INDEX-NEW 3036db6b0a61SColin Percival install_from_index INDEX-NEW || return 1 3037db6b0a61SColin Percival install_delete INDEX-OLD INDEX-NEW || return 1 3038db6b0a61SColin Percival 30396cd1bc53SEd Maste # Restart sshd if running (PR263489). Note that this does not 30406cd1bc53SEd Maste # affect child sshd processes handling existing sessions. 30416cd1bc53SEd Maste if service sshd status >/dev/null 2>/dev/null; then 30426cd1bc53SEd Maste echo 30436cd1bc53SEd Maste echo "Restarting sshd after upgrade" 30446cd1bc53SEd Maste service sshd restart 30456cd1bc53SEd Maste fi 30466cd1bc53SEd Maste 30472b17527cSKyle Evans # Rehash certs if we actually have certctl installed. 30482b17527cSKyle Evans if which certctl>/dev/null; then 30492b17527cSKyle Evans env DESTDIR=${BASEDIR} certctl rehash 30502b17527cSKyle Evans fi 30512b17527cSKyle Evans 3052ebebc41eSKyle Evans # Rebuild generated pwd files and /etc/login.conf.db. 30539b659110SEd Maste pwd_mkdb -d ${BASEDIR}/etc -p ${BASEDIR}/etc/master.passwd 3054c4a0c62cSThomas Quinot cap_mkdb ${BASEDIR}/etc/login.conf 3055db6b0a61SColin Percival 30569c812c8dSEd Maste # Rebuild man page databases, if necessary. 30579c812c8dSEd Maste for D in /usr/share/man /usr/share/openssl/man; do 30589c812c8dSEd Maste if [ ! -d ${BASEDIR}/$D ]; then 30599c812c8dSEd Maste continue 30609c812c8dSEd Maste fi 3061741223a6SEd Maste if [ -f ${BASEDIR}/$D/mandoc.db ] && \ 3062741223a6SEd Maste [ -z "$(find ${BASEDIR}/$D -type f -newer ${BASEDIR}/$D/mandoc.db)" ]; then 30639c812c8dSEd Maste continue; 30649c812c8dSEd Maste fi 30659c812c8dSEd Maste makewhatis ${BASEDIR}/$D 30669c812c8dSEd Maste done 30679c812c8dSEd Maste 3068db6b0a61SColin Percival # We've finished installing the world and deleting old files 3069db6b0a61SColin Percival # which are not shared libraries. 3070db6b0a61SColin Percival touch $1/worlddone 3071db6b0a61SColin Percival 3072db6b0a61SColin Percival # Do we need to ask the user to portupgrade now? 3073db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 30749546dbd1SColin Percival grep -E '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' | 3075db6b0a61SColin Percival cut -f 1 -d '|' | 3076db6b0a61SColin Percival sort > newfiles 3077db6b0a61SColin Percival if grep -vE '^/boot/' $1/INDEX-OLD | 30789546dbd1SColin Percival grep -E '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' | 3079db6b0a61SColin Percival cut -f 1 -d '|' | 3080db6b0a61SColin Percival sort | 3081db6b0a61SColin Percival join -v 1 - newfiles | 3082db6b0a61SColin Percival grep -q .; then 3083db6b0a61SColin Percival cat <<-EOF 3084db6b0a61SColin Percival 3085db6b0a61SColin PercivalCompleting this upgrade requires removing old shared object files. 3086db6b0a61SColin PercivalPlease rebuild all installed 3rd party software (e.g., programs 3087db6b0a61SColin Percivalinstalled from the ports tree) and then run "$0 install" 3088db6b0a61SColin Percivalagain to finish installing updates. 3089db6b0a61SColin Percival EOF 3090db6b0a61SColin Percival rm newfiles 3091db6b0a61SColin Percival exit 0 3092db6b0a61SColin Percival fi 3093db6b0a61SColin Percival rm newfiles 3094db6b0a61SColin Percival fi 3095db6b0a61SColin Percival 3096db6b0a61SColin Percival # Remove old shared libraries 3097db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3098cd1ab228SColin Percival grep -vE '^[^|]+\|d\|' | 30999546dbd1SColin Percival grep -E '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' > INDEX-NEW 3100db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-OLD | 3101cd1ab228SColin Percival grep -vE '^[^|]+\|d\|' | 31029546dbd1SColin Percival grep -E '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' > INDEX-OLD 3103db6b0a61SColin Percival install_delete INDEX-OLD INDEX-NEW || return 1 3104db6b0a61SColin Percival 3105cd1ab228SColin Percival # Remove old directories 3106ebc1d19cSColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3107ebc1d19cSColin Percival grep -E '^[^|]+\|d\|' > INDEX-NEW 3108cd1ab228SColin Percival grep -vE '^/boot/' $1/INDEX-OLD | 3109cd1ab228SColin Percival grep -E '^[^|]+\|d\|' > INDEX-OLD 3110cd1ab228SColin Percival install_delete INDEX-OLD INDEX-NEW || return 1 3111cd1ab228SColin Percival 3112db6b0a61SColin Percival # Remove temporary files 3113db6b0a61SColin Percival rm INDEX-OLD INDEX-NEW 311448ffe56aSColin Percival} 311548ffe56aSColin Percival 311648ffe56aSColin Percival# Rearrange bits to allow the installed updates to be rolled back 311748ffe56aSColin Percivalinstall_setup_rollback () { 3118db6b0a61SColin Percival # Remove the "reboot after installing kernel", "kernel updated", and 3119db6b0a61SColin Percival # "finished installing the world" flags if present -- they are 3120db6b0a61SColin Percival # irrelevant when rolling back updates. 3121db6b0a61SColin Percival if [ -f ${BDHASH}-install/kernelfirst ]; then 3122db6b0a61SColin Percival rm ${BDHASH}-install/kernelfirst 3123db6b0a61SColin Percival rm ${BDHASH}-install/kerneldone 3124db6b0a61SColin Percival fi 3125db6b0a61SColin Percival if [ -f ${BDHASH}-install/worlddone ]; then 3126db6b0a61SColin Percival rm ${BDHASH}-install/worlddone 3127db6b0a61SColin Percival fi 3128db6b0a61SColin Percival 312948ffe56aSColin Percival if [ -L ${BDHASH}-rollback ]; then 313048ffe56aSColin Percival mv ${BDHASH}-rollback ${BDHASH}-install/rollback 313148ffe56aSColin Percival fi 313248ffe56aSColin Percival 313348ffe56aSColin Percival mv ${BDHASH}-install ${BDHASH}-rollback 313448ffe56aSColin Percival} 313548ffe56aSColin Percival 313648ffe56aSColin Percival# Actually install updates 313748ffe56aSColin Percivalinstall_run () { 313848ffe56aSColin Percival echo -n "Installing updates..." 313948ffe56aSColin Percival 314048ffe56aSColin Percival # Make sure we have all the files we should have 314148ffe56aSColin Percival install_verify ${BDHASH}-install/INDEX-OLD \ 314248ffe56aSColin Percival ${BDHASH}-install/INDEX-NEW || return 1 314348ffe56aSColin Percival 314448ffe56aSColin Percival # Remove system immutable flag from files 314548ffe56aSColin Percival install_unschg ${BDHASH}-install/INDEX-OLD \ 314648ffe56aSColin Percival ${BDHASH}-install/INDEX-NEW || return 1 314748ffe56aSColin Percival 3148db6b0a61SColin Percival # Install new files, delete old files, and update linker.hints 3149db6b0a61SColin Percival install_files ${BDHASH}-install || return 1 315048ffe56aSColin Percival 315148ffe56aSColin Percival # Rearrange bits to allow the installed updates to be rolled back 315248ffe56aSColin Percival install_setup_rollback 315348ffe56aSColin Percival 315448ffe56aSColin Percival echo " done." 315548ffe56aSColin Percival} 315648ffe56aSColin Percival 315748ffe56aSColin Percival# Rearrange bits to allow the previous set of updates to be rolled back next. 315848ffe56aSColin Percivalrollback_setup_rollback () { 315948ffe56aSColin Percival if [ -L ${BDHASH}-rollback/rollback ]; then 316048ffe56aSColin Percival mv ${BDHASH}-rollback/rollback rollback-tmp 316148ffe56aSColin Percival rm -r ${BDHASH}-rollback/ 316248ffe56aSColin Percival rm ${BDHASH}-rollback 316348ffe56aSColin Percival mv rollback-tmp ${BDHASH}-rollback 316448ffe56aSColin Percival else 316548ffe56aSColin Percival rm -r ${BDHASH}-rollback/ 316648ffe56aSColin Percival rm ${BDHASH}-rollback 316748ffe56aSColin Percival fi 316848ffe56aSColin Percival} 316948ffe56aSColin Percival 3170db6b0a61SColin Percival# Install old files, delete new files, and update linker.hints 3171db6b0a61SColin Percivalrollback_files () { 31721ec4fb3aSColin Percival # Install old shared library files which don't have the same path as 31731ec4fb3aSColin Percival # a new shared library file. 31741ec4fb3aSColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3175fd0963d1SColin Percival grep -E '/lib/.*\.so\.[0-9]+\|' | 31761ec4fb3aSColin Percival cut -f 1 -d '|' | 31771ec4fb3aSColin Percival sort > INDEX-NEW.libs.flist 3178db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-OLD | 3179fd0963d1SColin Percival grep -E '/lib/.*\.so\.[0-9]+\|' | 31801ec4fb3aSColin Percival sort -k 1,1 -t '|' - | 31811ec4fb3aSColin Percival join -t '|' -v 1 - INDEX-NEW.libs.flist > INDEX-OLD 3182db6b0a61SColin Percival install_from_index INDEX-OLD || return 1 3183db6b0a61SColin Percival 3184db6b0a61SColin Percival # Deal with files which are neither kernel nor shared library 3185db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-OLD | 3186fd0963d1SColin Percival grep -vE '/lib/.*\.so\.[0-9]+\|' > INDEX-OLD 3187db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3188fd0963d1SColin Percival grep -vE '/lib/.*\.so\.[0-9]+\|' > INDEX-NEW 3189db6b0a61SColin Percival install_from_index INDEX-OLD || return 1 3190db6b0a61SColin Percival install_delete INDEX-NEW INDEX-OLD || return 1 3191db6b0a61SColin Percival 31921ec4fb3aSColin Percival # Install any old shared library files which we didn't install above. 31931ec4fb3aSColin Percival grep -vE '^/boot/' $1/INDEX-OLD | 3194fd0963d1SColin Percival grep -E '/lib/.*\.so\.[0-9]+\|' | 31951ec4fb3aSColin Percival sort -k 1,1 -t '|' - | 31961ec4fb3aSColin Percival join -t '|' - INDEX-NEW.libs.flist > INDEX-OLD 31971ec4fb3aSColin Percival install_from_index INDEX-OLD || return 1 31981ec4fb3aSColin Percival 3199db6b0a61SColin Percival # Delete unneeded shared library files 3200db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-OLD | 3201fd0963d1SColin Percival grep -E '/lib/.*\.so\.[0-9]+\|' > INDEX-OLD 3202db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3203fd0963d1SColin Percival grep -E '/lib/.*\.so\.[0-9]+\|' > INDEX-NEW 3204db6b0a61SColin Percival install_delete INDEX-NEW INDEX-OLD || return 1 3205db6b0a61SColin Percival 3206db6b0a61SColin Percival # Deal with kernel files 3207db6b0a61SColin Percival grep -E '^/boot/' $1/INDEX-OLD > INDEX-OLD 3208db6b0a61SColin Percival grep -E '^/boot/' $1/INDEX-NEW > INDEX-NEW 3209db6b0a61SColin Percival install_from_index INDEX-OLD || return 1 3210db6b0a61SColin Percival install_delete INDEX-NEW INDEX-OLD || return 1 3211db6b0a61SColin Percival if [ -s INDEX-OLD -o -s INDEX-NEW ]; then 3212db6b0a61SColin Percival kldxref -R /boot/ 2>/dev/null 3213db6b0a61SColin Percival fi 3214db6b0a61SColin Percival 3215db6b0a61SColin Percival # Remove temporary files 32160e0d8d5aSColin Percival rm INDEX-OLD INDEX-NEW INDEX-NEW.libs.flist 3217db6b0a61SColin Percival} 3218db6b0a61SColin Percival 321948ffe56aSColin Percival# Actually rollback updates 322048ffe56aSColin Percivalrollback_run () { 322148ffe56aSColin Percival echo -n "Uninstalling updates..." 322248ffe56aSColin Percival 322348ffe56aSColin Percival # If there are updates waiting to be installed, remove them; we 322448ffe56aSColin Percival # want the user to re-run 'fetch' after rolling back updates. 322548ffe56aSColin Percival if [ -L ${BDHASH}-install ]; then 322648ffe56aSColin Percival rm -r ${BDHASH}-install/ 322748ffe56aSColin Percival rm ${BDHASH}-install 322848ffe56aSColin Percival fi 322948ffe56aSColin Percival 323048ffe56aSColin Percival # Make sure we have all the files we should have 323148ffe56aSColin Percival install_verify ${BDHASH}-rollback/INDEX-NEW \ 323248ffe56aSColin Percival ${BDHASH}-rollback/INDEX-OLD || return 1 323348ffe56aSColin Percival 323448ffe56aSColin Percival # Remove system immutable flag from files 323548ffe56aSColin Percival install_unschg ${BDHASH}-rollback/INDEX-NEW \ 323648ffe56aSColin Percival ${BDHASH}-rollback/INDEX-OLD || return 1 323748ffe56aSColin Percival 3238db6b0a61SColin Percival # Install old files, delete new files, and update linker.hints 3239db6b0a61SColin Percival rollback_files ${BDHASH}-rollback || return 1 324048ffe56aSColin Percival 324148ffe56aSColin Percival # Remove the rollback directory and the symlink pointing to it; and 324248ffe56aSColin Percival # rearrange bits to allow the previous set of updates to be rolled 324348ffe56aSColin Percival # back next. 324448ffe56aSColin Percival rollback_setup_rollback 324548ffe56aSColin Percival 324648ffe56aSColin Percival echo " done." 324748ffe56aSColin Percival} 324848ffe56aSColin Percival 324908e23beeSColin Percival# Compare INDEX-ALL and INDEX-PRESENT and print warnings about differences. 325008e23beeSColin PercivalIDS_compare () { 3251bb10a826SColin Percival # Get all the lines which mismatch in something other than file 3252bb10a826SColin Percival # flags. We ignore file flags because sysinstall doesn't seem to 3253bb10a826SColin Percival # set them when it installs FreeBSD; warning about these adds a 3254bb10a826SColin Percival # very large amount of noise. 3255bb10a826SColin Percival cut -f 1-5,7-8 -d '|' $1 > $1.noflags 3256bb10a826SColin Percival sort -k 1,1 -t '|' $1.noflags > $1.sorted 3257bb10a826SColin Percival cut -f 1-5,7-8 -d '|' $2 | 3258bb10a826SColin Percival comm -13 $1.noflags - | 3259bb10a826SColin Percival fgrep -v '|-|||||' | 326008e23beeSColin Percival sort -k 1,1 -t '|' | 326108e23beeSColin Percival join -t '|' $1.sorted - > INDEX-NOTMATCHING 326208e23beeSColin Percival 326308e23beeSColin Percival # Ignore files which match IDSIGNOREPATHS. 326408e23beeSColin Percival for X in ${IDSIGNOREPATHS}; do 326508e23beeSColin Percival grep -E "^${X}" INDEX-NOTMATCHING 326608e23beeSColin Percival done | 326708e23beeSColin Percival sort -u | 326808e23beeSColin Percival comm -13 - INDEX-NOTMATCHING > INDEX-NOTMATCHING.tmp 326908e23beeSColin Percival mv INDEX-NOTMATCHING.tmp INDEX-NOTMATCHING 327008e23beeSColin Percival 327108e23beeSColin Percival # Go through the lines and print warnings. 3272aa60062eSColin Percival local IFS='|' 3273aa60062eSColin Percival while read FPATH TYPE OWNER GROUP PERM HASH LINK P_TYPE P_OWNER P_GROUP P_PERM P_HASH P_LINK; do 327408e23beeSColin Percival # Warn about different object types. 327508e23beeSColin Percival if ! [ "${TYPE}" = "${P_TYPE}" ]; then 327608e23beeSColin Percival echo -n "${FPATH} is a " 327708e23beeSColin Percival case "${P_TYPE}" in 327808e23beeSColin Percival f) echo -n "regular file, " 327908e23beeSColin Percival ;; 328008e23beeSColin Percival d) echo -n "directory, " 328108e23beeSColin Percival ;; 328208e23beeSColin Percival L) echo -n "symlink, " 328308e23beeSColin Percival ;; 328408e23beeSColin Percival esac 328508e23beeSColin Percival echo -n "but should be a " 328608e23beeSColin Percival case "${TYPE}" in 328708e23beeSColin Percival f) echo -n "regular file." 328808e23beeSColin Percival ;; 328908e23beeSColin Percival d) echo -n "directory." 329008e23beeSColin Percival ;; 329108e23beeSColin Percival L) echo -n "symlink." 329208e23beeSColin Percival ;; 329308e23beeSColin Percival esac 329408e23beeSColin Percival echo 329508e23beeSColin Percival 329608e23beeSColin Percival # Skip other tests, since they don't make sense if 329708e23beeSColin Percival # we're comparing different object types. 329808e23beeSColin Percival continue 329908e23beeSColin Percival fi 330008e23beeSColin Percival 330108e23beeSColin Percival # Warn about different owners. 330208e23beeSColin Percival if ! [ "${OWNER}" = "${P_OWNER}" ]; then 330308e23beeSColin Percival echo -n "${FPATH} is owned by user id ${P_OWNER}, " 330408e23beeSColin Percival echo "but should be owned by user id ${OWNER}." 330508e23beeSColin Percival fi 330608e23beeSColin Percival 330708e23beeSColin Percival # Warn about different groups. 330808e23beeSColin Percival if ! [ "${GROUP}" = "${P_GROUP}" ]; then 330908e23beeSColin Percival echo -n "${FPATH} is owned by group id ${P_GROUP}, " 331008e23beeSColin Percival echo "but should be owned by group id ${GROUP}." 331108e23beeSColin Percival fi 331208e23beeSColin Percival 331308e23beeSColin Percival # Warn about different permissions. We do not warn about 331408e23beeSColin Percival # different permissions on symlinks, since some archivers 331508e23beeSColin Percival # don't extract symlink permissions correctly and they are 331608e23beeSColin Percival # ignored anyway. 331708e23beeSColin Percival if ! [ "${PERM}" = "${P_PERM}" ] && 331808e23beeSColin Percival ! [ "${TYPE}" = "L" ]; then 331908e23beeSColin Percival echo -n "${FPATH} has ${P_PERM} permissions, " 332008e23beeSColin Percival echo "but should have ${PERM} permissions." 332108e23beeSColin Percival fi 332208e23beeSColin Percival 332308e23beeSColin Percival # Warn about different file hashes / symlink destinations. 332408e23beeSColin Percival if ! [ "${HASH}" = "${P_HASH}" ]; then 332508e23beeSColin Percival if [ "${TYPE}" = "L" ]; then 332608e23beeSColin Percival echo -n "${FPATH} is a symlink to ${P_HASH}, " 332708e23beeSColin Percival echo "but should be a symlink to ${HASH}." 332808e23beeSColin Percival fi 332908e23beeSColin Percival if [ "${TYPE}" = "f" ]; then 333008e23beeSColin Percival echo -n "${FPATH} has SHA256 hash ${P_HASH}, " 333108e23beeSColin Percival echo "but should have SHA256 hash ${HASH}." 333208e23beeSColin Percival fi 333308e23beeSColin Percival fi 333408e23beeSColin Percival 333508e23beeSColin Percival # We don't warn about different hard links, since some 333608e23beeSColin Percival # some archivers break hard links, and as long as the 333708e23beeSColin Percival # underlying data is correct they really don't matter. 333808e23beeSColin Percival done < INDEX-NOTMATCHING 333908e23beeSColin Percival 334008e23beeSColin Percival # Clean up 3341bb10a826SColin Percival rm $1 $1.noflags $1.sorted $2 INDEX-NOTMATCHING 334208e23beeSColin Percival} 334308e23beeSColin Percival 334408e23beeSColin Percival# Do the work involved in comparing the system to a "known good" index 334508e23beeSColin PercivalIDS_run () { 334608e23beeSColin Percival workdir_init || return 1 334708e23beeSColin Percival 334808e23beeSColin Percival # Prepare the mirror list. 334908e23beeSColin Percival fetch_pick_server_init && fetch_pick_server 335008e23beeSColin Percival 335108e23beeSColin Percival # Try to fetch the public key until we run out of servers. 335208e23beeSColin Percival while ! fetch_key; do 335308e23beeSColin Percival fetch_pick_server || return 1 335408e23beeSColin Percival done 335508e23beeSColin Percival 335608e23beeSColin Percival # Try to fetch the metadata index signature ("tag") until we run 335708e23beeSColin Percival # out of available servers; and sanity check the downloaded tag. 335808e23beeSColin Percival while ! fetch_tag; do 335908e23beeSColin Percival fetch_pick_server || return 1 336008e23beeSColin Percival done 336108e23beeSColin Percival fetch_tagsanity || return 1 336208e23beeSColin Percival 336308e23beeSColin Percival # Fetch INDEX-OLD and INDEX-ALL. 336408e23beeSColin Percival fetch_metadata INDEX-OLD INDEX-ALL || return 1 336508e23beeSColin Percival 336608e23beeSColin Percival # Generate filtered INDEX-OLD and INDEX-ALL files containing only 336708e23beeSColin Percival # the components we want and without anything marked as "Ignore". 336808e23beeSColin Percival fetch_filter_metadata INDEX-OLD || return 1 336908e23beeSColin Percival fetch_filter_metadata INDEX-ALL || return 1 337008e23beeSColin Percival 337108e23beeSColin Percival # Merge the INDEX-OLD and INDEX-ALL files into INDEX-ALL. 337208e23beeSColin Percival sort INDEX-OLD INDEX-ALL > INDEX-ALL.tmp 337308e23beeSColin Percival mv INDEX-ALL.tmp INDEX-ALL 337408e23beeSColin Percival rm INDEX-OLD 337508e23beeSColin Percival 337608e23beeSColin Percival # Translate /boot/${KERNCONF} to ${KERNELDIR} 337708e23beeSColin Percival fetch_filter_kernel_names INDEX-ALL ${KERNCONF} 337808e23beeSColin Percival 337908e23beeSColin Percival # Inspect the system and generate an INDEX-PRESENT file. 338008e23beeSColin Percival fetch_inspect_system INDEX-ALL INDEX-PRESENT /dev/null || return 1 338108e23beeSColin Percival 338208e23beeSColin Percival # Compare INDEX-ALL and INDEX-PRESENT and print warnings about any 338308e23beeSColin Percival # differences. 338408e23beeSColin Percival IDS_compare INDEX-ALL INDEX-PRESENT 338508e23beeSColin Percival} 338608e23beeSColin Percival 338748ffe56aSColin Percival#### Main functions -- call parameter-handling and core functions 338848ffe56aSColin Percival 338948ffe56aSColin Percival# Using the command line, configuration file, and defaults, 339048ffe56aSColin Percival# set all the parameters which are needed later. 339148ffe56aSColin Percivalget_params () { 339248ffe56aSColin Percival init_params 339348ffe56aSColin Percival parse_cmdline $@ 339448ffe56aSColin Percival parse_conffile 339548ffe56aSColin Percival default_params 339648ffe56aSColin Percival} 339748ffe56aSColin Percival 339848ffe56aSColin Percival# Fetch command. Make sure that we're being called 339948ffe56aSColin Percival# interactively, then run fetch_check_params and fetch_run 340048ffe56aSColin Percivalcmd_fetch () { 34019a63bbc9SColin Percival finalize_components_config ${COMPONENTS} 34028bf2dcceSAllan Jude if [ ! -t 0 -a $NOTTYOK -eq 0 ]; then 340348ffe56aSColin Percival echo -n "`basename $0` fetch should not " 340448ffe56aSColin Percival echo "be run non-interactively." 340548ffe56aSColin Percival echo "Run `basename $0` cron instead." 340648ffe56aSColin Percival exit 1 340748ffe56aSColin Percival fi 340848ffe56aSColin Percival fetch_check_params 340948ffe56aSColin Percival fetch_run || exit 1 341033bd05c3SGuangyuan Yang ISFETCHED=1 341148ffe56aSColin Percival} 341248ffe56aSColin Percival 341348ffe56aSColin Percival# Cron command. Make sure the parameters are sensible; wait 341448ffe56aSColin Percival# rand(3600) seconds; then fetch updates. While fetching updates, 341548ffe56aSColin Percival# send output to a temporary file; only print that file if the 341648ffe56aSColin Percival# fetching failed. 341748ffe56aSColin Percivalcmd_cron () { 341848ffe56aSColin Percival fetch_check_params 341948ffe56aSColin Percival sleep `jot -r 1 0 3600` 342048ffe56aSColin Percival 342148ffe56aSColin Percival TMPFILE=`mktemp /tmp/freebsd-update.XXXXXX` || exit 1 34229a63bbc9SColin Percival finalize_components_config ${COMPONENTS} >> ${TMPFILE} 342348ffe56aSColin Percival if ! fetch_run >> ${TMPFILE} || 342448ffe56aSColin Percival ! grep -q "No updates needed" ${TMPFILE} || 342548ffe56aSColin Percival [ ${VERBOSELEVEL} = "debug" ]; then 342648ffe56aSColin Percival mail -s "`hostname` security updates" ${MAILTO} < ${TMPFILE} 342748ffe56aSColin Percival fi 342848ffe56aSColin Percival 342948ffe56aSColin Percival rm ${TMPFILE} 343048ffe56aSColin Percival} 343148ffe56aSColin Percival 3432db6b0a61SColin Percival# Fetch files for upgrading to a new release. 3433db6b0a61SColin Percivalcmd_upgrade () { 34349a63bbc9SColin Percival finalize_components_config ${COMPONENTS} 3435db6b0a61SColin Percival upgrade_check_params 3436db6b0a61SColin Percival upgrade_run || exit 1 3437db6b0a61SColin Percival} 3438db6b0a61SColin Percival 3439101d33b8SMichael Gmelin# Check if there are fetched updates ready to install. 3440101d33b8SMichael Gmelin# Chdir into the working directory. 34418cfda118SMichael Gmelincmd_updatesready () { 34429a63bbc9SColin Percival finalize_components_config ${COMPONENTS} 3443101d33b8SMichael Gmelin # Check if working directory exists (if not, no updates pending) 3444101d33b8SMichael Gmelin if ! [ -e "${WORKDIR}" ]; then 3445101d33b8SMichael Gmelin echo "No updates are available to install." 3446101d33b8SMichael Gmelin exit 2 3447101d33b8SMichael Gmelin fi 3448101d33b8SMichael Gmelin 3449101d33b8SMichael Gmelin # Change into working directory (fail if no permission/directory etc.) 3450101d33b8SMichael Gmelin cd ${WORKDIR} || exit 1 3451101d33b8SMichael Gmelin 34528cfda118SMichael Gmelin # Construct a unique name from ${BASEDIR} 34538cfda118SMichael Gmelin BDHASH=`echo ${BASEDIR} | sha256 -q` 34548cfda118SMichael Gmelin 34558cfda118SMichael Gmelin # Check that we have updates ready to install 34568cfda118SMichael Gmelin if ! [ -L ${BDHASH}-install ]; then 34578cfda118SMichael Gmelin echo "No updates are available to install." 34588cfda118SMichael Gmelin exit 2 34598cfda118SMichael Gmelin fi 34608cfda118SMichael Gmelin 34618cfda118SMichael Gmelin echo "There are updates available to install." 34628cfda118SMichael Gmelin echo "Run '$0 install' to proceed." 34638cfda118SMichael Gmelin} 34648cfda118SMichael Gmelin 346548ffe56aSColin Percival# Install downloaded updates. 346648ffe56aSColin Percivalcmd_install () { 34679a63bbc9SColin Percival finalize_components_config ${COMPONENTS} 346848ffe56aSColin Percival install_check_params 3469f28f1389SDave Fullard install_create_be 347048ffe56aSColin Percival install_run || exit 1 347148ffe56aSColin Percival} 347248ffe56aSColin Percival 347348ffe56aSColin Percival# Rollback most recently installed updates. 347448ffe56aSColin Percivalcmd_rollback () { 34759a63bbc9SColin Percival finalize_components_config ${COMPONENTS} 347648ffe56aSColin Percival rollback_check_params 347748ffe56aSColin Percival rollback_run || exit 1 347848ffe56aSColin Percival} 347948ffe56aSColin Percival 348008e23beeSColin Percival# Compare system against a "known good" index. 348108e23beeSColin Percivalcmd_IDS () { 34829a63bbc9SColin Percival finalize_components_config ${COMPONENTS} 348308e23beeSColin Percival IDS_check_params 348408e23beeSColin Percival IDS_run || exit 1 348508e23beeSColin Percival} 348608e23beeSColin Percival 34878cfda118SMichael Gmelin# Output configuration. 34888cfda118SMichael Gmelincmd_showconfig () { 34899a63bbc9SColin Percival finalize_components_config ${COMPONENTS} 34908cfda118SMichael Gmelin for X in ${CONFIGOPTIONS}; do 34918cfda118SMichael Gmelin echo $X=$(eval echo \$${X}) 34928cfda118SMichael Gmelin done 34938cfda118SMichael Gmelin} 34948cfda118SMichael Gmelin 349548ffe56aSColin Percival#### Entry point 349648ffe56aSColin Percival 349748ffe56aSColin Percival# Make sure we find utilities from the base system 349848ffe56aSColin Percivalexport PATH=/sbin:/bin:/usr/sbin:/usr/bin:${PATH} 349948ffe56aSColin Percival 35009c990fb2SGordon Tetlow# Set a pager if the user doesn't 35019c990fb2SGordon Tetlowif [ -z "$PAGER" ]; then 350247cc9ee1SAlan Somers PAGER=/usr/bin/less 35039c990fb2SGordon Tetlowfi 35049c990fb2SGordon Tetlow 3505f2890dbdSColin Percival# Set LC_ALL in order to avoid problems with character ranges like [A-Z]. 3506f2890dbdSColin Percivalexport LC_ALL=C 3507f2890dbdSColin Percival 3508e093c61bSEd Maste# Clear environment variables that may affect operation of tools that we use. 3509e093c61bSEd Masteunset GREP_OPTIONS 3510e093c61bSEd Maste 351148ffe56aSColin Percivalget_params $@ 351248ffe56aSColin Percivalfor COMMAND in ${COMMANDS}; do 351348ffe56aSColin Percival cmd_${COMMAND} 351448ffe56aSColin Percivaldone 3515