148ffe56aSColin Percival#!/bin/sh 248ffe56aSColin Percival 348ffe56aSColin Percival#- 44d846d26SWarner Losh# SPDX-License-Identifier: BSD-2-Clause 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#### Usage function -- called from command-line handling code. 3148ffe56aSColin Percival 3248ffe56aSColin Percival# Usage instructions. Options not listed: 3348ffe56aSColin Percival# --debug -- don't filter output from utilities 3448ffe56aSColin Percival# --no-stats -- don't show progress statistics while fetching files 3548ffe56aSColin Percivalusage () { 3648ffe56aSColin Percival cat <<EOF 37c76da1f0SFaraz Vahediusage: `basename $0` [options] command ... 3848ffe56aSColin Percival 3948ffe56aSColin PercivalOptions: 4048ffe56aSColin Percival -b basedir -- Operate on a system mounted at basedir 4148ffe56aSColin Percival (default: /) 4248ffe56aSColin Percival -d workdir -- Store working files in workdir 4348ffe56aSColin Percival (default: /var/db/freebsd-update/) 4448ffe56aSColin Percival -f conffile -- Read configuration options from conffile 4548ffe56aSColin Percival (default: /etc/freebsd-update.conf) 46df7e2e0dSEd Maste -F -- Force a fetch operation to proceed in the 47df7e2e0dSEd Maste case of an unfinished upgrade 48c76da1f0SFaraz Vahedi -j jail -- Operate on the given jail specified by jid or name 4948ffe56aSColin Percival -k KEY -- Trust an RSA key with SHA256 hash of KEY 50e0e5bf4dSPoul-Henning Kamp -r release -- Target for upgrade (e.g., 13.2-RELEASE) 5148ffe56aSColin Percival -s server -- Server from which to fetch updates 5248ffe56aSColin Percival (default: update.FreeBSD.org) 5348ffe56aSColin Percival -t address -- Mail output of cron command, if any, to address 5448ffe56aSColin Percival (default: root) 558935f242SAllan Jude --not-running-from-cron 568935f242SAllan Jude -- Run without a tty, for use by automated tools 57b39ce43eSColin Percival --currently-running release 58b39ce43eSColin Percival -- Update as if currently running this release 5948ffe56aSColin PercivalCommands: 6048ffe56aSColin Percival fetch -- Fetch updates from server 6148ffe56aSColin Percival cron -- Sleep rand(3600) seconds, fetch updates, and send an 6248ffe56aSColin Percival email if updates were found 63db6b0a61SColin Percival upgrade -- Fetch upgrades to FreeBSD version specified via -r option 648cfda118SMichael Gmelin updatesready -- Check if there are fetched updates ready to install 65db6b0a61SColin Percival install -- Install downloaded updates or upgrades 6648ffe56aSColin Percival rollback -- Uninstall most recently installed updates 6775cb6429SEd Maste IDS -- Compare the system against an index of "known good" files 688cfda118SMichael Gmelin showconfig -- Show configuration 6948ffe56aSColin PercivalEOF 7048ffe56aSColin Percival exit 0 7148ffe56aSColin Percival} 7248ffe56aSColin Percival 7348ffe56aSColin Percival#### Configuration processing functions 7448ffe56aSColin Percival 7548ffe56aSColin Percival#- 7648ffe56aSColin Percival# Configuration options are set in the following order of priority: 7748ffe56aSColin Percival# 1. Command line options 7848ffe56aSColin Percival# 2. Configuration file options 7948ffe56aSColin Percival# 3. Default options 8048ffe56aSColin Percival# In addition, certain options (e.g., IgnorePaths) can be specified multiple 8148ffe56aSColin Percival# times and (as long as these are all in the same place, e.g., inside the 8248ffe56aSColin Percival# configuration file) they will accumulate. Finally, because the path to the 8348ffe56aSColin Percival# configuration file can be specified at the command line, the entire command 8448ffe56aSColin Percival# line must be processed before we start reading the configuration file. 8548ffe56aSColin Percival# 8648ffe56aSColin Percival# Sound like a mess? It is. Here's how we handle this: 8748ffe56aSColin Percival# 1. Initialize CONFFILE and all the options to "". 8848ffe56aSColin Percival# 2. Process the command line. Throw an error if a non-accumulating option 8948ffe56aSColin Percival# is specified twice. 9048ffe56aSColin Percival# 3. If CONFFILE is "", set CONFFILE to /etc/freebsd-update.conf . 9148ffe56aSColin Percival# 4. For all the configuration options X, set X_saved to X. 9248ffe56aSColin Percival# 5. Initialize all the options to "". 9348ffe56aSColin Percival# 6. Read CONFFILE line by line, parsing options. 9448ffe56aSColin Percival# 7. For each configuration option X, set X to X_saved iff X_saved is not "". 9548ffe56aSColin Percival# 8. Repeat steps 4-7, except setting options to their default values at (6). 9648ffe56aSColin Percival 9748ffe56aSColin PercivalCONFIGOPTIONS="KEYPRINT WORKDIR SERVERNAME MAILTO ALLOWADD ALLOWDELETE 9848ffe56aSColin Percival KEEPMODIFIEDMETADATA COMPONENTS IGNOREPATHS UPDATEIFUNMODIFIED 9908e23beeSColin Percival BASEDIR VERBOSELEVEL TARGETRELEASE STRICTCOMPONENTS MERGECHANGES 10023d827efSSimon L. B. Nielsen IDSIGNOREPATHS BACKUPKERNEL BACKUPKERNELDIR BACKUPKERNELSYMBOLFILES" 10148ffe56aSColin Percival 10248ffe56aSColin Percival# Set all the configuration options to "". 10348ffe56aSColin Percivalnullconfig () { 10448ffe56aSColin Percival for X in ${CONFIGOPTIONS}; do 10548ffe56aSColin Percival eval ${X}="" 10648ffe56aSColin Percival done 10748ffe56aSColin Percival} 10848ffe56aSColin Percival 10948ffe56aSColin Percival# For each configuration option X, set X_saved to X. 11048ffe56aSColin Percivalsaveconfig () { 11148ffe56aSColin Percival for X in ${CONFIGOPTIONS}; do 11248ffe56aSColin Percival eval ${X}_saved=\$${X} 11348ffe56aSColin Percival done 11448ffe56aSColin Percival} 11548ffe56aSColin Percival 11648ffe56aSColin Percival# For each configuration option X, set X to X_saved if X_saved is not "". 11748ffe56aSColin Percivalmergeconfig () { 11848ffe56aSColin Percival for X in ${CONFIGOPTIONS}; do 11948ffe56aSColin Percival eval _=\$${X}_saved 12048ffe56aSColin Percival if ! [ -z "${_}" ]; then 12148ffe56aSColin Percival eval ${X}=\$${X}_saved 12248ffe56aSColin Percival fi 12348ffe56aSColin Percival done 12448ffe56aSColin Percival} 12548ffe56aSColin Percival 12648ffe56aSColin Percival# Set the trusted keyprint. 12748ffe56aSColin Percivalconfig_KeyPrint () { 12848ffe56aSColin Percival if [ -z ${KEYPRINT} ]; then 12948ffe56aSColin Percival KEYPRINT=$1 13048ffe56aSColin Percival else 13148ffe56aSColin Percival return 1 13248ffe56aSColin Percival fi 13348ffe56aSColin Percival} 13448ffe56aSColin Percival 13548ffe56aSColin Percival# Set the working directory. 13648ffe56aSColin Percivalconfig_WorkDir () { 13748ffe56aSColin Percival if [ -z ${WORKDIR} ]; then 13848ffe56aSColin Percival WORKDIR=$1 13948ffe56aSColin Percival else 14048ffe56aSColin Percival return 1 14148ffe56aSColin Percival fi 14248ffe56aSColin Percival} 14348ffe56aSColin Percival 14448ffe56aSColin Percival# Set the name of the server (pool) from which to fetch updates 14548ffe56aSColin Percivalconfig_ServerName () { 14648ffe56aSColin Percival if [ -z ${SERVERNAME} ]; then 14748ffe56aSColin Percival SERVERNAME=$1 14848ffe56aSColin Percival else 14948ffe56aSColin Percival return 1 15048ffe56aSColin Percival fi 15148ffe56aSColin Percival} 15248ffe56aSColin Percival 15348ffe56aSColin Percival# Set the address to which 'cron' output will be mailed. 15448ffe56aSColin Percivalconfig_MailTo () { 15548ffe56aSColin Percival if [ -z ${MAILTO} ]; then 15648ffe56aSColin Percival MAILTO=$1 15748ffe56aSColin Percival else 15848ffe56aSColin Percival return 1 15948ffe56aSColin Percival fi 16048ffe56aSColin Percival} 16148ffe56aSColin Percival 16248ffe56aSColin Percival# Set whether FreeBSD Update is allowed to add files (or directories, or 16348ffe56aSColin Percival# symlinks) which did not previously exist. 16448ffe56aSColin Percivalconfig_AllowAdd () { 16548ffe56aSColin Percival if [ -z ${ALLOWADD} ]; then 16648ffe56aSColin Percival case $1 in 16748ffe56aSColin Percival [Yy][Ee][Ss]) 16848ffe56aSColin Percival ALLOWADD=yes 16948ffe56aSColin Percival ;; 17048ffe56aSColin Percival [Nn][Oo]) 17148ffe56aSColin Percival ALLOWADD=no 17248ffe56aSColin Percival ;; 17348ffe56aSColin Percival *) 17448ffe56aSColin Percival return 1 17548ffe56aSColin Percival ;; 17648ffe56aSColin Percival esac 17748ffe56aSColin Percival else 17848ffe56aSColin Percival return 1 17948ffe56aSColin Percival fi 18048ffe56aSColin Percival} 18148ffe56aSColin Percival 18248ffe56aSColin Percival# Set whether FreeBSD Update is allowed to remove files/directories/symlinks. 18348ffe56aSColin Percivalconfig_AllowDelete () { 18448ffe56aSColin Percival if [ -z ${ALLOWDELETE} ]; then 18548ffe56aSColin Percival case $1 in 18648ffe56aSColin Percival [Yy][Ee][Ss]) 18748ffe56aSColin Percival ALLOWDELETE=yes 18848ffe56aSColin Percival ;; 18948ffe56aSColin Percival [Nn][Oo]) 19048ffe56aSColin Percival ALLOWDELETE=no 19148ffe56aSColin Percival ;; 19248ffe56aSColin Percival *) 19348ffe56aSColin Percival return 1 19448ffe56aSColin Percival ;; 19548ffe56aSColin Percival esac 19648ffe56aSColin Percival else 19748ffe56aSColin Percival return 1 19848ffe56aSColin Percival fi 19948ffe56aSColin Percival} 20048ffe56aSColin Percival 20148ffe56aSColin Percival# Set whether FreeBSD Update should keep existing inode ownership, 20248ffe56aSColin Percival# permissions, and flags, in the event that they have been modified locally 20348ffe56aSColin Percival# after the release. 20448ffe56aSColin Percivalconfig_KeepModifiedMetadata () { 20548ffe56aSColin Percival if [ -z ${KEEPMODIFIEDMETADATA} ]; then 20648ffe56aSColin Percival case $1 in 20748ffe56aSColin Percival [Yy][Ee][Ss]) 20848ffe56aSColin Percival KEEPMODIFIEDMETADATA=yes 20948ffe56aSColin Percival ;; 21048ffe56aSColin Percival [Nn][Oo]) 21148ffe56aSColin Percival KEEPMODIFIEDMETADATA=no 21248ffe56aSColin Percival ;; 21348ffe56aSColin Percival *) 21448ffe56aSColin Percival return 1 21548ffe56aSColin Percival ;; 21648ffe56aSColin Percival esac 21748ffe56aSColin Percival else 21848ffe56aSColin Percival return 1 21948ffe56aSColin Percival fi 22048ffe56aSColin Percival} 22148ffe56aSColin Percival 22248ffe56aSColin Percival# Add to the list of components which should be kept updated. 22348ffe56aSColin Percivalconfig_Components () { 22448ffe56aSColin Percival for C in $@; do 22512294db4SMichael Gmelin COMPONENTS="${COMPONENTS} ${C}" 22612294db4SMichael Gmelin done 22712294db4SMichael Gmelin} 22812294db4SMichael Gmelin 22912294db4SMichael Gmelin# Remove src component from list if it isn't installed 23012294db4SMichael Gmelinfinalize_components_config () { 23112294db4SMichael Gmelin COMPONENTS="" 23212294db4SMichael Gmelin for C in $@; do 2335a74378cSXin LI if [ "$C" = "src" ]; then 234cfd9be9cSEd Maste if [ -e "${BASEDIR}/usr/src/COPYRIGHT" ]; then 23548ffe56aSColin Percival COMPONENTS="${COMPONENTS} ${C}" 2365a74378cSXin LI else 2375a74378cSXin LI echo "src component not installed, skipped" 2385a74378cSXin LI fi 2395a74378cSXin LI else 2405a74378cSXin LI COMPONENTS="${COMPONENTS} ${C}" 2415a74378cSXin LI fi 24248ffe56aSColin Percival done 24348ffe56aSColin Percival} 24448ffe56aSColin Percival 24548ffe56aSColin Percival# Add to the list of paths under which updates will be ignored. 24648ffe56aSColin Percivalconfig_IgnorePaths () { 24748ffe56aSColin Percival for C in $@; do 24848ffe56aSColin Percival IGNOREPATHS="${IGNOREPATHS} ${C}" 24948ffe56aSColin Percival done 25048ffe56aSColin Percival} 25148ffe56aSColin Percival 25208e23beeSColin Percival# Add to the list of paths which IDS should ignore. 25308e23beeSColin Percivalconfig_IDSIgnorePaths () { 25408e23beeSColin Percival for C in $@; do 25508e23beeSColin Percival IDSIGNOREPATHS="${IDSIGNOREPATHS} ${C}" 25608e23beeSColin Percival done 25708e23beeSColin Percival} 25808e23beeSColin Percival 25948ffe56aSColin Percival# Add to the list of paths within which updates will be performed only if the 26048ffe56aSColin Percival# file on disk has not been modified locally. 26148ffe56aSColin Percivalconfig_UpdateIfUnmodified () { 26248ffe56aSColin Percival for C in $@; do 26348ffe56aSColin Percival UPDATEIFUNMODIFIED="${UPDATEIFUNMODIFIED} ${C}" 26448ffe56aSColin Percival done 26548ffe56aSColin Percival} 26648ffe56aSColin Percival 267db6b0a61SColin Percival# Add to the list of paths within which updates to text files will be merged 268db6b0a61SColin Percival# instead of overwritten. 269db6b0a61SColin Percivalconfig_MergeChanges () { 270db6b0a61SColin Percival for C in $@; do 271db6b0a61SColin Percival MERGECHANGES="${MERGECHANGES} ${C}" 272db6b0a61SColin Percival done 273db6b0a61SColin Percival} 274db6b0a61SColin Percival 27548ffe56aSColin Percival# Work on a FreeBSD installation mounted under $1 27648ffe56aSColin Percivalconfig_BaseDir () { 27748ffe56aSColin Percival if [ -z ${BASEDIR} ]; then 27848ffe56aSColin Percival BASEDIR=$1 27948ffe56aSColin Percival else 28048ffe56aSColin Percival return 1 28148ffe56aSColin Percival fi 28248ffe56aSColin Percival} 28348ffe56aSColin Percival 284db6b0a61SColin Percival# When fetching upgrades, should we assume the user wants exactly the 285db6b0a61SColin Percival# components listed in COMPONENTS, rather than trying to guess based on 286db6b0a61SColin Percival# what's currently installed? 287db6b0a61SColin Percivalconfig_StrictComponents () { 288db6b0a61SColin Percival if [ -z ${STRICTCOMPONENTS} ]; then 289db6b0a61SColin Percival case $1 in 290db6b0a61SColin Percival [Yy][Ee][Ss]) 291db6b0a61SColin Percival STRICTCOMPONENTS=yes 292db6b0a61SColin Percival ;; 293db6b0a61SColin Percival [Nn][Oo]) 294db6b0a61SColin Percival STRICTCOMPONENTS=no 295db6b0a61SColin Percival ;; 296db6b0a61SColin Percival *) 297db6b0a61SColin Percival return 1 298db6b0a61SColin Percival ;; 299db6b0a61SColin Percival esac 300db6b0a61SColin Percival else 301db6b0a61SColin Percival return 1 302db6b0a61SColin Percival fi 303db6b0a61SColin Percival} 304db6b0a61SColin Percival 305db6b0a61SColin Percival# Upgrade to FreeBSD $1 306db6b0a61SColin Percivalconfig_TargetRelease () { 307db6b0a61SColin Percival if [ -z ${TARGETRELEASE} ]; then 308db6b0a61SColin Percival TARGETRELEASE=$1 309db6b0a61SColin Percival else 310db6b0a61SColin Percival return 1 311db6b0a61SColin Percival fi 312d23dc1eeSColin Percival if echo ${TARGETRELEASE} | grep -qE '^[0-9.]+$'; then 313d23dc1eeSColin Percival TARGETRELEASE="${TARGETRELEASE}-RELEASE" 314d23dc1eeSColin Percival fi 315db6b0a61SColin Percival} 316db6b0a61SColin Percival 3170d5c5243SEd Maste# Pretend current release is FreeBSD $1 3180d5c5243SEd Masteconfig_SourceRelease () { 3190d5c5243SEd Maste UNAME_r=$1 3200d5c5243SEd Maste if echo ${UNAME_r} | grep -qE '^[0-9.]+$'; then 3210d5c5243SEd Maste UNAME_r="${UNAME_r}-RELEASE" 3220d5c5243SEd Maste fi 323b958d4b2SEd Maste export UNAME_r 3240d5c5243SEd Maste} 3250d5c5243SEd Maste 326c76da1f0SFaraz Vahedi# Get the Jail's path and the version of its installed userland 327c76da1f0SFaraz Vahediconfig_TargetJail () { 328c76da1f0SFaraz Vahedi JAIL=$1 329c76da1f0SFaraz Vahedi UNAME_r=$(freebsd-version -j ${JAIL}) 330c76da1f0SFaraz Vahedi BASEDIR=$(jls -j ${JAIL} -h path | awk 'NR == 2 {print}') 331c76da1f0SFaraz Vahedi if [ -z ${BASEDIR} ] || [ -z ${UNAME_r} ]; then 332c76da1f0SFaraz Vahedi echo "The specified jail either doesn't exist or" \ 333c76da1f0SFaraz Vahedi "does not have freebsd-version." 334c76da1f0SFaraz Vahedi exit 1 335c76da1f0SFaraz Vahedi fi 336c76da1f0SFaraz Vahedi export UNAME_r 337c76da1f0SFaraz Vahedi} 338c76da1f0SFaraz Vahedi 33948ffe56aSColin Percival# Define what happens to output of utilities 34048ffe56aSColin Percivalconfig_VerboseLevel () { 34148ffe56aSColin Percival if [ -z ${VERBOSELEVEL} ]; then 34248ffe56aSColin Percival case $1 in 34348ffe56aSColin Percival [Dd][Ee][Bb][Uu][Gg]) 34448ffe56aSColin Percival VERBOSELEVEL=debug 34548ffe56aSColin Percival ;; 34648ffe56aSColin Percival [Nn][Oo][Ss][Tt][Aa][Tt][Ss]) 34748ffe56aSColin Percival VERBOSELEVEL=nostats 34848ffe56aSColin Percival ;; 34948ffe56aSColin Percival [Ss][Tt][Aa][Tt][Ss]) 35048ffe56aSColin Percival VERBOSELEVEL=stats 35148ffe56aSColin Percival ;; 35248ffe56aSColin Percival *) 35348ffe56aSColin Percival return 1 35448ffe56aSColin Percival ;; 35548ffe56aSColin Percival esac 35648ffe56aSColin Percival else 35748ffe56aSColin Percival return 1 35848ffe56aSColin Percival fi 35948ffe56aSColin Percival} 36048ffe56aSColin Percival 36123d827efSSimon L. B. Nielsenconfig_BackupKernel () { 36223d827efSSimon L. B. Nielsen if [ -z ${BACKUPKERNEL} ]; then 36323d827efSSimon L. B. Nielsen case $1 in 36423d827efSSimon L. B. Nielsen [Yy][Ee][Ss]) 36523d827efSSimon L. B. Nielsen BACKUPKERNEL=yes 36623d827efSSimon L. B. Nielsen ;; 36723d827efSSimon L. B. Nielsen [Nn][Oo]) 36823d827efSSimon L. B. Nielsen BACKUPKERNEL=no 36923d827efSSimon L. B. Nielsen ;; 37023d827efSSimon L. B. Nielsen *) 37123d827efSSimon L. B. Nielsen return 1 37223d827efSSimon L. B. Nielsen ;; 37323d827efSSimon L. B. Nielsen esac 37423d827efSSimon L. B. Nielsen else 37523d827efSSimon L. B. Nielsen return 1 37623d827efSSimon L. B. Nielsen fi 37723d827efSSimon L. B. Nielsen} 37823d827efSSimon L. B. Nielsen 37923d827efSSimon L. B. Nielsenconfig_BackupKernelDir () { 38023d827efSSimon L. B. Nielsen if [ -z ${BACKUPKERNELDIR} ]; then 38123d827efSSimon L. B. Nielsen if [ -z "$1" ]; then 38223d827efSSimon L. B. Nielsen echo "BackupKernelDir set to empty dir" 38323d827efSSimon L. B. Nielsen return 1 38423d827efSSimon L. B. Nielsen fi 38523d827efSSimon L. B. Nielsen 38623d827efSSimon L. B. Nielsen # We check for some paths which would be extremely odd 38723d827efSSimon L. B. Nielsen # to use, but which could cause a lot of problems if 38823d827efSSimon L. B. Nielsen # used. 38923d827efSSimon L. B. Nielsen case $1 in 39023d827efSSimon L. B. Nielsen /|/bin|/boot|/etc|/lib|/libexec|/sbin|/usr|/var) 39123d827efSSimon L. B. Nielsen echo "BackupKernelDir set to invalid path $1" 39223d827efSSimon L. B. Nielsen return 1 39323d827efSSimon L. B. Nielsen ;; 39423d827efSSimon L. B. Nielsen /*) 39523d827efSSimon L. B. Nielsen BACKUPKERNELDIR=$1 39623d827efSSimon L. B. Nielsen ;; 39723d827efSSimon L. B. Nielsen *) 39823d827efSSimon L. B. Nielsen echo "BackupKernelDir ($1) is not an absolute path" 39923d827efSSimon L. B. Nielsen return 1 40023d827efSSimon L. B. Nielsen ;; 40123d827efSSimon L. B. Nielsen esac 40223d827efSSimon L. B. Nielsen else 40323d827efSSimon L. B. Nielsen return 1 40423d827efSSimon L. B. Nielsen fi 40523d827efSSimon L. B. Nielsen} 40623d827efSSimon L. B. Nielsen 40723d827efSSimon L. B. Nielsenconfig_BackupKernelSymbolFiles () { 40823d827efSSimon L. B. Nielsen if [ -z ${BACKUPKERNELSYMBOLFILES} ]; then 40923d827efSSimon L. B. Nielsen case $1 in 41023d827efSSimon L. B. Nielsen [Yy][Ee][Ss]) 41123d827efSSimon L. B. Nielsen BACKUPKERNELSYMBOLFILES=yes 41223d827efSSimon L. B. Nielsen ;; 41323d827efSSimon L. B. Nielsen [Nn][Oo]) 41423d827efSSimon L. B. Nielsen BACKUPKERNELSYMBOLFILES=no 41523d827efSSimon L. B. Nielsen ;; 41623d827efSSimon L. B. Nielsen *) 41723d827efSSimon L. B. Nielsen return 1 41823d827efSSimon L. B. Nielsen ;; 41923d827efSSimon L. B. Nielsen esac 42023d827efSSimon L. B. Nielsen else 42123d827efSSimon L. B. Nielsen return 1 42223d827efSSimon L. B. Nielsen fi 42323d827efSSimon L. B. Nielsen} 42423d827efSSimon L. B. Nielsen 425f28f1389SDave Fullardconfig_CreateBootEnv () { 426f28f1389SDave Fullard if [ -z ${BOOTENV} ]; then 427f28f1389SDave Fullard case $1 in 428f28f1389SDave Fullard [Yy][Ee][Ss]) 429f28f1389SDave Fullard BOOTENV=yes 430f28f1389SDave Fullard ;; 431f28f1389SDave Fullard [Nn][Oo]) 432f28f1389SDave Fullard BOOTENV=no 433f28f1389SDave Fullard ;; 434f28f1389SDave Fullard *) 435f28f1389SDave Fullard return 1 436f28f1389SDave Fullard ;; 437f28f1389SDave Fullard esac 438f28f1389SDave Fullard else 439f28f1389SDave Fullard return 1 440f28f1389SDave Fullard fi 441f28f1389SDave Fullard} 44248ffe56aSColin Percival# Handle one line of configuration 44348ffe56aSColin Percivalconfigline () { 44448ffe56aSColin Percival if [ $# -eq 0 ]; then 44548ffe56aSColin Percival return 44648ffe56aSColin Percival fi 44748ffe56aSColin Percival 44848ffe56aSColin Percival OPT=$1 44948ffe56aSColin Percival shift 45048ffe56aSColin Percival config_${OPT} $@ 45148ffe56aSColin Percival} 45248ffe56aSColin Percival 45348ffe56aSColin Percival#### Parameter handling functions. 45448ffe56aSColin Percival 45548ffe56aSColin Percival# Initialize parameters to null, just in case they're 45648ffe56aSColin Percival# set in the environment. 45748ffe56aSColin Percivalinit_params () { 45848ffe56aSColin Percival # Configration settings 45948ffe56aSColin Percival nullconfig 46048ffe56aSColin Percival 46148ffe56aSColin Percival # No configuration file set yet 46248ffe56aSColin Percival CONFFILE="" 46348ffe56aSColin Percival 46448ffe56aSColin Percival # No commands specified yet 46548ffe56aSColin Percival COMMANDS="" 4668935f242SAllan Jude 4678935f242SAllan Jude # Force fetch to proceed 4688935f242SAllan Jude FORCEFETCH=0 4698935f242SAllan Jude 4708935f242SAllan Jude # Run without a TTY 4718935f242SAllan Jude NOTTYOK=0 47233bd05c3SGuangyuan Yang 47333bd05c3SGuangyuan Yang # Fetched first in a chain of commands 47433bd05c3SGuangyuan Yang ISFETCHED=0 47548ffe56aSColin Percival} 47648ffe56aSColin Percival 47748ffe56aSColin Percival# Parse the command line 47848ffe56aSColin Percivalparse_cmdline () { 47948ffe56aSColin Percival while [ $# -gt 0 ]; do 48048ffe56aSColin Percival case "$1" in 48148ffe56aSColin Percival # Location of configuration file 48248ffe56aSColin Percival -f) 48348ffe56aSColin Percival if [ $# -eq 1 ]; then usage; fi 48448ffe56aSColin Percival if [ ! -z "${CONFFILE}" ]; then usage; fi 48548ffe56aSColin Percival shift; CONFFILE="$1" 48648ffe56aSColin Percival ;; 4878935f242SAllan Jude -F) 4888935f242SAllan Jude FORCEFETCH=1 4898935f242SAllan Jude ;; 4908935f242SAllan Jude --not-running-from-cron) 4918935f242SAllan Jude NOTTYOK=1 4928935f242SAllan Jude ;; 493b39ce43eSColin Percival --currently-running) 4940d5c5243SEd Maste shift 4950d5c5243SEd Maste config_SourceRelease $1 || usage 496b39ce43eSColin Percival ;; 49748ffe56aSColin Percival 49848ffe56aSColin Percival # Configuration file equivalents 49948ffe56aSColin Percival -b) 50048ffe56aSColin Percival if [ $# -eq 1 ]; then usage; fi; shift 50148ffe56aSColin Percival config_BaseDir $1 || usage 50248ffe56aSColin Percival ;; 50348ffe56aSColin Percival -d) 50448ffe56aSColin Percival if [ $# -eq 1 ]; then usage; fi; shift 50548ffe56aSColin Percival config_WorkDir $1 || usage 50648ffe56aSColin Percival ;; 507c76da1f0SFaraz Vahedi -j) 508c76da1f0SFaraz Vahedi if [ $# -eq 1 ]; then usage; fi; shift 509c76da1f0SFaraz Vahedi config_TargetJail $1 || usage 510c76da1f0SFaraz Vahedi ;; 51148ffe56aSColin Percival -k) 51248ffe56aSColin Percival if [ $# -eq 1 ]; then usage; fi; shift 51348ffe56aSColin Percival config_KeyPrint $1 || usage 51448ffe56aSColin Percival ;; 51548ffe56aSColin Percival -s) 51648ffe56aSColin Percival if [ $# -eq 1 ]; then usage; fi; shift 51748ffe56aSColin Percival config_ServerName $1 || usage 51848ffe56aSColin Percival ;; 519db6b0a61SColin Percival -r) 520db6b0a61SColin Percival if [ $# -eq 1 ]; then usage; fi; shift 521db6b0a61SColin Percival config_TargetRelease $1 || usage 522db6b0a61SColin Percival ;; 52348ffe56aSColin Percival -t) 52448ffe56aSColin Percival if [ $# -eq 1 ]; then usage; fi; shift 52548ffe56aSColin Percival config_MailTo $1 || usage 52648ffe56aSColin Percival ;; 52748ffe56aSColin Percival -v) 52848ffe56aSColin Percival if [ $# -eq 1 ]; then usage; fi; shift 52948ffe56aSColin Percival config_VerboseLevel $1 || usage 53048ffe56aSColin Percival ;; 53148ffe56aSColin Percival 53248ffe56aSColin Percival # Aliases for "-v debug" and "-v nostats" 53348ffe56aSColin Percival --debug) 53448ffe56aSColin Percival config_VerboseLevel debug || usage 53548ffe56aSColin Percival ;; 53648ffe56aSColin Percival --no-stats) 53748ffe56aSColin Percival config_VerboseLevel nostats || usage 53848ffe56aSColin Percival ;; 53948ffe56aSColin Percival 54048ffe56aSColin Percival # Commands 5418cfda118SMichael Gmelin cron | fetch | upgrade | updatesready | install | rollback |\ 5428cfda118SMichael Gmelin IDS | showconfig) 54348ffe56aSColin Percival COMMANDS="${COMMANDS} $1" 54448ffe56aSColin Percival ;; 54548ffe56aSColin Percival 54648ffe56aSColin Percival # Anything else is an error 54748ffe56aSColin Percival *) 54848ffe56aSColin Percival usage 54948ffe56aSColin Percival ;; 55048ffe56aSColin Percival esac 55148ffe56aSColin Percival shift 55248ffe56aSColin Percival done 55348ffe56aSColin Percival 55448ffe56aSColin Percival # Make sure we have at least one command 55548ffe56aSColin Percival if [ -z "${COMMANDS}" ]; then 55648ffe56aSColin Percival usage 55748ffe56aSColin Percival fi 55848ffe56aSColin Percival} 55948ffe56aSColin Percival 56048ffe56aSColin Percival# Parse the configuration file 56148ffe56aSColin Percivalparse_conffile () { 56248ffe56aSColin Percival # If a configuration file was specified on the command line, check 56348ffe56aSColin Percival # that it exists and is readable. 56448ffe56aSColin Percival if [ ! -z "${CONFFILE}" ] && [ ! -r "${CONFFILE}" ]; then 56548ffe56aSColin Percival echo -n "File does not exist " 56648ffe56aSColin Percival echo -n "or is not readable: " 56748ffe56aSColin Percival echo ${CONFFILE} 56848ffe56aSColin Percival exit 1 56948ffe56aSColin Percival fi 57048ffe56aSColin Percival 57148ffe56aSColin Percival # If a configuration file was not specified on the command line, 57248ffe56aSColin Percival # use the default configuration file path. If that default does 57348ffe56aSColin Percival # not exist, give up looking for any configuration. 57448ffe56aSColin Percival if [ -z "${CONFFILE}" ]; then 57548ffe56aSColin Percival CONFFILE="/etc/freebsd-update.conf" 57648ffe56aSColin Percival if [ ! -r "${CONFFILE}" ]; then 57748ffe56aSColin Percival return 57848ffe56aSColin Percival fi 57948ffe56aSColin Percival fi 58048ffe56aSColin Percival 58148ffe56aSColin Percival # Save the configuration options specified on the command line, and 58248ffe56aSColin Percival # clear all the options in preparation for reading the config file. 58348ffe56aSColin Percival saveconfig 58448ffe56aSColin Percival nullconfig 58548ffe56aSColin Percival 58648ffe56aSColin Percival # Read the configuration file. Anything after the first '#' is 58748ffe56aSColin Percival # ignored, and any blank lines are ignored. 58848ffe56aSColin Percival L=0 58948ffe56aSColin Percival while read LINE; do 59048ffe56aSColin Percival L=$(($L + 1)) 59148ffe56aSColin Percival LINEX=`echo "${LINE}" | cut -f 1 -d '#'` 59248ffe56aSColin Percival if ! configline ${LINEX}; then 59348ffe56aSColin Percival echo "Error processing configuration file, line $L:" 59448ffe56aSColin Percival echo "==> ${LINE}" 59548ffe56aSColin Percival exit 1 59648ffe56aSColin Percival fi 59748ffe56aSColin Percival done < ${CONFFILE} 59848ffe56aSColin Percival 59948ffe56aSColin Percival # Merge the settings read from the configuration file with those 60048ffe56aSColin Percival # provided at the command line. 60148ffe56aSColin Percival mergeconfig 60248ffe56aSColin Percival} 60348ffe56aSColin Percival 60448ffe56aSColin Percival# Provide some default parameters 60548ffe56aSColin Percivaldefault_params () { 60648ffe56aSColin Percival # Save any parameters already configured, and clear the slate 60748ffe56aSColin Percival saveconfig 60848ffe56aSColin Percival nullconfig 60948ffe56aSColin Percival 61048ffe56aSColin Percival # Default configurations 61148ffe56aSColin Percival config_WorkDir /var/db/freebsd-update 61248ffe56aSColin Percival config_MailTo root 61348ffe56aSColin Percival config_AllowAdd yes 61448ffe56aSColin Percival config_AllowDelete yes 61548ffe56aSColin Percival config_KeepModifiedMetadata yes 61648ffe56aSColin Percival config_BaseDir / 61748ffe56aSColin Percival config_VerboseLevel stats 618db6b0a61SColin Percival config_StrictComponents no 61923d827efSSimon L. B. Nielsen config_BackupKernel yes 62023d827efSSimon L. B. Nielsen config_BackupKernelDir /boot/kernel.old 62123d827efSSimon L. B. Nielsen config_BackupKernelSymbolFiles no 622f28f1389SDave Fullard config_CreateBootEnv yes 62348ffe56aSColin Percival 62448ffe56aSColin Percival # Merge these defaults into the earlier-configured settings 62548ffe56aSColin Percival mergeconfig 62648ffe56aSColin Percival} 62748ffe56aSColin Percival 62848ffe56aSColin Percival# Set utility output filtering options, based on ${VERBOSELEVEL} 62948ffe56aSColin Percivalfetch_setup_verboselevel () { 63048ffe56aSColin Percival case ${VERBOSELEVEL} in 63148ffe56aSColin Percival debug) 63248ffe56aSColin Percival QUIETREDIR="/dev/stderr" 63348ffe56aSColin Percival QUIETFLAG=" " 63448ffe56aSColin Percival STATSREDIR="/dev/stderr" 63548ffe56aSColin Percival DDSTATS=".." 63648ffe56aSColin Percival XARGST="-t" 63748ffe56aSColin Percival NDEBUG=" " 63848ffe56aSColin Percival ;; 63948ffe56aSColin Percival nostats) 64048ffe56aSColin Percival QUIETREDIR="" 64148ffe56aSColin Percival QUIETFLAG="" 64248ffe56aSColin Percival STATSREDIR="/dev/null" 64348ffe56aSColin Percival DDSTATS=".." 64448ffe56aSColin Percival XARGST="" 64548ffe56aSColin Percival NDEBUG="" 64648ffe56aSColin Percival ;; 64748ffe56aSColin Percival stats) 64848ffe56aSColin Percival QUIETREDIR="/dev/null" 64948ffe56aSColin Percival QUIETFLAG="-q" 65048ffe56aSColin Percival STATSREDIR="/dev/stdout" 65148ffe56aSColin Percival DDSTATS="" 65248ffe56aSColin Percival XARGST="" 65348ffe56aSColin Percival NDEBUG="-n" 65448ffe56aSColin Percival ;; 65548ffe56aSColin Percival esac 65648ffe56aSColin Percival} 65748ffe56aSColin Percival 658bc0c6c9cSFernando Apesteguía# Check if there are any kernel modules installed from ports. 659bc0c6c9cSFernando Apesteguía# In that case warn the user that a rebuild from ports (i.e. not from 660bc0c6c9cSFernando Apesteguía# packages) might need necessary for the modules to work in the new release. 661bc0c6c9cSFernando Apesteguíaupgrade_check_kmod_ports() { 662bc0c6c9cSFernando Apesteguía local mod_name 663bc0c6c9cSFernando Apesteguía local modules 664bc0c6c9cSFernando Apesteguía local pattern 665bc0c6c9cSFernando Apesteguía local pkg_name 666bc0c6c9cSFernando Apesteguía local port_name 667bc0c6c9cSFernando Apesteguía local report 668bc0c6c9cSFernando Apesteguía local w 669bc0c6c9cSFernando Apesteguía 670d76ef58dSZhenlei Huang if ! pkg -N 2>/dev/null; then 671bc0c6c9cSFernando Apesteguía echo "Skipping kernel modules check. pkg(8) not present." 672bc0c6c9cSFernando Apesteguía return 673bc0c6c9cSFernando Apesteguía fi 674bc0c6c9cSFernando Apesteguía 675bc0c6c9cSFernando Apesteguía # Most modules are in /boot/modules but we should actually look 676d3b6d70eSFernando Apesteguía # in every module_path passed to the kernel: 677d3b6d70eSFernando Apesteguía pattern=$(sysctl -n kern.module_path | tr ";" "|") 678bc0c6c9cSFernando Apesteguía 679bc0c6c9cSFernando Apesteguía if [ -z "${pattern}" ]; then 680d3b6d70eSFernando Apesteguía echo "Empty kern.module_path sysctl. This should not happen." 681d3b6d70eSFernando Apesteguía echo "Aborting check of kernel modules installed from ports." 682d3b6d70eSFernando Apesteguía return 683bc0c6c9cSFernando Apesteguía fi 684bc0c6c9cSFernando Apesteguía 685bc0c6c9cSFernando Apesteguía # Check the pkg database for modules installed in those directories 686bc0c6c9cSFernando Apesteguía modules=$(pkg query '%Fp' | grep -E "${pattern}") 687bc0c6c9cSFernando Apesteguía 688bc0c6c9cSFernando Apesteguía if [ -z "${modules}" ]; then 689bc0c6c9cSFernando Apesteguía return 690bc0c6c9cSFernando Apesteguía fi 691bc0c6c9cSFernando Apesteguía 692bc0c6c9cSFernando Apesteguía echo -e "\n" 693bc0c6c9cSFernando Apesteguía echo "The following modules have been installed from packages." 694bc0c6c9cSFernando Apesteguía echo "As a consequence they might not work when performing a major or minor upgrade." 695bc0c6c9cSFernando Apesteguía echo -e "It is advised to rebuild these ports:\n" 696bc0c6c9cSFernando Apesteguía 697bc0c6c9cSFernando Apesteguía 698bc0c6c9cSFernando Apesteguía report="Module Package Port\n------ ------- ----\n" 699bc0c6c9cSFernando Apesteguía for module in ${modules}; do 700bc0c6c9cSFernando Apesteguía w=$(pkg which "${module}") 701bc0c6c9cSFernando Apesteguía mod_name=$(echo "${w}" | awk '{print $1;}') 702bc0c6c9cSFernando Apesteguía pkg_name=$(echo "${w}" | awk '{print $6;}') 703bc0c6c9cSFernando Apesteguía port_name=$(pkg info -o "${pkg_name}" | awk '{print $2;}') 704bc0c6c9cSFernando Apesteguía report="${report}${mod_name} ${pkg_name} ${port_name}\n" 705bc0c6c9cSFernando Apesteguía done 706bc0c6c9cSFernando Apesteguía 707bc0c6c9cSFernando Apesteguía echo -e "${report}" | column -t 708bc0c6c9cSFernando Apesteguía echo -e "\n" 709bc0c6c9cSFernando Apesteguía} 710bc0c6c9cSFernando Apesteguía 71148ffe56aSColin Percival# Perform sanity checks and set some final parameters 71248ffe56aSColin Percival# in preparation for fetching files. Figure out which 71348ffe56aSColin Percival# set of updates should be downloaded: If the user is 71448ffe56aSColin Percival# running *-p[0-9]+, strip off the last part; if the 71548ffe56aSColin Percival# user is running -SECURITY, call it -RELEASE. Chdir 71648ffe56aSColin Percival# into the working directory. 717211f2ba0SColin Percivalfetchupgrade_check_params () { 71848ffe56aSColin Percival export HTTP_USER_AGENT="freebsd-update (${COMMAND}, `uname -r`)" 71948ffe56aSColin Percival 72048ffe56aSColin Percival _SERVERNAME_z=\ 72148ffe56aSColin Percival"SERVERNAME must be given via command line or configuration file." 72248ffe56aSColin Percival _KEYPRINT_z="Key must be given via -k option or configuration file." 72348ffe56aSColin Percival _KEYPRINT_bad="Invalid key fingerprint: " 72448ffe56aSColin Percival _WORKDIR_bad="Directory does not exist or is not writable: " 725f88076f0SMark Felder _WORKDIR_bad2="Directory is not on a persistent filesystem: " 72648ffe56aSColin Percival 72748ffe56aSColin Percival if [ -z "${SERVERNAME}" ]; then 72848ffe56aSColin Percival echo -n "`basename $0`: " 72948ffe56aSColin Percival echo "${_SERVERNAME_z}" 73048ffe56aSColin Percival exit 1 73148ffe56aSColin Percival fi 73248ffe56aSColin Percival if [ -z "${KEYPRINT}" ]; then 73348ffe56aSColin Percival echo -n "`basename $0`: " 73448ffe56aSColin Percival echo "${_KEYPRINT_z}" 73548ffe56aSColin Percival exit 1 73648ffe56aSColin Percival fi 73748ffe56aSColin Percival if ! echo "${KEYPRINT}" | grep -qE "^[0-9a-f]{64}$"; then 73848ffe56aSColin Percival echo -n "`basename $0`: " 73948ffe56aSColin Percival echo -n "${_KEYPRINT_bad}" 74048ffe56aSColin Percival echo ${KEYPRINT} 74148ffe56aSColin Percival exit 1 74248ffe56aSColin Percival fi 74348ffe56aSColin Percival if ! [ -d "${WORKDIR}" -a -w "${WORKDIR}" ]; then 74448ffe56aSColin Percival echo -n "`basename $0`: " 74548ffe56aSColin Percival echo -n "${_WORKDIR_bad}" 74648ffe56aSColin Percival echo ${WORKDIR} 74748ffe56aSColin Percival exit 1 74848ffe56aSColin Percival fi 749dfe9215bSMark Felder case `df -T ${WORKDIR}` in */dev/md[0-9]* | *tmpfs*) 750f88076f0SMark Felder echo -n "`basename $0`: " 751f88076f0SMark Felder echo -n "${_WORKDIR_bad2}" 752f88076f0SMark Felder echo ${WORKDIR} 753f88076f0SMark Felder exit 1 754dfe9215bSMark Felder ;; 755dfe9215bSMark Felder esac 756a2356430SColin Percival chmod 700 ${WORKDIR} 75748ffe56aSColin Percival cd ${WORKDIR} || exit 1 75848ffe56aSColin Percival 75948ffe56aSColin Percival # Generate release number. The s/SECURITY/RELEASE/ bit exists 76048ffe56aSColin Percival # to provide an upgrade path for FreeBSD Update 1.x users, since 76148ffe56aSColin Percival # the kernels provided by FreeBSD Update 1.x are always labelled 76248ffe56aSColin Percival # as X.Y-SECURITY. 76348ffe56aSColin Percival RELNUM=`uname -r | 76448ffe56aSColin Percival sed -E 's,-p[0-9]+,,' | 76548ffe56aSColin Percival sed -E 's,-SECURITY,-RELEASE,'` 76648ffe56aSColin Percival ARCH=`uname -m` 76748ffe56aSColin Percival FETCHDIR=${RELNUM}/${ARCH} 768db6b0a61SColin Percival PATCHDIR=${RELNUM}/${ARCH}/bp 76948ffe56aSColin Percival 770d308a8bfSEd Maste # Disallow upgrade from a version that is not a release 771d308a8bfSEd Maste case ${RELNUM} in 772d308a8bfSEd Maste *-RELEASE | *-ALPHA* | *-BETA* | *-RC*) 773d308a8bfSEd Maste ;; 774d308a8bfSEd Maste *) 7750d5c5243SEd Maste echo -n "`basename $0`: " 7760d5c5243SEd Maste cat <<- EOF 777d308a8bfSEd Maste Cannot upgrade from a version that is not a release 778d308a8bfSEd Maste (including alpha, beta and release candidates) 779d308a8bfSEd Maste using `basename $0`. Instead, FreeBSD can be directly 780d308a8bfSEd Maste upgraded by source or upgraded to a RELEASE/RELENG version 781d308a8bfSEd Maste prior to running `basename $0`. 782d308a8bfSEd Maste Currently running: ${RELNUM} 7830d5c5243SEd Maste EOF 7840d5c5243SEd Maste exit 1 785d308a8bfSEd Maste ;; 786d308a8bfSEd Maste esac 7870d5c5243SEd Maste 78848ffe56aSColin Percival # Figure out what directory contains the running kernel 78948ffe56aSColin Percival BOOTFILE=`sysctl -n kern.bootfile` 79048ffe56aSColin Percival KERNELDIR=${BOOTFILE%/kernel} 79148ffe56aSColin Percival if ! [ -d ${KERNELDIR} ]; then 79248ffe56aSColin Percival echo "Cannot identify running kernel" 79348ffe56aSColin Percival exit 1 79448ffe56aSColin Percival fi 79548ffe56aSColin Percival 7962c434b2cSColin Percival # Figure out what kernel configuration is running. We start with 7972c434b2cSColin Percival # the output of `uname -i`, and then make the following adjustments: 7982c434b2cSColin Percival # 1. Replace "SMP-GENERIC" with "SMP". Why the SMP kernel config 7992c434b2cSColin Percival # file says "ident SMP-GENERIC", I don't know... 8002c434b2cSColin Percival # 2. If the kernel claims to be GENERIC _and_ ${ARCH} is "amd64" 8012c434b2cSColin Percival # _and_ `sysctl kern.version` contains a line which ends "/SMP", then 8022c434b2cSColin Percival # we're running an SMP kernel. This mis-identification is a bug 8032c434b2cSColin Percival # which was fixed in 6.2-STABLE. 8042c434b2cSColin Percival KERNCONF=`uname -i` 8052c434b2cSColin Percival if [ ${KERNCONF} = "SMP-GENERIC" ]; then 8062c434b2cSColin Percival KERNCONF=SMP 8072c434b2cSColin Percival fi 8082c434b2cSColin Percival if [ ${KERNCONF} = "GENERIC" ] && [ ${ARCH} = "amd64" ]; then 8092c434b2cSColin Percival if sysctl kern.version | grep -qE '/SMP$'; then 8102c434b2cSColin Percival KERNCONF=SMP 8112c434b2cSColin Percival fi 8122c434b2cSColin Percival fi 8132c434b2cSColin Percival 81448ffe56aSColin Percival # Define some paths 81548ffe56aSColin Percival BSPATCH=/usr/bin/bspatch 81648ffe56aSColin Percival SHA256=/sbin/sha256 81748ffe56aSColin Percival PHTTPGET=/usr/libexec/phttpget 81848ffe56aSColin Percival 81948ffe56aSColin Percival # Set up variables relating to VERBOSELEVEL 82048ffe56aSColin Percival fetch_setup_verboselevel 82148ffe56aSColin Percival 82248ffe56aSColin Percival # Construct a unique name from ${BASEDIR} 82348ffe56aSColin Percival BDHASH=`echo ${BASEDIR} | sha256 -q` 82448ffe56aSColin Percival} 82548ffe56aSColin Percival 826211f2ba0SColin Percival# Perform sanity checks etc. before fetching updates. 827211f2ba0SColin Percivalfetch_check_params () { 828211f2ba0SColin Percival fetchupgrade_check_params 829211f2ba0SColin Percival 830211f2ba0SColin Percival if ! [ -z "${TARGETRELEASE}" ]; then 831211f2ba0SColin Percival echo -n "`basename $0`: " 83259b02bb4SMichael Osipov echo -n "'-r' option is meaningless with 'fetch' command. " 833211f2ba0SColin Percival echo "(Did you mean 'upgrade' instead?)" 834211f2ba0SColin Percival exit 1 835211f2ba0SColin Percival fi 8368935f242SAllan Jude 8378935f242SAllan Jude # Check that we have updates ready to install 8388bf2dcceSAllan Jude if [ -f ${BDHASH}-install/kerneldone -a $FORCEFETCH -eq 0 ]; then 8398935f242SAllan Jude echo "You have a partially completed upgrade pending" 84059b02bb4SMichael Osipov echo "Run '`basename $0` [options] install' first." 84159b02bb4SMichael Osipov echo "Run '`basename $0` [options] fetch -F' to proceed anyway." 8428935f242SAllan Jude exit 1 8438935f242SAllan Jude fi 844211f2ba0SColin Percival} 845211f2ba0SColin Percival 846db6b0a61SColin Percival# Perform sanity checks etc. before fetching upgrades. 847db6b0a61SColin Percivalupgrade_check_params () { 848211f2ba0SColin Percival fetchupgrade_check_params 849db6b0a61SColin Percival 850db6b0a61SColin Percival # Unless set otherwise, we're upgrading to the same kernel config. 851db6b0a61SColin Percival NKERNCONF=${KERNCONF} 852db6b0a61SColin Percival 853db6b0a61SColin Percival # We need TARGETRELEASE set 85459b02bb4SMichael Osipov _TARGETRELEASE_z="Release target must be specified via '-r' option." 855db6b0a61SColin Percival if [ -z "${TARGETRELEASE}" ]; then 856db6b0a61SColin Percival echo -n "`basename $0`: " 857db6b0a61SColin Percival echo "${_TARGETRELEASE_z}" 858db6b0a61SColin Percival exit 1 859db6b0a61SColin Percival fi 860db6b0a61SColin Percival 861db6b0a61SColin Percival # The target release should be != the current release. 862db6b0a61SColin Percival if [ "${TARGETRELEASE}" = "${RELNUM}" ]; then 863db6b0a61SColin Percival echo -n "`basename $0`: " 864db6b0a61SColin Percival echo "Cannot upgrade from ${RELNUM} to itself" 865db6b0a61SColin Percival exit 1 866db6b0a61SColin Percival fi 867db6b0a61SColin Percival 868db6b0a61SColin Percival # Turning off AllowAdd or AllowDelete is a bad idea for upgrades. 869db6b0a61SColin Percival if [ "${ALLOWADD}" = "no" ]; then 870db6b0a61SColin Percival echo -n "`basename $0`: " 871db6b0a61SColin Percival echo -n "WARNING: \"AllowAdd no\" is a bad idea " 872db6b0a61SColin Percival echo "when upgrading between releases." 873db6b0a61SColin Percival echo 874db6b0a61SColin Percival fi 875db6b0a61SColin Percival if [ "${ALLOWDELETE}" = "no" ]; then 876db6b0a61SColin Percival echo -n "`basename $0`: " 877db6b0a61SColin Percival echo -n "WARNING: \"AllowDelete no\" is a bad idea " 878db6b0a61SColin Percival echo "when upgrading between releases." 879db6b0a61SColin Percival echo 880db6b0a61SColin Percival fi 881db6b0a61SColin Percival 882db6b0a61SColin Percival # Set EDITOR to /usr/bin/vi if it isn't already set 883db6b0a61SColin Percival : ${EDITOR:='/usr/bin/vi'} 884db6b0a61SColin Percival} 885db6b0a61SColin Percival 88648ffe56aSColin Percival# Perform sanity checks and set some final parameters in 88748ffe56aSColin Percival# preparation for installing updates. 88848ffe56aSColin Percivalinstall_check_params () { 88948ffe56aSColin Percival # Check that we are root. All sorts of things won't work otherwise. 89048ffe56aSColin Percival if [ `id -u` != 0 ]; then 89148ffe56aSColin Percival echo "You must be root to run this." 89248ffe56aSColin Percival exit 1 89348ffe56aSColin Percival fi 89448ffe56aSColin Percival 8952328d598SColin Percival # Check that securelevel <= 0. Otherwise we can't update schg files. 8962328d598SColin Percival if [ `sysctl -n kern.securelevel` -gt 0 ]; then 8972328d598SColin Percival echo "Updates cannot be installed when the system securelevel" 8982328d598SColin Percival echo "is greater than zero." 8992328d598SColin Percival exit 1 9002328d598SColin Percival fi 9012328d598SColin Percival 90248ffe56aSColin Percival # Check that we have a working directory 90348ffe56aSColin Percival _WORKDIR_bad="Directory does not exist or is not writable: " 90448ffe56aSColin Percival if ! [ -d "${WORKDIR}" -a -w "${WORKDIR}" ]; then 90548ffe56aSColin Percival echo -n "`basename $0`: " 90648ffe56aSColin Percival echo -n "${_WORKDIR_bad}" 90748ffe56aSColin Percival echo ${WORKDIR} 90848ffe56aSColin Percival exit 1 90948ffe56aSColin Percival fi 91048ffe56aSColin Percival cd ${WORKDIR} || exit 1 91148ffe56aSColin Percival 91248ffe56aSColin Percival # Construct a unique name from ${BASEDIR} 91348ffe56aSColin Percival BDHASH=`echo ${BASEDIR} | sha256 -q` 91448ffe56aSColin Percival 91548ffe56aSColin Percival # Check that we have updates ready to install 91648ffe56aSColin Percival if ! [ -L ${BDHASH}-install ]; then 91748ffe56aSColin Percival echo "No updates are available to install." 91833bd05c3SGuangyuan Yang if [ $ISFETCHED -eq 0 ]; then 91959b02bb4SMichael Osipov echo "Run '`basename $0` [options] fetch' first." 9208cfda118SMichael Gmelin exit 2 92133bd05c3SGuangyuan Yang fi 92233bd05c3SGuangyuan Yang exit 0 92348ffe56aSColin Percival fi 92448ffe56aSColin Percival if ! [ -f ${BDHASH}-install/INDEX-OLD ] || 92548ffe56aSColin Percival ! [ -f ${BDHASH}-install/INDEX-NEW ]; then 92648ffe56aSColin Percival echo "Update manifest is corrupt -- this should never happen." 92759b02bb4SMichael Osipov echo "Re-run '`basename $0` [options] fetch'." 92848ffe56aSColin Percival exit 1 92948ffe56aSColin Percival fi 93023d827efSSimon L. B. Nielsen 93123d827efSSimon L. B. Nielsen # Figure out what directory contains the running kernel 93223d827efSSimon L. B. Nielsen BOOTFILE=`sysctl -n kern.bootfile` 93323d827efSSimon L. B. Nielsen KERNELDIR=${BOOTFILE%/kernel} 93423d827efSSimon L. B. Nielsen if ! [ -d ${KERNELDIR} ]; then 93523d827efSSimon L. B. Nielsen echo "Cannot identify running kernel" 93623d827efSSimon L. B. Nielsen exit 1 93723d827efSSimon L. B. Nielsen fi 93848ffe56aSColin Percival} 93948ffe56aSColin Percival 940f28f1389SDave Fullard# Creates a new boot environment 941f28f1389SDave Fullardinstall_create_be () { 942f28f1389SDave Fullard # Figure out if we're running in a jail and return if we are 943f28f1389SDave Fullard if [ `sysctl -n security.jail.jailed` = 1 ]; then 944f28f1389SDave Fullard return 1 945f28f1389SDave Fullard fi 946e01e8f91SKyle Evans # Operating on roots that aren't located at / will, more often than not, 947e01e8f91SKyle Evans # not touch the boot environment. 948e01e8f91SKyle Evans if [ "$BASEDIR" != "/" ]; then 949e01e8f91SKyle Evans return 1 950e01e8f91SKyle Evans fi 951f28f1389SDave Fullard # Create a boot environment if enabled 952f28f1389SDave Fullard if [ ${BOOTENV} = yes ]; then 953f28f1389SDave Fullard bectl check 2>/dev/null 954f28f1389SDave Fullard case $? in 955f28f1389SDave Fullard 0) 956f28f1389SDave Fullard # Boot environment are supported 957f28f1389SDave Fullard CREATEBE=yes 958f28f1389SDave Fullard ;; 959f28f1389SDave Fullard 255) 960f28f1389SDave Fullard # Boot environments are not supported 961f28f1389SDave Fullard CREATEBE=no 962f28f1389SDave Fullard ;; 963f28f1389SDave Fullard *) 964f28f1389SDave Fullard # If bectl returns an unexpected exit code, don't create a BE 965f28f1389SDave Fullard CREATEBE=no 966f28f1389SDave Fullard ;; 967f28f1389SDave Fullard esac 968f28f1389SDave Fullard if [ ${CREATEBE} = yes ]; then 969f28f1389SDave Fullard echo -n "Creating snapshot of existing boot environment... " 970e01e8f91SKyle Evans VERSION=`freebsd-version -ku | sort -V | tail -n 1` 971f28f1389SDave Fullard TIMESTAMP=`date +"%Y-%m-%d_%H%M%S"` 972989c5f6dSKyle Evans bectl create -r ${VERSION}_${TIMESTAMP} 973f28f1389SDave Fullard if [ $? -eq 0 ]; then 974f28f1389SDave Fullard echo "done."; 975f28f1389SDave Fullard else 976f28f1389SDave Fullard echo "failed." 977f28f1389SDave Fullard exit 1 978f28f1389SDave Fullard fi 979f28f1389SDave Fullard fi 980f28f1389SDave Fullard fi 981f28f1389SDave Fullard} 982f28f1389SDave Fullard 98348ffe56aSColin Percival# Perform sanity checks and set some final parameters in 98448ffe56aSColin Percival# preparation for UNinstalling updates. 98548ffe56aSColin Percivalrollback_check_params () { 98648ffe56aSColin Percival # Check that we are root. All sorts of things won't work otherwise. 98748ffe56aSColin Percival if [ `id -u` != 0 ]; then 98848ffe56aSColin Percival echo "You must be root to run this." 98948ffe56aSColin Percival exit 1 99048ffe56aSColin Percival fi 99148ffe56aSColin Percival 99248ffe56aSColin Percival # Check that we have a working directory 99348ffe56aSColin Percival _WORKDIR_bad="Directory does not exist or is not writable: " 99448ffe56aSColin Percival if ! [ -d "${WORKDIR}" -a -w "${WORKDIR}" ]; then 99548ffe56aSColin Percival echo -n "`basename $0`: " 99648ffe56aSColin Percival echo -n "${_WORKDIR_bad}" 99748ffe56aSColin Percival echo ${WORKDIR} 99848ffe56aSColin Percival exit 1 99948ffe56aSColin Percival fi 100048ffe56aSColin Percival cd ${WORKDIR} || exit 1 100148ffe56aSColin Percival 100248ffe56aSColin Percival # Construct a unique name from ${BASEDIR} 100348ffe56aSColin Percival BDHASH=`echo ${BASEDIR} | sha256 -q` 100448ffe56aSColin Percival 100548ffe56aSColin Percival # Check that we have updates ready to rollback 100648ffe56aSColin Percival if ! [ -L ${BDHASH}-rollback ]; then 100748ffe56aSColin Percival echo "No rollback directory found." 100848ffe56aSColin Percival exit 1 100948ffe56aSColin Percival fi 101048ffe56aSColin Percival if ! [ -f ${BDHASH}-rollback/INDEX-OLD ] || 101148ffe56aSColin Percival ! [ -f ${BDHASH}-rollback/INDEX-NEW ]; then 101248ffe56aSColin Percival echo "Update manifest is corrupt -- this should never happen." 101348ffe56aSColin Percival exit 1 101448ffe56aSColin Percival fi 101548ffe56aSColin Percival} 101648ffe56aSColin Percival 101708e23beeSColin Percival# Perform sanity checks and set some final parameters 101808e23beeSColin Percival# in preparation for comparing the system against the 101908e23beeSColin Percival# published index. Figure out which index we should 102008e23beeSColin Percival# compare against: If the user is running *-p[0-9]+, 102108e23beeSColin Percival# strip off the last part; if the user is running 102208e23beeSColin Percival# -SECURITY, call it -RELEASE. Chdir into the working 102308e23beeSColin Percival# directory. 102408e23beeSColin PercivalIDS_check_params () { 102508e23beeSColin Percival export HTTP_USER_AGENT="freebsd-update (${COMMAND}, `uname -r`)" 102608e23beeSColin Percival 102708e23beeSColin Percival _SERVERNAME_z=\ 102808e23beeSColin Percival"SERVERNAME must be given via command line or configuration file." 102959b02bb4SMichael Osipov _KEYPRINT_z="Key must be given via '-k' option or configuration file." 103008e23beeSColin Percival _KEYPRINT_bad="Invalid key fingerprint: " 103108e23beeSColin Percival _WORKDIR_bad="Directory does not exist or is not writable: " 103208e23beeSColin Percival 103308e23beeSColin Percival if [ -z "${SERVERNAME}" ]; then 103408e23beeSColin Percival echo -n "`basename $0`: " 103508e23beeSColin Percival echo "${_SERVERNAME_z}" 103608e23beeSColin Percival exit 1 103708e23beeSColin Percival fi 103808e23beeSColin Percival if [ -z "${KEYPRINT}" ]; then 103908e23beeSColin Percival echo -n "`basename $0`: " 104008e23beeSColin Percival echo "${_KEYPRINT_z}" 104108e23beeSColin Percival exit 1 104208e23beeSColin Percival fi 104308e23beeSColin Percival if ! echo "${KEYPRINT}" | grep -qE "^[0-9a-f]{64}$"; then 104408e23beeSColin Percival echo -n "`basename $0`: " 104508e23beeSColin Percival echo -n "${_KEYPRINT_bad}" 104608e23beeSColin Percival echo ${KEYPRINT} 104708e23beeSColin Percival exit 1 104808e23beeSColin Percival fi 104908e23beeSColin Percival if ! [ -d "${WORKDIR}" -a -w "${WORKDIR}" ]; then 105008e23beeSColin Percival echo -n "`basename $0`: " 105108e23beeSColin Percival echo -n "${_WORKDIR_bad}" 105208e23beeSColin Percival echo ${WORKDIR} 105308e23beeSColin Percival exit 1 105408e23beeSColin Percival fi 105508e23beeSColin Percival cd ${WORKDIR} || exit 1 105608e23beeSColin Percival 105708e23beeSColin Percival # Generate release number. The s/SECURITY/RELEASE/ bit exists 105808e23beeSColin Percival # to provide an upgrade path for FreeBSD Update 1.x users, since 105908e23beeSColin Percival # the kernels provided by FreeBSD Update 1.x are always labelled 106008e23beeSColin Percival # as X.Y-SECURITY. 106108e23beeSColin Percival RELNUM=`uname -r | 106208e23beeSColin Percival sed -E 's,-p[0-9]+,,' | 106308e23beeSColin Percival sed -E 's,-SECURITY,-RELEASE,'` 106408e23beeSColin Percival ARCH=`uname -m` 106508e23beeSColin Percival FETCHDIR=${RELNUM}/${ARCH} 106608e23beeSColin Percival PATCHDIR=${RELNUM}/${ARCH}/bp 106708e23beeSColin Percival 106808e23beeSColin Percival # Figure out what directory contains the running kernel 106908e23beeSColin Percival BOOTFILE=`sysctl -n kern.bootfile` 107008e23beeSColin Percival KERNELDIR=${BOOTFILE%/kernel} 107108e23beeSColin Percival if ! [ -d ${KERNELDIR} ]; then 107208e23beeSColin Percival echo "Cannot identify running kernel" 107308e23beeSColin Percival exit 1 107408e23beeSColin Percival fi 107508e23beeSColin Percival 107608e23beeSColin Percival # Figure out what kernel configuration is running. We start with 107708e23beeSColin Percival # the output of `uname -i`, and then make the following adjustments: 107808e23beeSColin Percival # 1. Replace "SMP-GENERIC" with "SMP". Why the SMP kernel config 107908e23beeSColin Percival # file says "ident SMP-GENERIC", I don't know... 108008e23beeSColin Percival # 2. If the kernel claims to be GENERIC _and_ ${ARCH} is "amd64" 108108e23beeSColin Percival # _and_ `sysctl kern.version` contains a line which ends "/SMP", then 108208e23beeSColin Percival # we're running an SMP kernel. This mis-identification is a bug 108308e23beeSColin Percival # which was fixed in 6.2-STABLE. 108408e23beeSColin Percival KERNCONF=`uname -i` 108508e23beeSColin Percival if [ ${KERNCONF} = "SMP-GENERIC" ]; then 108608e23beeSColin Percival KERNCONF=SMP 108708e23beeSColin Percival fi 108808e23beeSColin Percival if [ ${KERNCONF} = "GENERIC" ] && [ ${ARCH} = "amd64" ]; then 108908e23beeSColin Percival if sysctl kern.version | grep -qE '/SMP$'; then 109008e23beeSColin Percival KERNCONF=SMP 109108e23beeSColin Percival fi 109208e23beeSColin Percival fi 109308e23beeSColin Percival 109408e23beeSColin Percival # Define some paths 109508e23beeSColin Percival SHA256=/sbin/sha256 109608e23beeSColin Percival PHTTPGET=/usr/libexec/phttpget 109708e23beeSColin Percival 109808e23beeSColin Percival # Set up variables relating to VERBOSELEVEL 109908e23beeSColin Percival fetch_setup_verboselevel 110008e23beeSColin Percival} 110108e23beeSColin Percival 1102*cf1aba28SEd Maste# Packaged base and freebsd-update are incompatible. Exit with an error if 1103*cf1aba28SEd Maste# packaged base is in use. 1104*cf1aba28SEd Mastecheck_pkgbase() 1105*cf1aba28SEd Maste{ 1106*cf1aba28SEd Maste # Packaged base requires that pkg is bootstrapped. 1107*cf1aba28SEd Maste if ! pkg -c ${BASEDIR} -N >/dev/null 2>/dev/null; then 1108*cf1aba28SEd Maste return 1109*cf1aba28SEd Maste fi 1110*cf1aba28SEd Maste # Presence of FreeBSD-* package(s) indicates packaged base. 1111*cf1aba28SEd Maste if ! pkg -c ${BASEDIR} info -q -x '^FreeBSD' 2>/dev/null; then 1112*cf1aba28SEd Maste return 1113*cf1aba28SEd Maste fi 1114*cf1aba28SEd Maste cat <<EOF 1115*cf1aba28SEd MasteFreeBSD-update is incompatible with the use of packaged base. Please see 1116*cf1aba28SEd Mastehttps://wiki.freebsd.org/PkgBase for more information. 1117*cf1aba28SEd MasteEOF 1118*cf1aba28SEd Maste exit 1 1119*cf1aba28SEd Maste} 1120*cf1aba28SEd Maste 112148ffe56aSColin Percival#### Core functionality -- the actual work gets done here 112248ffe56aSColin Percival 112348ffe56aSColin Percival# Use an SRV query to pick a server. If the SRV query doesn't provide 112448ffe56aSColin Percival# a useful answer, use the server name specified by the user. 112548ffe56aSColin Percival# Put another way... look up _http._tcp.${SERVERNAME} and pick a server 112648ffe56aSColin Percival# from that; or if no servers are returned, use ${SERVERNAME}. 11279b30b96cSOlivier Certner# This allows a user to specify "update.FreeBSD.org" (in which case 11289b30b96cSOlivier Certner# freebsd-update will select one of the mirrors) or "update1.freebsd.org" 11299b30b96cSOlivier Certner# (in which case freebsd-update will use that particular server, since 11309b30b96cSOlivier Certner# there won't be an SRV entry for that name). 113148ffe56aSColin Percival# 113248ffe56aSColin Percival# We ignore the Port field, since we are always going to use port 80. 113348ffe56aSColin Percival 113448ffe56aSColin Percival# Fetch the mirror list, but do not pick a mirror yet. Returns 1 if 113548ffe56aSColin Percival# no mirrors are available for any reason. 113648ffe56aSColin Percivalfetch_pick_server_init () { 113748ffe56aSColin Percival : > serverlist_tried 113848ffe56aSColin Percival 113948ffe56aSColin Percival# Check that host(1) exists (i.e., that the system wasn't built with the 114048ffe56aSColin Percival# WITHOUT_BIND set) and don't try to find a mirror if it doesn't exist. 114148ffe56aSColin Percival if ! which -s host; then 114248ffe56aSColin Percival : > serverlist_full 114348ffe56aSColin Percival return 1 114448ffe56aSColin Percival fi 114548ffe56aSColin Percival 114648ffe56aSColin Percival echo -n "Looking up ${SERVERNAME} mirrors... " 114748ffe56aSColin Percival 114848ffe56aSColin Percival# Issue the SRV query and pull out the Priority, Weight, and Target fields. 114948ffe56aSColin Percival# BIND 9 prints "$name has SRV record ..." while BIND 8 prints 115048ffe56aSColin Percival# "$name server selection ..."; we allow either format. 115148ffe56aSColin Percival MLIST="_http._tcp.${SERVERNAME}" 115248ffe56aSColin Percival host -t srv "${MLIST}" | 1153e7fd266eSColin Percival sed -nE "s/${MLIST} (has SRV record|server selection) //Ip" | 115448ffe56aSColin Percival cut -f 1,2,4 -d ' ' | 115548ffe56aSColin Percival sed -e 's/\.$//' | 115648ffe56aSColin Percival sort > serverlist_full 115748ffe56aSColin Percival 115848ffe56aSColin Percival# If no records, give up -- we'll just use the server name we were given. 115948ffe56aSColin Percival if [ `wc -l < serverlist_full` -eq 0 ]; then 116048ffe56aSColin Percival echo "none found." 116148ffe56aSColin Percival return 1 116248ffe56aSColin Percival fi 116348ffe56aSColin Percival 116448ffe56aSColin Percival# Report how many mirrors we found. 116548ffe56aSColin Percival echo `wc -l < serverlist_full` "mirrors found." 116648ffe56aSColin Percival 116748ffe56aSColin Percival# Generate a random seed for use in picking mirrors. If HTTP_PROXY 116848ffe56aSColin Percival# is set, this will be used to generate the seed; otherwise, the seed 116948ffe56aSColin Percival# will be random. 117048ffe56aSColin Percival if [ -n "${HTTP_PROXY}${http_proxy}" ]; then 117148ffe56aSColin Percival RANDVALUE=`sha256 -qs "${HTTP_PROXY}${http_proxy}" | 117248ffe56aSColin Percival tr -d 'a-f' | 117348ffe56aSColin Percival cut -c 1-9` 117448ffe56aSColin Percival else 117548ffe56aSColin Percival RANDVALUE=`jot -r 1 0 999999999` 117648ffe56aSColin Percival fi 117748ffe56aSColin Percival} 117848ffe56aSColin Percival 117948ffe56aSColin Percival# Pick a mirror. Returns 1 if we have run out of mirrors to try. 118048ffe56aSColin Percivalfetch_pick_server () { 118148ffe56aSColin Percival# Generate a list of not-yet-tried mirrors 118248ffe56aSColin Percival sort serverlist_tried | 118348ffe56aSColin Percival comm -23 serverlist_full - > serverlist 118448ffe56aSColin Percival 118548ffe56aSColin Percival# Have we run out of mirrors? 118648ffe56aSColin Percival if [ `wc -l < serverlist` -eq 0 ]; then 11879e8c28fcSEd Maste cat <<- EOF 11889e8c28fcSEd Maste No mirrors remaining, giving up. 11899e8c28fcSEd Maste 11909e8c28fcSEd Maste This may be because upgrading from this platform (${ARCH}) 11919e8c28fcSEd Maste or release (${RELNUM}) is unsupported by `basename $0`. Only 11929e8c28fcSEd Maste platforms with Tier 1 support can be upgraded by `basename $0`. 119386d0d3aaSLi-Wen Hsu See https://www.freebsd.org/platforms/ for more info. 11949e8c28fcSEd Maste 11959e8c28fcSEd Maste If unsupported, FreeBSD must be upgraded by source. 11969e8c28fcSEd Maste EOF 119748ffe56aSColin Percival return 1 119848ffe56aSColin Percival fi 119948ffe56aSColin Percival 120048ffe56aSColin Percival# Find the highest priority level (lowest numeric value). 120148ffe56aSColin Percival SRV_PRIORITY=`cut -f 1 -d ' ' serverlist | sort -n | head -1` 120248ffe56aSColin Percival 120348ffe56aSColin Percival# Add up the weights of the response lines at that priority level. 120448ffe56aSColin Percival SRV_WSUM=0; 120548ffe56aSColin Percival while read X; do 120648ffe56aSColin Percival case "$X" in 120748ffe56aSColin Percival ${SRV_PRIORITY}\ *) 120848ffe56aSColin Percival SRV_W=`echo $X | cut -f 2 -d ' '` 120948ffe56aSColin Percival SRV_WSUM=$(($SRV_WSUM + $SRV_W)) 121048ffe56aSColin Percival ;; 121148ffe56aSColin Percival esac 121248ffe56aSColin Percival done < serverlist 121348ffe56aSColin Percival 121448ffe56aSColin Percival# If all the weights are 0, pretend that they are all 1 instead. 121548ffe56aSColin Percival if [ ${SRV_WSUM} -eq 0 ]; then 121648ffe56aSColin Percival SRV_WSUM=`grep -E "^${SRV_PRIORITY} " serverlist | wc -l` 121748ffe56aSColin Percival SRV_W_ADD=1 121848ffe56aSColin Percival else 121948ffe56aSColin Percival SRV_W_ADD=0 122048ffe56aSColin Percival fi 122148ffe56aSColin Percival 122248ffe56aSColin Percival# Pick a value between 0 and the sum of the weights - 1 122348ffe56aSColin Percival SRV_RND=`expr ${RANDVALUE} % ${SRV_WSUM}` 122448ffe56aSColin Percival 122548ffe56aSColin Percival# Read through the list of mirrors and set SERVERNAME. Write the line 122648ffe56aSColin Percival# corresponding to the mirror we selected into serverlist_tried so that 122748ffe56aSColin Percival# we won't try it again. 122848ffe56aSColin Percival while read X; do 122948ffe56aSColin Percival case "$X" in 123048ffe56aSColin Percival ${SRV_PRIORITY}\ *) 123148ffe56aSColin Percival SRV_W=`echo $X | cut -f 2 -d ' '` 123248ffe56aSColin Percival SRV_W=$(($SRV_W + $SRV_W_ADD)) 123348ffe56aSColin Percival if [ $SRV_RND -lt $SRV_W ]; then 123448ffe56aSColin Percival SERVERNAME=`echo $X | cut -f 3 -d ' '` 123548ffe56aSColin Percival echo "$X" >> serverlist_tried 123648ffe56aSColin Percival break 123748ffe56aSColin Percival else 123848ffe56aSColin Percival SRV_RND=$(($SRV_RND - $SRV_W)) 123948ffe56aSColin Percival fi 124048ffe56aSColin Percival ;; 124148ffe56aSColin Percival esac 124248ffe56aSColin Percival done < serverlist 124348ffe56aSColin Percival} 124448ffe56aSColin Percival 124548ffe56aSColin Percival# Take a list of ${oldhash}|${newhash} and output a list of needed patches, 124648ffe56aSColin Percival# i.e., those for which we have ${oldhash} and don't have ${newhash}. 124748ffe56aSColin Percivalfetch_make_patchlist () { 124848ffe56aSColin Percival grep -vE "^([0-9a-f]{64})\|\1$" | 124948ffe56aSColin Percival tr '|' ' ' | 125048ffe56aSColin Percival while read X Y; do 125148ffe56aSColin Percival if [ -f "files/${Y}.gz" ] || 125248ffe56aSColin Percival [ ! -f "files/${X}.gz" ]; then 125348ffe56aSColin Percival continue 125448ffe56aSColin Percival fi 125548ffe56aSColin Percival echo "${X}|${Y}" 1256f6e21461SEd Maste done | sort -u 125748ffe56aSColin Percival} 125848ffe56aSColin Percival 125948ffe56aSColin Percival# Print user-friendly progress statistics 126048ffe56aSColin Percivalfetch_progress () { 126148ffe56aSColin Percival LNC=0 126248ffe56aSColin Percival while read x; do 126348ffe56aSColin Percival LNC=$(($LNC + 1)) 126448ffe56aSColin Percival if [ $(($LNC % 10)) = 0 ]; then 126548ffe56aSColin Percival echo -n $LNC 126648ffe56aSColin Percival elif [ $(($LNC % 2)) = 0 ]; then 126748ffe56aSColin Percival echo -n . 126848ffe56aSColin Percival fi 126948ffe56aSColin Percival done 127048ffe56aSColin Percival echo -n " " 127148ffe56aSColin Percival} 127248ffe56aSColin Percival 1273db6b0a61SColin Percival# Function for asking the user if everything is ok 1274db6b0a61SColin Percivalcontinuep () { 1275db6b0a61SColin Percival while read -p "Does this look reasonable (y/n)? " CONTINUE; do 1276db6b0a61SColin Percival case "${CONTINUE}" in 127739f4633bSJuraj Lutter [yY]*) 1278db6b0a61SColin Percival return 0 1279db6b0a61SColin Percival ;; 128039f4633bSJuraj Lutter [nN]*) 1281db6b0a61SColin Percival return 1 1282db6b0a61SColin Percival ;; 1283db6b0a61SColin Percival esac 1284db6b0a61SColin Percival done 1285db6b0a61SColin Percival} 1286db6b0a61SColin Percival 128748ffe56aSColin Percival# Initialize the working directory 128848ffe56aSColin Percivalworkdir_init () { 128948ffe56aSColin Percival mkdir -p files 129048ffe56aSColin Percival touch tINDEX.present 129148ffe56aSColin Percival} 129248ffe56aSColin Percival 129348ffe56aSColin Percival# Check that we have a public key with an appropriate hash, or 129448ffe56aSColin Percival# fetch the key if it doesn't exist. Returns 1 if the key has 129548ffe56aSColin Percival# not yet been fetched. 129648ffe56aSColin Percivalfetch_key () { 129748ffe56aSColin Percival if [ -r pub.ssl ] && [ `${SHA256} -q pub.ssl` = ${KEYPRINT} ]; then 129848ffe56aSColin Percival return 0 129948ffe56aSColin Percival fi 130048ffe56aSColin Percival 130148ffe56aSColin Percival echo -n "Fetching public key from ${SERVERNAME}... " 130248ffe56aSColin Percival rm -f pub.ssl 130348ffe56aSColin Percival fetch ${QUIETFLAG} http://${SERVERNAME}/${FETCHDIR}/pub.ssl \ 130448ffe56aSColin Percival 2>${QUIETREDIR} || true 130548ffe56aSColin Percival if ! [ -r pub.ssl ]; then 130648ffe56aSColin Percival echo "failed." 130748ffe56aSColin Percival return 1 130848ffe56aSColin Percival fi 130948ffe56aSColin Percival if ! [ `${SHA256} -q pub.ssl` = ${KEYPRINT} ]; then 131048ffe56aSColin Percival echo "key has incorrect hash." 131148ffe56aSColin Percival rm -f pub.ssl 131248ffe56aSColin Percival return 1 131348ffe56aSColin Percival fi 131448ffe56aSColin Percival echo "done." 131548ffe56aSColin Percival} 131648ffe56aSColin Percival 131748ffe56aSColin Percival# Fetch metadata signature, aka "tag". 131848ffe56aSColin Percivalfetch_tag () { 1319db6b0a61SColin Percival echo -n "Fetching metadata signature " 1320db6b0a61SColin Percival echo ${NDEBUG} "for ${RELNUM} from ${SERVERNAME}... " 132148ffe56aSColin Percival rm -f latest.ssl 132248ffe56aSColin Percival fetch ${QUIETFLAG} http://${SERVERNAME}/${FETCHDIR}/latest.ssl \ 132348ffe56aSColin Percival 2>${QUIETREDIR} || true 132448ffe56aSColin Percival if ! [ -r latest.ssl ]; then 132548ffe56aSColin Percival echo "failed." 132648ffe56aSColin Percival return 1 132748ffe56aSColin Percival fi 132848ffe56aSColin Percival 13297220a45bSJose Luis Duran openssl pkeyutl -pubin -inkey pub.ssl -verifyrecover \ 133048ffe56aSColin Percival < latest.ssl > tag.new 2>${QUIETREDIR} || true 133148ffe56aSColin Percival rm latest.ssl 133248ffe56aSColin Percival 133348ffe56aSColin Percival if ! [ `wc -l < tag.new` = 1 ] || 133448ffe56aSColin Percival ! grep -qE \ 133548ffe56aSColin Percival "^freebsd-update\|${ARCH}\|${RELNUM}\|[0-9]+\|[0-9a-f]{64}\|[0-9]{10}" \ 133648ffe56aSColin Percival tag.new; then 133748ffe56aSColin Percival echo "invalid signature." 133848ffe56aSColin Percival return 1 133948ffe56aSColin Percival fi 134048ffe56aSColin Percival 134148ffe56aSColin Percival echo "done." 134248ffe56aSColin Percival 134348ffe56aSColin Percival RELPATCHNUM=`cut -f 4 -d '|' < tag.new` 134448ffe56aSColin Percival TINDEXHASH=`cut -f 5 -d '|' < tag.new` 134548ffe56aSColin Percival EOLTIME=`cut -f 6 -d '|' < tag.new` 134648ffe56aSColin Percival} 134748ffe56aSColin Percival 134848ffe56aSColin Percival# Sanity-check the patch number in a tag, to make sure that we're not 134948ffe56aSColin Percival# going to "update" backwards and to prevent replay attacks. 135048ffe56aSColin Percivalfetch_tagsanity () { 135148ffe56aSColin Percival # Check that we're not going to move from -pX to -pY with Y < X. 135248ffe56aSColin Percival RELPX=`uname -r | sed -E 's,.*-,,'` 135348ffe56aSColin Percival if echo ${RELPX} | grep -qE '^p[0-9]+$'; then 135448ffe56aSColin Percival RELPX=`echo ${RELPX} | cut -c 2-` 135548ffe56aSColin Percival else 135648ffe56aSColin Percival RELPX=0 135748ffe56aSColin Percival fi 135848ffe56aSColin Percival if [ "${RELPATCHNUM}" -lt "${RELPX}" ]; then 135948ffe56aSColin Percival echo 136048ffe56aSColin Percival echo -n "Files on mirror (${RELNUM}-p${RELPATCHNUM})" 136148ffe56aSColin Percival echo " appear older than what" 136248ffe56aSColin Percival echo "we are currently running (`uname -r`)!" 136348ffe56aSColin Percival echo "Cowardly refusing to proceed any further." 136448ffe56aSColin Percival return 1 136548ffe56aSColin Percival fi 136648ffe56aSColin Percival 136748ffe56aSColin Percival # If "tag" exists and corresponds to ${RELNUM}, make sure that 136848ffe56aSColin Percival # it contains a patch number <= RELPATCHNUM, in order to protect 136948ffe56aSColin Percival # against rollback (replay) attacks. 137048ffe56aSColin Percival if [ -f tag ] && 137148ffe56aSColin Percival grep -qE \ 137248ffe56aSColin Percival "^freebsd-update\|${ARCH}\|${RELNUM}\|[0-9]+\|[0-9a-f]{64}\|[0-9]{10}" \ 137348ffe56aSColin Percival tag; then 137448ffe56aSColin Percival LASTRELPATCHNUM=`cut -f 4 -d '|' < tag` 137548ffe56aSColin Percival 137648ffe56aSColin Percival if [ "${RELPATCHNUM}" -lt "${LASTRELPATCHNUM}" ]; then 137748ffe56aSColin Percival echo 137848ffe56aSColin Percival echo -n "Files on mirror (${RELNUM}-p${RELPATCHNUM})" 137948ffe56aSColin Percival echo " are older than the" 138048ffe56aSColin Percival echo -n "most recently seen updates" 138148ffe56aSColin Percival echo " (${RELNUM}-p${LASTRELPATCHNUM})." 138248ffe56aSColin Percival echo "Cowardly refusing to proceed any further." 138348ffe56aSColin Percival return 1 138448ffe56aSColin Percival fi 138548ffe56aSColin Percival fi 138648ffe56aSColin Percival} 138748ffe56aSColin Percival 138848ffe56aSColin Percival# Fetch metadata index file 138948ffe56aSColin Percivalfetch_metadata_index () { 139048ffe56aSColin Percival echo ${NDEBUG} "Fetching metadata index... " 139148ffe56aSColin Percival rm -f ${TINDEXHASH} 139248ffe56aSColin Percival fetch ${QUIETFLAG} http://${SERVERNAME}/${FETCHDIR}/t/${TINDEXHASH} 139348ffe56aSColin Percival 2>${QUIETREDIR} 139448ffe56aSColin Percival if ! [ -f ${TINDEXHASH} ]; then 139548ffe56aSColin Percival echo "failed." 139648ffe56aSColin Percival return 1 139748ffe56aSColin Percival fi 139848ffe56aSColin Percival if [ `${SHA256} -q ${TINDEXHASH}` != ${TINDEXHASH} ]; then 139948ffe56aSColin Percival echo "update metadata index corrupt." 140048ffe56aSColin Percival return 1 140148ffe56aSColin Percival fi 140248ffe56aSColin Percival echo "done." 140348ffe56aSColin Percival} 140448ffe56aSColin Percival 140548ffe56aSColin Percival# Print an error message about signed metadata being bogus. 140648ffe56aSColin Percivalfetch_metadata_bogus () { 140748ffe56aSColin Percival echo 140848ffe56aSColin Percival echo "The update metadata$1 is correctly signed, but" 140948ffe56aSColin Percival echo "failed an integrity check." 141048ffe56aSColin Percival echo "Cowardly refusing to proceed any further." 141148ffe56aSColin Percival return 1 141248ffe56aSColin Percival} 141348ffe56aSColin Percival 141448ffe56aSColin Percival# Construct tINDEX.new by merging the lines named in $1 from ${TINDEXHASH} 141548ffe56aSColin Percival# with the lines not named in $@ from tINDEX.present (if that file exists). 141648ffe56aSColin Percivalfetch_metadata_index_merge () { 141748ffe56aSColin Percival for METAFILE in $@; do 141848ffe56aSColin Percival if [ `grep -E "^${METAFILE}\|" ${TINDEXHASH} | wc -l` \ 141948ffe56aSColin Percival -ne 1 ]; then 142048ffe56aSColin Percival fetch_metadata_bogus " index" 142148ffe56aSColin Percival return 1 142248ffe56aSColin Percival fi 142348ffe56aSColin Percival 142448ffe56aSColin Percival grep -E "${METAFILE}\|" ${TINDEXHASH} 142548ffe56aSColin Percival done | 142648ffe56aSColin Percival sort > tINDEX.wanted 142748ffe56aSColin Percival 142848ffe56aSColin Percival if [ -f tINDEX.present ]; then 142948ffe56aSColin Percival join -t '|' -v 2 tINDEX.wanted tINDEX.present | 143048ffe56aSColin Percival sort -m - tINDEX.wanted > tINDEX.new 143148ffe56aSColin Percival rm tINDEX.wanted 143248ffe56aSColin Percival else 143348ffe56aSColin Percival mv tINDEX.wanted tINDEX.new 143448ffe56aSColin Percival fi 143548ffe56aSColin Percival} 143648ffe56aSColin Percival 143748ffe56aSColin Percival# Sanity check all the lines of tINDEX.new. Even if more metadata lines 143848ffe56aSColin Percival# are added by future versions of the server, this won't cause problems, 143948ffe56aSColin Percival# since the only lines which appear in tINDEX.new are the ones which we 144048ffe56aSColin Percival# specifically grepped out of ${TINDEXHASH}. 144148ffe56aSColin Percivalfetch_metadata_index_sanity () { 144248ffe56aSColin Percival if grep -qvE '^[0-9A-Z.-]+\|[0-9a-f]{64}$' tINDEX.new; then 144348ffe56aSColin Percival fetch_metadata_bogus " index" 144448ffe56aSColin Percival return 1 144548ffe56aSColin Percival fi 144648ffe56aSColin Percival} 144748ffe56aSColin Percival 144848ffe56aSColin Percival# Sanity check the metadata file $1. 144948ffe56aSColin Percivalfetch_metadata_sanity () { 145048ffe56aSColin Percival # Some aliases to save space later: ${P} is a character which can 145148ffe56aSColin Percival # appear in a path; ${M} is the four numeric metadata fields; and 145248ffe56aSColin Percival # ${H} is a sha256 hash. 14537c06c7c5SKris Moore P="[-+./:=,%@_[~[:alnum:]]" 145448ffe56aSColin Percival M="[0-9]+\|[0-9]+\|[0-9]+\|[0-9]+" 145548ffe56aSColin Percival H="[0-9a-f]{64}" 145648ffe56aSColin Percival 145748ffe56aSColin Percival # Check that the first four fields make sense. 145848ffe56aSColin Percival if gunzip -c < files/$1.gz | 1459823c0d5fSXin LI grep -qvE "^[a-z]+\|[0-9a-z-]+\|${P}+\|[fdL-]\|"; then 146048ffe56aSColin Percival fetch_metadata_bogus "" 146148ffe56aSColin Percival return 1 146248ffe56aSColin Percival fi 146348ffe56aSColin Percival 146448ffe56aSColin Percival # Remove the first three fields. 146548ffe56aSColin Percival gunzip -c < files/$1.gz | 146648ffe56aSColin Percival cut -f 4- -d '|' > sanitycheck.tmp 146748ffe56aSColin Percival 146848ffe56aSColin Percival # Sanity check entries with type 'f' 146948ffe56aSColin Percival if grep -E '^f' sanitycheck.tmp | 147048ffe56aSColin Percival grep -qvE "^f\|${M}\|${H}\|${P}*\$"; then 147148ffe56aSColin Percival fetch_metadata_bogus "" 147248ffe56aSColin Percival return 1 147348ffe56aSColin Percival fi 147448ffe56aSColin Percival 147548ffe56aSColin Percival # Sanity check entries with type 'd' 147648ffe56aSColin Percival if grep -E '^d' sanitycheck.tmp | 147748ffe56aSColin Percival grep -qvE "^d\|${M}\|\|\$"; then 147848ffe56aSColin Percival fetch_metadata_bogus "" 147948ffe56aSColin Percival return 1 148048ffe56aSColin Percival fi 148148ffe56aSColin Percival 148248ffe56aSColin Percival # Sanity check entries with type 'L' 148348ffe56aSColin Percival if grep -E '^L' sanitycheck.tmp | 148448ffe56aSColin Percival grep -qvE "^L\|${M}\|${P}*\|\$"; then 148548ffe56aSColin Percival fetch_metadata_bogus "" 148648ffe56aSColin Percival return 1 148748ffe56aSColin Percival fi 148848ffe56aSColin Percival 148948ffe56aSColin Percival # Sanity check entries with type '-' 149048ffe56aSColin Percival if grep -E '^-' sanitycheck.tmp | 149148ffe56aSColin Percival grep -qvE "^-\|\|\|\|\|\|"; then 149248ffe56aSColin Percival fetch_metadata_bogus "" 149348ffe56aSColin Percival return 1 149448ffe56aSColin Percival fi 149548ffe56aSColin Percival 149648ffe56aSColin Percival # Clean up 149748ffe56aSColin Percival rm sanitycheck.tmp 149848ffe56aSColin Percival} 149948ffe56aSColin Percival 150048ffe56aSColin Percival# Fetch the metadata index and metadata files listed in $@, 150148ffe56aSColin Percival# taking advantage of metadata patches where possible. 150248ffe56aSColin Percivalfetch_metadata () { 150348ffe56aSColin Percival fetch_metadata_index || return 1 150448ffe56aSColin Percival fetch_metadata_index_merge $@ || return 1 150548ffe56aSColin Percival fetch_metadata_index_sanity || return 1 150648ffe56aSColin Percival 150748ffe56aSColin Percival # Generate a list of wanted metadata patches 150848ffe56aSColin Percival join -t '|' -o 1.2,2.2 tINDEX.present tINDEX.new | 150948ffe56aSColin Percival fetch_make_patchlist > patchlist 151048ffe56aSColin Percival 151148ffe56aSColin Percival if [ -s patchlist ]; then 151248ffe56aSColin Percival # Attempt to fetch metadata patches 151348ffe56aSColin Percival echo -n "Fetching `wc -l < patchlist | tr -d ' '` " 151448ffe56aSColin Percival echo ${NDEBUG} "metadata patches.${DDSTATS}" 151548ffe56aSColin Percival tr '|' '-' < patchlist | 151648ffe56aSColin Percival lam -s "${FETCHDIR}/tp/" - -s ".gz" | 151748ffe56aSColin Percival xargs ${XARGST} ${PHTTPGET} ${SERVERNAME} \ 151848ffe56aSColin Percival 2>${STATSREDIR} | fetch_progress 151948ffe56aSColin Percival echo "done." 152048ffe56aSColin Percival 152148ffe56aSColin Percival # Attempt to apply metadata patches 152248ffe56aSColin Percival echo -n "Applying metadata patches... " 152348ffe56aSColin Percival tr '|' ' ' < patchlist | 152448ffe56aSColin Percival while read X Y; do 152548ffe56aSColin Percival if [ ! -f "${X}-${Y}.gz" ]; then continue; fi 152648ffe56aSColin Percival gunzip -c < ${X}-${Y}.gz > diff 152748ffe56aSColin Percival gunzip -c < files/${X}.gz > diff-OLD 152848ffe56aSColin Percival 152948ffe56aSColin Percival # Figure out which lines are being added and removed 153048ffe56aSColin Percival grep -E '^-' diff | 153148ffe56aSColin Percival cut -c 2- | 153248ffe56aSColin Percival while read PREFIX; do 153348ffe56aSColin Percival look "${PREFIX}" diff-OLD 153448ffe56aSColin Percival done | 153548ffe56aSColin Percival sort > diff-rm 153648ffe56aSColin Percival grep -E '^\+' diff | 153748ffe56aSColin Percival cut -c 2- > diff-add 153848ffe56aSColin Percival 153948ffe56aSColin Percival # Generate the new file 154048ffe56aSColin Percival comm -23 diff-OLD diff-rm | 154148ffe56aSColin Percival sort - diff-add > diff-NEW 154248ffe56aSColin Percival 154348ffe56aSColin Percival if [ `${SHA256} -q diff-NEW` = ${Y} ]; then 154448ffe56aSColin Percival mv diff-NEW files/${Y} 154548ffe56aSColin Percival gzip -n files/${Y} 154648ffe56aSColin Percival else 154748ffe56aSColin Percival mv diff-NEW ${Y}.bad 154848ffe56aSColin Percival fi 154948ffe56aSColin Percival rm -f ${X}-${Y}.gz diff 155048ffe56aSColin Percival rm -f diff-OLD diff-NEW diff-add diff-rm 155148ffe56aSColin Percival done 2>${QUIETREDIR} 155248ffe56aSColin Percival echo "done." 155348ffe56aSColin Percival fi 155448ffe56aSColin Percival 155548ffe56aSColin Percival # Update metadata without patches 155648ffe56aSColin Percival cut -f 2 -d '|' < tINDEX.new | 155748ffe56aSColin Percival while read Y; do 155848ffe56aSColin Percival if [ ! -f "files/${Y}.gz" ]; then 155948ffe56aSColin Percival echo ${Y}; 156048ffe56aSColin Percival fi 1561bce02f98SColin Percival done | 1562bce02f98SColin Percival sort -u > filelist 156348ffe56aSColin Percival 156448ffe56aSColin Percival if [ -s filelist ]; then 156548ffe56aSColin Percival echo -n "Fetching `wc -l < filelist | tr -d ' '` " 156648ffe56aSColin Percival echo ${NDEBUG} "metadata files... " 156748ffe56aSColin Percival lam -s "${FETCHDIR}/m/" - -s ".gz" < filelist | 156848ffe56aSColin Percival xargs ${XARGST} ${PHTTPGET} ${SERVERNAME} \ 156948ffe56aSColin Percival 2>${QUIETREDIR} 157048ffe56aSColin Percival 157148ffe56aSColin Percival while read Y; do 157248ffe56aSColin Percival if ! [ -f ${Y}.gz ]; then 157348ffe56aSColin Percival echo "failed." 157448ffe56aSColin Percival return 1 157548ffe56aSColin Percival fi 157648ffe56aSColin Percival if [ `gunzip -c < ${Y}.gz | 157748ffe56aSColin Percival ${SHA256} -q` = ${Y} ]; then 157848ffe56aSColin Percival mv ${Y}.gz files/${Y}.gz 157948ffe56aSColin Percival else 158048ffe56aSColin Percival echo "metadata is corrupt." 158148ffe56aSColin Percival return 1 158248ffe56aSColin Percival fi 158348ffe56aSColin Percival done < filelist 158448ffe56aSColin Percival echo "done." 158548ffe56aSColin Percival fi 158648ffe56aSColin Percival 158748ffe56aSColin Percival# Sanity-check the metadata files. 158848ffe56aSColin Percival cut -f 2 -d '|' tINDEX.new > filelist 158948ffe56aSColin Percival while read X; do 159048ffe56aSColin Percival fetch_metadata_sanity ${X} || return 1 159148ffe56aSColin Percival done < filelist 159248ffe56aSColin Percival 159348ffe56aSColin Percival# Remove files which are no longer needed 159448ffe56aSColin Percival cut -f 2 -d '|' tINDEX.present | 159548ffe56aSColin Percival sort > oldfiles 159648ffe56aSColin Percival cut -f 2 -d '|' tINDEX.new | 159748ffe56aSColin Percival sort | 159848ffe56aSColin Percival comm -13 - oldfiles | 159948ffe56aSColin Percival lam -s "files/" - -s ".gz" | 160048ffe56aSColin Percival xargs rm -f 160148ffe56aSColin Percival rm patchlist filelist oldfiles 160248ffe56aSColin Percival rm ${TINDEXHASH} 160348ffe56aSColin Percival 160448ffe56aSColin Percival# We're done! 160548ffe56aSColin Percival mv tINDEX.new tINDEX.present 160648ffe56aSColin Percival mv tag.new tag 160748ffe56aSColin Percival 160848ffe56aSColin Percival return 0 160948ffe56aSColin Percival} 161048ffe56aSColin Percival 1611db6b0a61SColin Percival# Extract a subset of a downloaded metadata file containing only the parts 1612db6b0a61SColin Percival# which are listed in COMPONENTS. 1613db6b0a61SColin Percivalfetch_filter_metadata_components () { 1614db6b0a61SColin Percival METAHASH=`look "$1|" tINDEX.present | cut -f 2 -d '|'` 1615db6b0a61SColin Percival gunzip -c < files/${METAHASH}.gz > $1.all 1616db6b0a61SColin Percival 1617db6b0a61SColin Percival # Fish out the lines belonging to components we care about. 1618db6b0a61SColin Percival for C in ${COMPONENTS}; do 1619db6b0a61SColin Percival look "`echo ${C} | tr '/' '|'`|" $1.all 1620db6b0a61SColin Percival done > $1 1621db6b0a61SColin Percival 1622db6b0a61SColin Percival # Remove temporary file. 1623db6b0a61SColin Percival rm $1.all 1624db6b0a61SColin Percival} 1625db6b0a61SColin Percival 1626b698a3abSColin Percival# Generate a filtered version of the metadata file $1 from the downloaded 162748ffe56aSColin Percival# file, by fishing out the lines corresponding to components we're trying 162848ffe56aSColin Percival# to keep updated, and then removing lines corresponding to paths we want 162948ffe56aSColin Percival# to ignore. 163048ffe56aSColin Percivalfetch_filter_metadata () { 163148ffe56aSColin Percival # Fish out the lines belonging to components we care about. 1632db6b0a61SColin Percival fetch_filter_metadata_components $1 1633db6b0a61SColin Percival 163448ffe56aSColin Percival # Canonicalize directory names by removing any trailing / in 163548ffe56aSColin Percival # order to avoid listing directories multiple times if they 163648ffe56aSColin Percival # belong to multiple components. Turning "/" into "" doesn't 163748ffe56aSColin Percival # matter, since we add a leading "/" when we use paths later. 1638db6b0a61SColin Percival cut -f 3- -d '|' $1 | 163948ffe56aSColin Percival sed -e 's,/|d|,|d|,' | 16407e654612SColin Percival sed -e 's,/|-|,|-|,' | 164148ffe56aSColin Percival sort -u > $1.tmp 164248ffe56aSColin Percival 164348ffe56aSColin Percival # Figure out which lines to ignore and remove them. 164448ffe56aSColin Percival for X in ${IGNOREPATHS}; do 164548ffe56aSColin Percival grep -E "^${X}" $1.tmp 164648ffe56aSColin Percival done | 164748ffe56aSColin Percival sort -u | 164848ffe56aSColin Percival comm -13 - $1.tmp > $1 164948ffe56aSColin Percival 165048ffe56aSColin Percival # Remove temporary files. 1651db6b0a61SColin Percival rm $1.tmp 165248ffe56aSColin Percival} 165348ffe56aSColin Percival 1654db6b0a61SColin Percival# Filter the metadata file $1 by adding lines with "/boot/$2" 1655bce02f98SColin Percival# replaced by ${KERNELDIR} (which is `sysctl -n kern.bootfile` minus the 1656db6b0a61SColin Percival# trailing "/kernel"); and if "/boot/$2" does not exist, remove 1657bce02f98SColin Percival# the original lines which start with that. 1658bce02f98SColin Percival# Put another way: Deal with the fact that the FOO kernel is sometimes 1659bce02f98SColin Percival# installed in /boot/FOO/ and is sometimes installed elsewhere. 166048ffe56aSColin Percivalfetch_filter_kernel_names () { 1661db6b0a61SColin Percival grep ^/boot/$2 $1 | 1662db6b0a61SColin Percival sed -e "s,/boot/$2,${KERNELDIR},g" | 166348ffe56aSColin Percival sort - $1 > $1.tmp 166448ffe56aSColin Percival mv $1.tmp $1 1665bce02f98SColin Percival 1666db6b0a61SColin Percival if ! [ -d /boot/$2 ]; then 1667db6b0a61SColin Percival grep -v ^/boot/$2 $1 > $1.tmp 1668bce02f98SColin Percival mv $1.tmp $1 1669bce02f98SColin Percival fi 167048ffe56aSColin Percival} 167148ffe56aSColin Percival 167248ffe56aSColin Percival# For all paths appearing in $1 or $3, inspect the system 167348ffe56aSColin Percival# and generate $2 describing what is currently installed. 167448ffe56aSColin Percivalfetch_inspect_system () { 167548ffe56aSColin Percival # No errors yet... 167648ffe56aSColin Percival rm -f .err 167748ffe56aSColin Percival 167848ffe56aSColin Percival # Tell the user why his disk is suddenly making lots of noise 167948ffe56aSColin Percival echo -n "Inspecting system... " 168048ffe56aSColin Percival 168148ffe56aSColin Percival # Generate list of files to inspect 168248ffe56aSColin Percival cat $1 $3 | 168348ffe56aSColin Percival cut -f 1 -d '|' | 168448ffe56aSColin Percival sort -u > filelist 168548ffe56aSColin Percival 168648ffe56aSColin Percival # Examine each file and output lines of the form 168748ffe56aSColin Percival # /path/to/file|type|device-inum|user|group|perm|flags|value 168848ffe56aSColin Percival # sorted by device and inode number. 168948ffe56aSColin Percival while read F; do 169048ffe56aSColin Percival # If the symlink/file/directory does not exist, record this. 169148ffe56aSColin Percival if ! [ -e ${BASEDIR}/${F} ]; then 169248ffe56aSColin Percival echo "${F}|-||||||" 169348ffe56aSColin Percival continue 169448ffe56aSColin Percival fi 169548ffe56aSColin Percival if ! [ -r ${BASEDIR}/${F} ]; then 169648ffe56aSColin Percival echo "Cannot read file: ${BASEDIR}/${F}" \ 169748ffe56aSColin Percival >/dev/stderr 169848ffe56aSColin Percival touch .err 169948ffe56aSColin Percival return 1 170048ffe56aSColin Percival fi 170148ffe56aSColin Percival 170248ffe56aSColin Percival # Otherwise, output an index line. 170348ffe56aSColin Percival if [ -L ${BASEDIR}/${F} ]; then 170448ffe56aSColin Percival echo -n "${F}|L|" 170548ffe56aSColin Percival stat -n -f '%d-%i|%u|%g|%Mp%Lp|%Of|' ${BASEDIR}/${F}; 170648ffe56aSColin Percival readlink ${BASEDIR}/${F}; 170748ffe56aSColin Percival elif [ -f ${BASEDIR}/${F} ]; then 170848ffe56aSColin Percival echo -n "${F}|f|" 170948ffe56aSColin Percival stat -n -f '%d-%i|%u|%g|%Mp%Lp|%Of|' ${BASEDIR}/${F}; 171048ffe56aSColin Percival sha256 -q ${BASEDIR}/${F}; 171148ffe56aSColin Percival elif [ -d ${BASEDIR}/${F} ]; then 171248ffe56aSColin Percival echo -n "${F}|d|" 171348ffe56aSColin Percival stat -f '%d-%i|%u|%g|%Mp%Lp|%Of|' ${BASEDIR}/${F}; 171448ffe56aSColin Percival else 171548ffe56aSColin Percival echo "Unknown file type: ${BASEDIR}/${F}" \ 171648ffe56aSColin Percival >/dev/stderr 171748ffe56aSColin Percival touch .err 171848ffe56aSColin Percival return 1 171948ffe56aSColin Percival fi 172048ffe56aSColin Percival done < filelist | 172148ffe56aSColin Percival sort -k 3,3 -t '|' > $2.tmp 172248ffe56aSColin Percival rm filelist 172348ffe56aSColin Percival 17246dcc68c8SBenedict Reuschling # Check if an error occurred during system inspection 172548ffe56aSColin Percival if [ -f .err ]; then 172648ffe56aSColin Percival return 1 172748ffe56aSColin Percival fi 172848ffe56aSColin Percival 172948ffe56aSColin Percival # Convert to the form 173048ffe56aSColin Percival # /path/to/file|type|user|group|perm|flags|value|hlink 173148ffe56aSColin Percival # by resolving identical device and inode numbers into hard links. 173248ffe56aSColin Percival cut -f 1,3 -d '|' $2.tmp | 173348ffe56aSColin Percival sort -k 1,1 -t '|' | 173448ffe56aSColin Percival sort -s -u -k 2,2 -t '|' | 173548ffe56aSColin Percival join -1 2 -2 3 -t '|' - $2.tmp | 173648ffe56aSColin Percival awk -F \| -v OFS=\| \ 173748ffe56aSColin Percival '{ 173848ffe56aSColin Percival if (($2 == $3) || ($4 == "-")) 173948ffe56aSColin Percival print $3,$4,$5,$6,$7,$8,$9,"" 174048ffe56aSColin Percival else 174148ffe56aSColin Percival print $3,$4,$5,$6,$7,$8,$9,$2 174248ffe56aSColin Percival }' | 174348ffe56aSColin Percival sort > $2 174448ffe56aSColin Percival rm $2.tmp 174548ffe56aSColin Percival 174648ffe56aSColin Percival # We're finished looking around 174748ffe56aSColin Percival echo "done." 174848ffe56aSColin Percival} 174948ffe56aSColin Percival 1750c55b7e52SColin Percival# For any paths matching ${MERGECHANGES}, compare $2 against $1 and $3 and 1751c55b7e52SColin Percival# find any files with values unique to $2; generate $4 containing these paths 1752c55b7e52SColin Percival# and their corresponding hashes from $1. 1753db6b0a61SColin Percivalfetch_filter_mergechanges () { 1754db6b0a61SColin Percival # Pull out the paths and hashes of the files matching ${MERGECHANGES}. 1755c55b7e52SColin Percival for F in $1 $2 $3; do 1756db6b0a61SColin Percival for X in ${MERGECHANGES}; do 1757db6b0a61SColin Percival grep -E "^${X}" ${F} 1758db6b0a61SColin Percival done | 1759db6b0a61SColin Percival cut -f 1,2,7 -d '|' | 1760db6b0a61SColin Percival sort > ${F}-values 1761db6b0a61SColin Percival done 1762db6b0a61SColin Percival 1763c55b7e52SColin Percival # Any line in $2-values which doesn't appear in $1-values or $3-values 1764c55b7e52SColin Percival # and is a file means that we should list the path in $3. 1765c55b7e52SColin Percival sort $1-values $3-values | 1766c55b7e52SColin Percival comm -13 - $2-values | 1767db6b0a61SColin Percival fgrep '|f|' | 1768db6b0a61SColin Percival cut -f 1 -d '|' > $2-paths 1769db6b0a61SColin Percival 1770db6b0a61SColin Percival # For each path, pull out one (and only one!) entry from $1-values. 1771db6b0a61SColin Percival # Note that we cannot distinguish which "old" version the user made 1772db6b0a61SColin Percival # changes to; but hopefully any changes which occur due to security 1773db6b0a61SColin Percival # updates will exist in both the "new" version and the version which 1774db6b0a61SColin Percival # the user has installed, so the merging will still work. 1775db6b0a61SColin Percival while read X; do 1776db6b0a61SColin Percival look "${X}|" $1-values | 1777db6b0a61SColin Percival head -1 1778c55b7e52SColin Percival done < $2-paths > $4 1779db6b0a61SColin Percival 1780db6b0a61SColin Percival # Clean up 1781c55b7e52SColin Percival rm $1-values $2-values $3-values $2-paths 1782db6b0a61SColin Percival} 1783db6b0a61SColin Percival 178448ffe56aSColin Percival# For any paths matching ${UPDATEIFUNMODIFIED}, remove lines from $[123] 1785db6b0a61SColin Percival# which correspond to lines in $2 with hashes not matching $1 or $3, unless 1786db6b0a61SColin Percival# the paths are listed in $4. For entries in $2 marked "not present" 1787db6b0a61SColin Percival# (aka. type -), remove lines from $[123] unless there is a corresponding 1788db6b0a61SColin Percival# entry in $1. 178948ffe56aSColin Percivalfetch_filter_unmodified_notpresent () { 179048ffe56aSColin Percival # Figure out which lines of $1 and $3 correspond to bits which 179148ffe56aSColin Percival # should only be updated if they haven't changed, and fish out 179248ffe56aSColin Percival # the (path, type, value) tuples. 179348ffe56aSColin Percival # NOTE: We don't consider a file to be "modified" if it matches 179448ffe56aSColin Percival # the hash from $3. 179548ffe56aSColin Percival for X in ${UPDATEIFUNMODIFIED}; do 179648ffe56aSColin Percival grep -E "^${X}" $1 179748ffe56aSColin Percival grep -E "^${X}" $3 179848ffe56aSColin Percival done | 179948ffe56aSColin Percival cut -f 1,2,7 -d '|' | 180048ffe56aSColin Percival sort > $1-values 180148ffe56aSColin Percival 180248ffe56aSColin Percival # Do the same for $2. 180348ffe56aSColin Percival for X in ${UPDATEIFUNMODIFIED}; do 180448ffe56aSColin Percival grep -E "^${X}" $2 180548ffe56aSColin Percival done | 180648ffe56aSColin Percival cut -f 1,2,7 -d '|' | 180748ffe56aSColin Percival sort > $2-values 180848ffe56aSColin Percival 180948ffe56aSColin Percival # Any entry in $2-values which is not in $1-values corresponds to 1810db6b0a61SColin Percival # a path which we need to remove from $1, $2, and $3, unless it 1811db6b0a61SColin Percival # that path appears in $4. 1812db6b0a61SColin Percival comm -13 $1-values $2-values | 1813db6b0a61SColin Percival sort -t '|' -k 1,1 > mlines.tmp 1814db6b0a61SColin Percival cut -f 1 -d '|' $4 | 1815db6b0a61SColin Percival sort | 1816db6b0a61SColin Percival join -v 2 -t '|' - mlines.tmp | 1817db6b0a61SColin Percival sort > mlines 1818db6b0a61SColin Percival rm $1-values $2-values mlines.tmp 181948ffe56aSColin Percival 182048ffe56aSColin Percival # Any lines in $2 which are not in $1 AND are "not present" lines 182148ffe56aSColin Percival # also belong in mlines. 182248ffe56aSColin Percival comm -13 $1 $2 | 182348ffe56aSColin Percival cut -f 1,2,7 -d '|' | 182448ffe56aSColin Percival fgrep '|-|' >> mlines 182548ffe56aSColin Percival 182648ffe56aSColin Percival # Remove lines from $1, $2, and $3 182748ffe56aSColin Percival for X in $1 $2 $3; do 182848ffe56aSColin Percival sort -t '|' -k 1,1 ${X} > ${X}.tmp 182948ffe56aSColin Percival cut -f 1 -d '|' < mlines | 183048ffe56aSColin Percival sort | 183148ffe56aSColin Percival join -v 2 -t '|' - ${X}.tmp | 183248ffe56aSColin Percival sort > ${X} 183348ffe56aSColin Percival rm ${X}.tmp 183448ffe56aSColin Percival done 183548ffe56aSColin Percival 183648ffe56aSColin Percival # Store a list of the modified files, for future reference 183748ffe56aSColin Percival fgrep -v '|-|' mlines | 183848ffe56aSColin Percival cut -f 1 -d '|' > modifiedfiles 183948ffe56aSColin Percival rm mlines 184048ffe56aSColin Percival} 184148ffe56aSColin Percival 184248ffe56aSColin Percival# For each entry in $1 of type -, remove any corresponding 184348ffe56aSColin Percival# entry from $2 if ${ALLOWADD} != "yes". Remove all entries 184448ffe56aSColin Percival# of type - from $1. 184548ffe56aSColin Percivalfetch_filter_allowadd () { 184648ffe56aSColin Percival cut -f 1,2 -d '|' < $1 | 184748ffe56aSColin Percival fgrep '|-' | 184848ffe56aSColin Percival cut -f 1 -d '|' > filesnotpresent 184948ffe56aSColin Percival 185048ffe56aSColin Percival if [ ${ALLOWADD} != "yes" ]; then 185148ffe56aSColin Percival sort < $2 | 185248ffe56aSColin Percival join -v 1 -t '|' - filesnotpresent | 185348ffe56aSColin Percival sort > $2.tmp 185448ffe56aSColin Percival mv $2.tmp $2 185548ffe56aSColin Percival fi 185648ffe56aSColin Percival 185748ffe56aSColin Percival sort < $1 | 185848ffe56aSColin Percival join -v 1 -t '|' - filesnotpresent | 185948ffe56aSColin Percival sort > $1.tmp 186048ffe56aSColin Percival mv $1.tmp $1 186148ffe56aSColin Percival rm filesnotpresent 186248ffe56aSColin Percival} 186348ffe56aSColin Percival 186448ffe56aSColin Percival# If ${ALLOWDELETE} != "yes", then remove any entries from $1 186548ffe56aSColin Percival# which don't correspond to entries in $2. 186648ffe56aSColin Percivalfetch_filter_allowdelete () { 186748ffe56aSColin Percival # Produce a lists ${PATH}|${TYPE} 186848ffe56aSColin Percival for X in $1 $2; do 186948ffe56aSColin Percival cut -f 1-2 -d '|' < ${X} | 187048ffe56aSColin Percival sort -u > ${X}.nodes 187148ffe56aSColin Percival done 187248ffe56aSColin Percival 187348ffe56aSColin Percival # Figure out which lines need to be removed from $1. 187448ffe56aSColin Percival if [ ${ALLOWDELETE} != "yes" ]; then 187548ffe56aSColin Percival comm -23 $1.nodes $2.nodes > $1.badnodes 187648ffe56aSColin Percival else 187748ffe56aSColin Percival : > $1.badnodes 187848ffe56aSColin Percival fi 187948ffe56aSColin Percival 188048ffe56aSColin Percival # Remove the relevant lines from $1 188148ffe56aSColin Percival while read X; do 188248ffe56aSColin Percival look "${X}|" $1 188348ffe56aSColin Percival done < $1.badnodes | 188448ffe56aSColin Percival comm -13 - $1 > $1.tmp 188548ffe56aSColin Percival mv $1.tmp $1 188648ffe56aSColin Percival 188748ffe56aSColin Percival rm $1.badnodes $1.nodes $2.nodes 188848ffe56aSColin Percival} 188948ffe56aSColin Percival 189048ffe56aSColin Percival# If ${KEEPMODIFIEDMETADATA} == "yes", then for each entry in $2 189148ffe56aSColin Percival# with metadata not matching any entry in $1, replace the corresponding 189248ffe56aSColin Percival# line of $3 with one having the same metadata as the entry in $2. 189348ffe56aSColin Percivalfetch_filter_modified_metadata () { 189448ffe56aSColin Percival # Fish out the metadata from $1 and $2 189548ffe56aSColin Percival for X in $1 $2; do 189648ffe56aSColin Percival cut -f 1-6 -d '|' < ${X} > ${X}.metadata 189748ffe56aSColin Percival done 189848ffe56aSColin Percival 189948ffe56aSColin Percival # Find the metadata we need to keep 190048ffe56aSColin Percival if [ ${KEEPMODIFIEDMETADATA} = "yes" ]; then 190148ffe56aSColin Percival comm -13 $1.metadata $2.metadata > keepmeta 190248ffe56aSColin Percival else 190348ffe56aSColin Percival : > keepmeta 190448ffe56aSColin Percival fi 190548ffe56aSColin Percival 190648ffe56aSColin Percival # Extract the lines which we need to remove from $3, and 190748ffe56aSColin Percival # construct the lines which we need to add to $3. 190848ffe56aSColin Percival : > $3.remove 190948ffe56aSColin Percival : > $3.add 191048ffe56aSColin Percival while read LINE; do 191148ffe56aSColin Percival NODE=`echo "${LINE}" | cut -f 1-2 -d '|'` 191248ffe56aSColin Percival look "${NODE}|" $3 >> $3.remove 191348ffe56aSColin Percival look "${NODE}|" $3 | 191448ffe56aSColin Percival cut -f 7- -d '|' | 191548ffe56aSColin Percival lam -s "${LINE}|" - >> $3.add 191648ffe56aSColin Percival done < keepmeta 191748ffe56aSColin Percival 191848ffe56aSColin Percival # Remove the specified lines and add the new lines. 191948ffe56aSColin Percival sort $3.remove | 192048ffe56aSColin Percival comm -13 - $3 | 192148ffe56aSColin Percival sort -u - $3.add > $3.tmp 192248ffe56aSColin Percival mv $3.tmp $3 192348ffe56aSColin Percival 192448ffe56aSColin Percival rm keepmeta $1.metadata $2.metadata $3.add $3.remove 192548ffe56aSColin Percival} 192648ffe56aSColin Percival 192748ffe56aSColin Percival# Remove lines from $1 and $2 which are identical; 192848ffe56aSColin Percival# no need to update a file if it isn't changing. 192948ffe56aSColin Percivalfetch_filter_uptodate () { 193048ffe56aSColin Percival comm -23 $1 $2 > $1.tmp 193148ffe56aSColin Percival comm -13 $1 $2 > $2.tmp 193248ffe56aSColin Percival 193348ffe56aSColin Percival mv $1.tmp $1 193448ffe56aSColin Percival mv $2.tmp $2 193548ffe56aSColin Percival} 193648ffe56aSColin Percival 1937db6b0a61SColin Percival# Fetch any "clean" old versions of files we need for merging changes. 1938db6b0a61SColin Percivalfetch_files_premerge () { 1939db6b0a61SColin Percival # We only need to do anything if $1 is non-empty. 1940db6b0a61SColin Percival if [ -s $1 ]; then 1941db6b0a61SColin Percival # Tell the user what we're doing 1942db6b0a61SColin Percival echo -n "Fetching files from ${OLDRELNUM} for merging... " 1943db6b0a61SColin Percival 1944db6b0a61SColin Percival # List of files wanted 1945db6b0a61SColin Percival fgrep '|f|' < $1 | 1946db6b0a61SColin Percival cut -f 3 -d '|' | 1947db6b0a61SColin Percival sort -u > files.wanted 1948db6b0a61SColin Percival 1949db6b0a61SColin Percival # Only fetch the files we don't already have 1950db6b0a61SColin Percival while read Y; do 1951db6b0a61SColin Percival if [ ! -f "files/${Y}.gz" ]; then 1952db6b0a61SColin Percival echo ${Y}; 1953db6b0a61SColin Percival fi 1954db6b0a61SColin Percival done < files.wanted > filelist 1955db6b0a61SColin Percival 1956db6b0a61SColin Percival # Actually fetch them 1957db6b0a61SColin Percival lam -s "${OLDFETCHDIR}/f/" - -s ".gz" < filelist | 1958db6b0a61SColin Percival xargs ${XARGST} ${PHTTPGET} ${SERVERNAME} \ 1959db6b0a61SColin Percival 2>${QUIETREDIR} 1960db6b0a61SColin Percival 1961db6b0a61SColin Percival # Make sure we got them all, and move them into /files/ 1962db6b0a61SColin Percival while read Y; do 1963db6b0a61SColin Percival if ! [ -f ${Y}.gz ]; then 1964db6b0a61SColin Percival echo "failed." 1965db6b0a61SColin Percival return 1 1966db6b0a61SColin Percival fi 1967db6b0a61SColin Percival if [ `gunzip -c < ${Y}.gz | 1968db6b0a61SColin Percival ${SHA256} -q` = ${Y} ]; then 1969db6b0a61SColin Percival mv ${Y}.gz files/${Y}.gz 1970db6b0a61SColin Percival else 1971db6b0a61SColin Percival echo "${Y} has incorrect hash." 1972db6b0a61SColin Percival return 1 1973db6b0a61SColin Percival fi 1974db6b0a61SColin Percival done < filelist 1975db6b0a61SColin Percival echo "done." 1976db6b0a61SColin Percival 1977db6b0a61SColin Percival # Clean up 1978db6b0a61SColin Percival rm filelist files.wanted 1979db6b0a61SColin Percival fi 1980db6b0a61SColin Percival} 1981db6b0a61SColin Percival 198248ffe56aSColin Percival# Prepare to fetch files: Generate a list of the files we need, 198348ffe56aSColin Percival# copy the unmodified files we have into /files/, and generate 198448ffe56aSColin Percival# a list of patches to download. 198548ffe56aSColin Percivalfetch_files_prepare () { 198648ffe56aSColin Percival # Tell the user why his disk is suddenly making lots of noise 198748ffe56aSColin Percival echo -n "Preparing to download files... " 198848ffe56aSColin Percival 198948ffe56aSColin Percival # Reduce indices to ${PATH}|${HASH} pairs 199048ffe56aSColin Percival for X in $1 $2 $3; do 199148ffe56aSColin Percival cut -f 1,2,7 -d '|' < ${X} | 199248ffe56aSColin Percival fgrep '|f|' | 199348ffe56aSColin Percival cut -f 1,3 -d '|' | 199448ffe56aSColin Percival sort > ${X}.hashes 199548ffe56aSColin Percival done 199648ffe56aSColin Percival 199748ffe56aSColin Percival # List of files wanted 199848ffe56aSColin Percival cut -f 2 -d '|' < $3.hashes | 19992328d598SColin Percival sort -u | 20002328d598SColin Percival while read HASH; do 20012328d598SColin Percival if ! [ -f files/${HASH}.gz ]; then 20022328d598SColin Percival echo ${HASH} 20032328d598SColin Percival fi 20042328d598SColin Percival done > files.wanted 200548ffe56aSColin Percival 200648ffe56aSColin Percival # Generate a list of unmodified files 200748ffe56aSColin Percival comm -12 $1.hashes $2.hashes | 200848ffe56aSColin Percival sort -k 1,1 -t '|' > unmodified.files 200948ffe56aSColin Percival 201048ffe56aSColin Percival # Copy all files into /files/. We only need the unmodified files 201148ffe56aSColin Percival # for use in patching; but we'll want all of them if the user asks 201248ffe56aSColin Percival # to rollback the updates later. 2013210b8123SColin Percival while read LINE; do 2014210b8123SColin Percival F=`echo "${LINE}" | cut -f 1 -d '|'` 2015210b8123SColin Percival HASH=`echo "${LINE}" | cut -f 2 -d '|'` 2016210b8123SColin Percival 2017210b8123SColin Percival # Skip files we already have. 2018210b8123SColin Percival if [ -f files/${HASH}.gz ]; then 2019210b8123SColin Percival continue 2020210b8123SColin Percival fi 2021210b8123SColin Percival 2022210b8123SColin Percival # Make sure the file hasn't changed. 202348ffe56aSColin Percival cp "${BASEDIR}/${F}" tmpfile 2024210b8123SColin Percival if [ `sha256 -q tmpfile` != ${HASH} ]; then 2025210b8123SColin Percival echo 2026210b8123SColin Percival echo "File changed while FreeBSD Update running: ${F}" 2027210b8123SColin Percival return 1 2028210b8123SColin Percival fi 2029210b8123SColin Percival 2030210b8123SColin Percival # Place the file into storage. 2031210b8123SColin Percival gzip -c < tmpfile > files/${HASH}.gz 203248ffe56aSColin Percival rm tmpfile 2033210b8123SColin Percival done < $2.hashes 203448ffe56aSColin Percival 203548ffe56aSColin Percival # Produce a list of patches to download 203648ffe56aSColin Percival sort -k 1,1 -t '|' $3.hashes | 203748ffe56aSColin Percival join -t '|' -o 2.2,1.2 - unmodified.files | 203848ffe56aSColin Percival fetch_make_patchlist > patchlist 203948ffe56aSColin Percival 204048ffe56aSColin Percival # Garbage collect 204148ffe56aSColin Percival rm unmodified.files $1.hashes $2.hashes $3.hashes 204248ffe56aSColin Percival 204348ffe56aSColin Percival # We don't need the list of possible old files any more. 204448ffe56aSColin Percival rm $1 204548ffe56aSColin Percival 204648ffe56aSColin Percival # We're finished making noise 204748ffe56aSColin Percival echo "done." 204848ffe56aSColin Percival} 204948ffe56aSColin Percival 205048ffe56aSColin Percival# Fetch files. 205148ffe56aSColin Percivalfetch_files () { 205248ffe56aSColin Percival # Attempt to fetch patches 205348ffe56aSColin Percival if [ -s patchlist ]; then 205448ffe56aSColin Percival echo -n "Fetching `wc -l < patchlist | tr -d ' '` " 205548ffe56aSColin Percival echo ${NDEBUG} "patches.${DDSTATS}" 205648ffe56aSColin Percival tr '|' '-' < patchlist | 2057db6b0a61SColin Percival lam -s "${PATCHDIR}/" - | 205848ffe56aSColin Percival xargs ${XARGST} ${PHTTPGET} ${SERVERNAME} \ 205948ffe56aSColin Percival 2>${STATSREDIR} | fetch_progress 206048ffe56aSColin Percival echo "done." 206148ffe56aSColin Percival 206248ffe56aSColin Percival # Attempt to apply patches 206348ffe56aSColin Percival echo -n "Applying patches... " 206448ffe56aSColin Percival tr '|' ' ' < patchlist | 206548ffe56aSColin Percival while read X Y; do 206648ffe56aSColin Percival if [ ! -f "${X}-${Y}" ]; then continue; fi 206748ffe56aSColin Percival gunzip -c < files/${X}.gz > OLD 206848ffe56aSColin Percival 206948ffe56aSColin Percival bspatch OLD NEW ${X}-${Y} 207048ffe56aSColin Percival 207148ffe56aSColin Percival if [ `${SHA256} -q NEW` = ${Y} ]; then 207248ffe56aSColin Percival mv NEW files/${Y} 207348ffe56aSColin Percival gzip -n files/${Y} 207448ffe56aSColin Percival fi 207548ffe56aSColin Percival rm -f diff OLD NEW ${X}-${Y} 207648ffe56aSColin Percival done 2>${QUIETREDIR} 207748ffe56aSColin Percival echo "done." 207848ffe56aSColin Percival fi 207948ffe56aSColin Percival 208048ffe56aSColin Percival # Download files which couldn't be generate via patching 208148ffe56aSColin Percival while read Y; do 208248ffe56aSColin Percival if [ ! -f "files/${Y}.gz" ]; then 208348ffe56aSColin Percival echo ${Y}; 208448ffe56aSColin Percival fi 208548ffe56aSColin Percival done < files.wanted > filelist 208648ffe56aSColin Percival 208748ffe56aSColin Percival if [ -s filelist ]; then 208848ffe56aSColin Percival echo -n "Fetching `wc -l < filelist | tr -d ' '` " 208948ffe56aSColin Percival echo ${NDEBUG} "files... " 209048ffe56aSColin Percival lam -s "${FETCHDIR}/f/" - -s ".gz" < filelist | 209148ffe56aSColin Percival xargs ${XARGST} ${PHTTPGET} ${SERVERNAME} \ 2092d6e1e31aSConrad Meyer 2>${STATSREDIR} | fetch_progress 209348ffe56aSColin Percival 209448ffe56aSColin Percival while read Y; do 209548ffe56aSColin Percival if ! [ -f ${Y}.gz ]; then 209648ffe56aSColin Percival echo "failed." 209748ffe56aSColin Percival return 1 209848ffe56aSColin Percival fi 209948ffe56aSColin Percival if [ `gunzip -c < ${Y}.gz | 210048ffe56aSColin Percival ${SHA256} -q` = ${Y} ]; then 210148ffe56aSColin Percival mv ${Y}.gz files/${Y}.gz 210248ffe56aSColin Percival else 210348ffe56aSColin Percival echo "${Y} has incorrect hash." 210448ffe56aSColin Percival return 1 210548ffe56aSColin Percival fi 210648ffe56aSColin Percival done < filelist 210748ffe56aSColin Percival echo "done." 210848ffe56aSColin Percival fi 210948ffe56aSColin Percival 211048ffe56aSColin Percival # Clean up 211148ffe56aSColin Percival rm files.wanted filelist patchlist 211248ffe56aSColin Percival} 211348ffe56aSColin Percival 211448ffe56aSColin Percival# Create and populate install manifest directory; and report what updates 211548ffe56aSColin Percival# are available. 211648ffe56aSColin Percivalfetch_create_manifest () { 211748ffe56aSColin Percival # If we have an existing install manifest, nuke it. 211848ffe56aSColin Percival if [ -L "${BDHASH}-install" ]; then 211948ffe56aSColin Percival rm -r ${BDHASH}-install/ 212048ffe56aSColin Percival rm ${BDHASH}-install 212148ffe56aSColin Percival fi 212248ffe56aSColin Percival 212348ffe56aSColin Percival # Report to the user if any updates were avoided due to local changes 212448ffe56aSColin Percival if [ -s modifiedfiles ]; then 2125fc24ba59SEd Maste cat - modifiedfiles <<- EOF | ${PAGER} 2126b882e02bSEnji Cooper The following files are affected by updates. No changes have 2127b882e02bSEnji Cooper been downloaded, however, because the files have been modified 2128b882e02bSEnji Cooper locally: 2129fc24ba59SEd Maste EOF 2130fc24ba59SEd Maste fi 213148ffe56aSColin Percival rm modifiedfiles 213248ffe56aSColin Percival 213348ffe56aSColin Percival # If no files will be updated, tell the user and exit 213448ffe56aSColin Percival if ! [ -s INDEX-PRESENT ] && 213548ffe56aSColin Percival ! [ -s INDEX-NEW ]; then 213648ffe56aSColin Percival rm INDEX-PRESENT INDEX-NEW 213748ffe56aSColin Percival echo 213848ffe56aSColin Percival echo -n "No updates needed to update system to " 213948ffe56aSColin Percival echo "${RELNUM}-p${RELPATCHNUM}." 214048ffe56aSColin Percival return 214148ffe56aSColin Percival fi 214248ffe56aSColin Percival 214348ffe56aSColin Percival # Divide files into (a) removed files, (b) added files, and 214448ffe56aSColin Percival # (c) updated files. 214548ffe56aSColin Percival cut -f 1 -d '|' < INDEX-PRESENT | 214648ffe56aSColin Percival sort > INDEX-PRESENT.flist 214748ffe56aSColin Percival cut -f 1 -d '|' < INDEX-NEW | 214848ffe56aSColin Percival sort > INDEX-NEW.flist 214948ffe56aSColin Percival comm -23 INDEX-PRESENT.flist INDEX-NEW.flist > files.removed 215048ffe56aSColin Percival comm -13 INDEX-PRESENT.flist INDEX-NEW.flist > files.added 215148ffe56aSColin Percival comm -12 INDEX-PRESENT.flist INDEX-NEW.flist > files.updated 215248ffe56aSColin Percival rm INDEX-PRESENT.flist INDEX-NEW.flist 215348ffe56aSColin Percival 215448ffe56aSColin Percival # Report removed files, if any 215548ffe56aSColin Percival if [ -s files.removed ]; then 2156fc24ba59SEd Maste cat - files.removed <<- EOF | ${PAGER} 2157fc24ba59SEd Maste The following files will be removed as part of updating to 2158fc24ba59SEd Maste ${RELNUM}-p${RELPATCHNUM}: 2159fc24ba59SEd Maste EOF 2160fc24ba59SEd Maste fi 216148ffe56aSColin Percival rm files.removed 216248ffe56aSColin Percival 216348ffe56aSColin Percival # Report added files, if any 216448ffe56aSColin Percival if [ -s files.added ]; then 2165fc24ba59SEd Maste cat - files.added <<- EOF | ${PAGER} 2166fc24ba59SEd Maste The following files will be added as part of updating to 2167fc24ba59SEd Maste ${RELNUM}-p${RELPATCHNUM}: 2168fc24ba59SEd Maste EOF 2169fc24ba59SEd Maste fi 217048ffe56aSColin Percival rm files.added 217148ffe56aSColin Percival 217248ffe56aSColin Percival # Report updated files, if any 217348ffe56aSColin Percival if [ -s files.updated ]; then 2174fc24ba59SEd Maste cat - files.updated <<- EOF | ${PAGER} 2175fc24ba59SEd Maste The following files will be updated as part of updating to 2176fc24ba59SEd Maste ${RELNUM}-p${RELPATCHNUM}: 2177fc24ba59SEd Maste EOF 2178fc24ba59SEd Maste fi 217948ffe56aSColin Percival rm files.updated 218048ffe56aSColin Percival 218148ffe56aSColin Percival # Create a directory for the install manifest. 218248ffe56aSColin Percival MDIR=`mktemp -d install.XXXXXX` || return 1 218348ffe56aSColin Percival 218448ffe56aSColin Percival # Populate it 218548ffe56aSColin Percival mv INDEX-PRESENT ${MDIR}/INDEX-OLD 218648ffe56aSColin Percival mv INDEX-NEW ${MDIR}/INDEX-NEW 218748ffe56aSColin Percival 218848ffe56aSColin Percival # Link it into place 218948ffe56aSColin Percival ln -s ${MDIR} ${BDHASH}-install 219048ffe56aSColin Percival} 219148ffe56aSColin Percival 219248ffe56aSColin Percival# Warn about any upcoming EoL 219348ffe56aSColin Percivalfetch_warn_eol () { 219448ffe56aSColin Percival # What's the current time? 219548ffe56aSColin Percival NOWTIME=`date "+%s"` 219648ffe56aSColin Percival 219748ffe56aSColin Percival # When did we last warn about the EoL date? 219848ffe56aSColin Percival if [ -f lasteolwarn ]; then 219948ffe56aSColin Percival LASTWARN=`cat lasteolwarn` 220048ffe56aSColin Percival else 220148ffe56aSColin Percival LASTWARN=`expr ${NOWTIME} - 63072000` 220248ffe56aSColin Percival fi 220348ffe56aSColin Percival 220448ffe56aSColin Percival # If the EoL time is past, warn. 220548ffe56aSColin Percival if [ ${EOLTIME} -lt ${NOWTIME} ]; then 220648ffe56aSColin Percival echo 220748ffe56aSColin Percival cat <<-EOF 2208b698a3abSColin Percival WARNING: `uname -sr` HAS PASSED ITS END-OF-LIFE DATE. 220948ffe56aSColin Percival Any security issues discovered after `date -r ${EOLTIME}` 221048ffe56aSColin Percival will not have been corrected. 221148ffe56aSColin Percival EOF 221248ffe56aSColin Percival return 1 221348ffe56aSColin Percival fi 221448ffe56aSColin Percival 221548ffe56aSColin Percival # Figure out how long it has been since we last warned about the 221648ffe56aSColin Percival # upcoming EoL, and how much longer we have left. 221748ffe56aSColin Percival SINCEWARN=`expr ${NOWTIME} - ${LASTWARN}` 221848ffe56aSColin Percival TIMELEFT=`expr ${EOLTIME} - ${NOWTIME}` 221948ffe56aSColin Percival 222089b14566SColin Percival # Don't warn if the EoL is more than 3 months away 222189b14566SColin Percival if [ ${TIMELEFT} -gt 7884000 ]; then 222248ffe56aSColin Percival return 0 222348ffe56aSColin Percival fi 222448ffe56aSColin Percival 222548ffe56aSColin Percival # Don't warn if the time remaining is more than 3 times the time 222648ffe56aSColin Percival # since the last warning. 222748ffe56aSColin Percival if [ ${TIMELEFT} -gt `expr ${SINCEWARN} \* 3` ]; then 222848ffe56aSColin Percival return 0 222948ffe56aSColin Percival fi 223048ffe56aSColin Percival 223148ffe56aSColin Percival # Figure out what time units to use. 223248ffe56aSColin Percival if [ ${TIMELEFT} -lt 604800 ]; then 223348ffe56aSColin Percival UNIT="day" 223448ffe56aSColin Percival SIZE=86400 223548ffe56aSColin Percival elif [ ${TIMELEFT} -lt 2678400 ]; then 223648ffe56aSColin Percival UNIT="week" 223748ffe56aSColin Percival SIZE=604800 223848ffe56aSColin Percival else 223948ffe56aSColin Percival UNIT="month" 224048ffe56aSColin Percival SIZE=2678400 224148ffe56aSColin Percival fi 224248ffe56aSColin Percival 224348ffe56aSColin Percival # Compute the right number of units 224448ffe56aSColin Percival NUM=`expr ${TIMELEFT} / ${SIZE}` 224548ffe56aSColin Percival if [ ${NUM} != 1 ]; then 224648ffe56aSColin Percival UNIT="${UNIT}s" 224748ffe56aSColin Percival fi 224848ffe56aSColin Percival 224948ffe56aSColin Percival # Print the warning 225048ffe56aSColin Percival echo 225148ffe56aSColin Percival cat <<-EOF 225248ffe56aSColin Percival WARNING: `uname -sr` is approaching its End-of-Life date. 225348ffe56aSColin Percival It is strongly recommended that you upgrade to a newer 225448ffe56aSColin Percival release within the next ${NUM} ${UNIT}. 225548ffe56aSColin Percival EOF 225648ffe56aSColin Percival 225748ffe56aSColin Percival # Update the stored time of last warning 225848ffe56aSColin Percival echo ${NOWTIME} > lasteolwarn 225948ffe56aSColin Percival} 226048ffe56aSColin Percival 226148ffe56aSColin Percival# Do the actual work involved in "fetch" / "cron". 226248ffe56aSColin Percivalfetch_run () { 226348ffe56aSColin Percival workdir_init || return 1 226448ffe56aSColin Percival 226548ffe56aSColin Percival # Prepare the mirror list. 226648ffe56aSColin Percival fetch_pick_server_init && fetch_pick_server 226748ffe56aSColin Percival 226848ffe56aSColin Percival # Try to fetch the public key until we run out of servers. 226948ffe56aSColin Percival while ! fetch_key; do 227048ffe56aSColin Percival fetch_pick_server || return 1 227148ffe56aSColin Percival done 227248ffe56aSColin Percival 227348ffe56aSColin Percival # Try to fetch the metadata index signature ("tag") until we run 227448ffe56aSColin Percival # out of available servers; and sanity check the downloaded tag. 227548ffe56aSColin Percival while ! fetch_tag; do 227648ffe56aSColin Percival fetch_pick_server || return 1 227748ffe56aSColin Percival done 227848ffe56aSColin Percival fetch_tagsanity || return 1 227948ffe56aSColin Percival 228048ffe56aSColin Percival # Fetch the latest INDEX-NEW and INDEX-OLD files. 228148ffe56aSColin Percival fetch_metadata INDEX-NEW INDEX-OLD || return 1 228248ffe56aSColin Percival 228348ffe56aSColin Percival # Generate filtered INDEX-NEW and INDEX-OLD files containing only 228448ffe56aSColin Percival # the lines which (a) belong to components we care about, and (b) 228548ffe56aSColin Percival # don't correspond to paths we're explicitly ignoring. 228648ffe56aSColin Percival fetch_filter_metadata INDEX-NEW || return 1 228748ffe56aSColin Percival fetch_filter_metadata INDEX-OLD || return 1 228848ffe56aSColin Percival 2289db6b0a61SColin Percival # Translate /boot/${KERNCONF} into ${KERNELDIR} 2290db6b0a61SColin Percival fetch_filter_kernel_names INDEX-NEW ${KERNCONF} 2291db6b0a61SColin Percival fetch_filter_kernel_names INDEX-OLD ${KERNCONF} 229248ffe56aSColin Percival 229348ffe56aSColin Percival # For all paths appearing in INDEX-OLD or INDEX-NEW, inspect the 229448ffe56aSColin Percival # system and generate an INDEX-PRESENT file. 229548ffe56aSColin Percival fetch_inspect_system INDEX-OLD INDEX-PRESENT INDEX-NEW || return 1 229648ffe56aSColin Percival 229748ffe56aSColin Percival # Based on ${UPDATEIFUNMODIFIED}, remove lines from INDEX-* which 229848ffe56aSColin Percival # correspond to lines in INDEX-PRESENT with hashes not appearing 229948ffe56aSColin Percival # in INDEX-OLD or INDEX-NEW. Also remove lines where the entry in 230048ffe56aSColin Percival # INDEX-PRESENT has type - and there isn't a corresponding entry in 230148ffe56aSColin Percival # INDEX-OLD with type -. 2302db6b0a61SColin Percival fetch_filter_unmodified_notpresent \ 2303db6b0a61SColin Percival INDEX-OLD INDEX-PRESENT INDEX-NEW /dev/null 230448ffe56aSColin Percival 230548ffe56aSColin Percival # For each entry in INDEX-PRESENT of type -, remove any corresponding 230648ffe56aSColin Percival # entry from INDEX-NEW if ${ALLOWADD} != "yes". Remove all entries 230748ffe56aSColin Percival # of type - from INDEX-PRESENT. 230848ffe56aSColin Percival fetch_filter_allowadd INDEX-PRESENT INDEX-NEW 230948ffe56aSColin Percival 231048ffe56aSColin Percival # If ${ALLOWDELETE} != "yes", then remove any entries from 231148ffe56aSColin Percival # INDEX-PRESENT which don't correspond to entries in INDEX-NEW. 231248ffe56aSColin Percival fetch_filter_allowdelete INDEX-PRESENT INDEX-NEW 231348ffe56aSColin Percival 231448ffe56aSColin Percival # If ${KEEPMODIFIEDMETADATA} == "yes", then for each entry in 231548ffe56aSColin Percival # INDEX-PRESENT with metadata not matching any entry in INDEX-OLD, 231648ffe56aSColin Percival # replace the corresponding line of INDEX-NEW with one having the 231748ffe56aSColin Percival # same metadata as the entry in INDEX-PRESENT. 231848ffe56aSColin Percival fetch_filter_modified_metadata INDEX-OLD INDEX-PRESENT INDEX-NEW 231948ffe56aSColin Percival 232048ffe56aSColin Percival # Remove lines from INDEX-PRESENT and INDEX-NEW which are identical; 232148ffe56aSColin Percival # no need to update a file if it isn't changing. 232248ffe56aSColin Percival fetch_filter_uptodate INDEX-PRESENT INDEX-NEW 232348ffe56aSColin Percival 232448ffe56aSColin Percival # Prepare to fetch files: Generate a list of the files we need, 232548ffe56aSColin Percival # copy the unmodified files we have into /files/, and generate 232648ffe56aSColin Percival # a list of patches to download. 2327210b8123SColin Percival fetch_files_prepare INDEX-OLD INDEX-PRESENT INDEX-NEW || return 1 232848ffe56aSColin Percival 232948ffe56aSColin Percival # Fetch files. 233048ffe56aSColin Percival fetch_files || return 1 233148ffe56aSColin Percival 233248ffe56aSColin Percival # Create and populate install manifest directory; and report what 233348ffe56aSColin Percival # updates are available. 233448ffe56aSColin Percival fetch_create_manifest || return 1 233548ffe56aSColin Percival 233648ffe56aSColin Percival # Warn about any upcoming EoL 233748ffe56aSColin Percival fetch_warn_eol || return 1 233848ffe56aSColin Percival} 233948ffe56aSColin Percival 2340db6b0a61SColin Percival# If StrictComponents is not "yes", generate a new components list 2341db6b0a61SColin Percival# with only the components which appear to be installed. 2342db6b0a61SColin Percivalupgrade_guess_components () { 2343db6b0a61SColin Percival if [ "${STRICTCOMPONENTS}" = "no" ]; then 2344db6b0a61SColin Percival # Generate filtered INDEX-ALL with only the components listed 2345db6b0a61SColin Percival # in COMPONENTS. 2346db6b0a61SColin Percival fetch_filter_metadata_components $1 || return 1 2347db6b0a61SColin Percival 2348db6b0a61SColin Percival # Tell the user why his disk is suddenly making lots of noise 2349db6b0a61SColin Percival echo -n "Inspecting system... " 2350db6b0a61SColin Percival 2351db6b0a61SColin Percival # Look at the files on disk, and assume that a component is 2352db6b0a61SColin Percival # supposed to be present if it is more than half-present. 2353db6b0a61SColin Percival cut -f 1-3 -d '|' < INDEX-ALL | 2354db6b0a61SColin Percival tr '|' ' ' | 2355db6b0a61SColin Percival while read C S F; do 2356db6b0a61SColin Percival if [ -e ${BASEDIR}/${F} ]; then 2357db6b0a61SColin Percival echo "+ ${C}|${S}" 2358db6b0a61SColin Percival fi 2359db6b0a61SColin Percival echo "= ${C}|${S}" 2360db6b0a61SColin Percival done | 2361db6b0a61SColin Percival sort | 2362db6b0a61SColin Percival uniq -c | 2363db6b0a61SColin Percival sed -E 's,^ +,,' > compfreq 2364db6b0a61SColin Percival grep ' = ' compfreq | 2365db6b0a61SColin Percival cut -f 1,3 -d ' ' | 2366db6b0a61SColin Percival sort -k 2,2 -t ' ' > compfreq.total 2367db6b0a61SColin Percival grep ' + ' compfreq | 2368db6b0a61SColin Percival cut -f 1,3 -d ' ' | 2369db6b0a61SColin Percival sort -k 2,2 -t ' ' > compfreq.present 2370db6b0a61SColin Percival join -t ' ' -1 2 -2 2 compfreq.present compfreq.total | 2371db6b0a61SColin Percival while read S P T; do 2372ae97aa98SEd Maste if [ ${T} -ne 0 -a ${P} -gt `expr ${T} / 2` ]; then 2373db6b0a61SColin Percival echo ${S} 2374db6b0a61SColin Percival fi 2375db6b0a61SColin Percival done > comp.present 2376db6b0a61SColin Percival cut -f 2 -d ' ' < compfreq.total > comp.total 2377db6b0a61SColin Percival rm INDEX-ALL compfreq compfreq.total compfreq.present 2378db6b0a61SColin Percival 2379db6b0a61SColin Percival # We're done making noise. 2380db6b0a61SColin Percival echo "done." 2381db6b0a61SColin Percival 2382db6b0a61SColin Percival # Sometimes the kernel isn't installed where INDEX-ALL 2383db6b0a61SColin Percival # thinks that it should be: In particular, it is often in 2384db6b0a61SColin Percival # /boot/kernel instead of /boot/GENERIC or /boot/SMP. To 2385db6b0a61SColin Percival # deal with this, if "kernel|X" is listed in comp.total 2386db6b0a61SColin Percival # (i.e., is a component which would be upgraded if it is 2387db6b0a61SColin Percival # found to be present) we will add it to comp.present. 2388db6b0a61SColin Percival # If "kernel|<anything>" is in comp.total but "kernel|X" is 2389db6b0a61SColin Percival # not, we print a warning -- the user is running a kernel 2390db6b0a61SColin Percival # which isn't part of the release. 2391db6b0a61SColin Percival KCOMP=`echo ${KERNCONF} | tr 'A-Z' 'a-z'` 2392db6b0a61SColin Percival grep -E "^kernel\|${KCOMP}\$" comp.total >> comp.present 2393db6b0a61SColin Percival 2394db6b0a61SColin Percival if grep -qE "^kernel\|" comp.total && 2395db6b0a61SColin Percival ! grep -qE "^kernel\|${KCOMP}\$" comp.total; then 2396db6b0a61SColin Percival cat <<-EOF 2397db6b0a61SColin Percival 2398db6b0a61SColin PercivalWARNING: This system is running a "${KCOMP}" kernel, which is not a 2399db6b0a61SColin Percivalkernel configuration distributed as part of FreeBSD ${RELNUM}. 2400db6b0a61SColin PercivalThis kernel will not be updated: you MUST update the kernel manually 240159b02bb4SMichael Osipovbefore running '`basename $0` [options] install'. 2402db6b0a61SColin Percival EOF 2403db6b0a61SColin Percival fi 2404db6b0a61SColin Percival 2405db6b0a61SColin Percival # Re-sort the list of installed components and generate 2406db6b0a61SColin Percival # the list of non-installed components. 2407db6b0a61SColin Percival sort -u < comp.present > comp.present.tmp 2408db6b0a61SColin Percival mv comp.present.tmp comp.present 2409db6b0a61SColin Percival comm -13 comp.present comp.total > comp.absent 2410db6b0a61SColin Percival 2411db6b0a61SColin Percival # Ask the user to confirm that what we have is correct. To 2412db6b0a61SColin Percival # reduce user confusion, translate "X|Y" back to "X/Y" (as 2413db6b0a61SColin Percival # subcomponents must be listed in the configuration file). 2414db6b0a61SColin Percival echo 2415db6b0a61SColin Percival echo -n "The following components of FreeBSD " 2416db6b0a61SColin Percival echo "seem to be installed:" 2417db6b0a61SColin Percival tr '|' '/' < comp.present | 2418db6b0a61SColin Percival fmt -72 2419db6b0a61SColin Percival echo 2420db6b0a61SColin Percival echo -n "The following components of FreeBSD " 2421db6b0a61SColin Percival echo "do not seem to be installed:" 2422db6b0a61SColin Percival tr '|' '/' < comp.absent | 2423db6b0a61SColin Percival fmt -72 2424db6b0a61SColin Percival echo 2425db6b0a61SColin Percival continuep || return 1 2426db6b0a61SColin Percival echo 2427db6b0a61SColin Percival 2428db6b0a61SColin Percival # Suck the generated list of components into ${COMPONENTS}. 2429db6b0a61SColin Percival # Note that comp.present.tmp is used due to issues with 2430db6b0a61SColin Percival # pipelines and setting variables. 2431db6b0a61SColin Percival COMPONENTS="" 2432db6b0a61SColin Percival tr '|' '/' < comp.present > comp.present.tmp 2433db6b0a61SColin Percival while read C; do 2434db6b0a61SColin Percival COMPONENTS="${COMPONENTS} ${C}" 2435db6b0a61SColin Percival done < comp.present.tmp 2436db6b0a61SColin Percival 2437db6b0a61SColin Percival # Delete temporary files 2438db6b0a61SColin Percival rm comp.present comp.present.tmp comp.absent comp.total 2439db6b0a61SColin Percival fi 2440db6b0a61SColin Percival} 2441db6b0a61SColin Percival 2442db6b0a61SColin Percival# If StrictComponents is not "yes", COMPONENTS contains an entry 2443db6b0a61SColin Percival# corresponding to the currently running kernel, and said kernel 2444db6b0a61SColin Percival# does not exist in the new release, add "kernel/generic" to the 2445db6b0a61SColin Percival# list of components. 2446db6b0a61SColin Percivalupgrade_guess_new_kernel () { 2447db6b0a61SColin Percival if [ "${STRICTCOMPONENTS}" = "no" ]; then 2448db6b0a61SColin Percival # Grab the unfiltered metadata file. 2449db6b0a61SColin Percival METAHASH=`look "$1|" tINDEX.present | cut -f 2 -d '|'` 2450db6b0a61SColin Percival gunzip -c < files/${METAHASH}.gz > $1.all 2451db6b0a61SColin Percival 2452db6b0a61SColin Percival # If "kernel/${KCOMP}" is in ${COMPONENTS} and that component 2453db6b0a61SColin Percival # isn't in $1.all, we need to add kernel/generic. 2454db6b0a61SColin Percival for C in ${COMPONENTS}; do 2455db6b0a61SColin Percival if [ ${C} = "kernel/${KCOMP}" ] && 2456db6b0a61SColin Percival ! grep -qE "^kernel\|${KCOMP}\|" $1.all; then 2457db6b0a61SColin Percival COMPONENTS="${COMPONENTS} kernel/generic" 2458db6b0a61SColin Percival NKERNCONF="GENERIC" 2459db6b0a61SColin Percival cat <<-EOF 2460db6b0a61SColin Percival 2461db6b0a61SColin PercivalWARNING: This system is running a "${KCOMP}" kernel, which is not a 2462db6b0a61SColin Percivalkernel configuration distributed as part of FreeBSD ${RELNUM}. 2463db6b0a61SColin PercivalAs part of upgrading to FreeBSD ${RELNUM}, this kernel will be 2464db6b0a61SColin Percivalreplaced with a "generic" kernel. 2465db6b0a61SColin Percival EOF 2466db6b0a61SColin Percival continuep || return 1 2467db6b0a61SColin Percival fi 2468db6b0a61SColin Percival done 2469db6b0a61SColin Percival 2470db6b0a61SColin Percival # Don't need this any more... 2471db6b0a61SColin Percival rm $1.all 2472db6b0a61SColin Percival fi 2473db6b0a61SColin Percival} 2474db6b0a61SColin Percival 2475db6b0a61SColin Percival# Convert INDEX-OLD (last release) and INDEX-ALL (new release) into 2476db6b0a61SColin Percival# INDEX-OLD and INDEX-NEW files (in the sense of normal upgrades). 2477db6b0a61SColin Percivalupgrade_oldall_to_oldnew () { 2478db6b0a61SColin Percival # For each ${F}|... which appears in INDEX-ALL but does not appear 2479db6b0a61SColin Percival # in INDEX-OLD, add ${F}|-|||||| to INDEX-OLD. 2480db6b0a61SColin Percival cut -f 1 -d '|' < $1 | 2481db6b0a61SColin Percival sort -u > $1.paths 2482db6b0a61SColin Percival cut -f 1 -d '|' < $2 | 2483db6b0a61SColin Percival sort -u | 2484db6b0a61SColin Percival comm -13 $1.paths - | 2485db6b0a61SColin Percival lam - -s "|-||||||" | 2486db6b0a61SColin Percival sort - $1 > $1.tmp 2487db6b0a61SColin Percival mv $1.tmp $1 2488db6b0a61SColin Percival 2489db6b0a61SColin Percival # Remove lines from INDEX-OLD which also appear in INDEX-ALL 2490db6b0a61SColin Percival comm -23 $1 $2 > $1.tmp 2491db6b0a61SColin Percival mv $1.tmp $1 2492db6b0a61SColin Percival 2493db6b0a61SColin Percival # Remove lines from INDEX-ALL which have a file name not appearing 2494db6b0a61SColin Percival # anywhere in INDEX-OLD (since these must be files which haven't 2495db6b0a61SColin Percival # changed -- if they were new, there would be an entry of type "-"). 2496db6b0a61SColin Percival cut -f 1 -d '|' < $1 | 2497db6b0a61SColin Percival sort -u > $1.paths 2498db6b0a61SColin Percival sort -k 1,1 -t '|' < $2 | 2499db6b0a61SColin Percival join -t '|' - $1.paths | 2500db6b0a61SColin Percival sort > $2.tmp 2501db6b0a61SColin Percival rm $1.paths 2502db6b0a61SColin Percival mv $2.tmp $2 2503db6b0a61SColin Percival 2504db6b0a61SColin Percival # Rename INDEX-ALL to INDEX-NEW. 2505db6b0a61SColin Percival mv $2 $3 2506db6b0a61SColin Percival} 2507db6b0a61SColin Percival 25087449d2f5SColin Percival# Helper for upgrade_merge: Return zero true iff the two files differ only 25096d514f10SDag-Erling Smørgrav# in the contents of their RCS tags. 25107449d2f5SColin Percivalsamef () { 25117449d2f5SColin Percival X=`sed -E 's/\\$FreeBSD.*\\$/\$FreeBSD\$/' < $1 | ${SHA256}` 25127449d2f5SColin Percival Y=`sed -E 's/\\$FreeBSD.*\\$/\$FreeBSD\$/' < $2 | ${SHA256}` 25137449d2f5SColin Percival 25147449d2f5SColin Percival if [ $X = $Y ]; then 25157449d2f5SColin Percival return 0; 25167449d2f5SColin Percival else 25177449d2f5SColin Percival return 1; 25187449d2f5SColin Percival fi 25197449d2f5SColin Percival} 25207449d2f5SColin Percival 2521db6b0a61SColin Percival# From the list of "old" files in $1, merge changes in $2 with those in $3, 2522db6b0a61SColin Percival# and update $3 to reflect the hashes of merged files. 2523db6b0a61SColin Percivalupgrade_merge () { 2524db6b0a61SColin Percival # We only need to do anything if $1 is non-empty. 2525db6b0a61SColin Percival if [ -s $1 ]; then 2526db6b0a61SColin Percival cut -f 1 -d '|' $1 | 2527db6b0a61SColin Percival sort > $1-paths 2528db6b0a61SColin Percival 2529db6b0a61SColin Percival # Create staging area for merging files 2530db6b0a61SColin Percival rm -rf merge/ 2531db6b0a61SColin Percival while read F; do 2532db6b0a61SColin Percival D=`dirname ${F}` 2533db6b0a61SColin Percival mkdir -p merge/old/${D} 2534db6b0a61SColin Percival mkdir -p merge/${OLDRELNUM}/${D} 2535db6b0a61SColin Percival mkdir -p merge/${RELNUM}/${D} 2536db6b0a61SColin Percival mkdir -p merge/new/${D} 2537db6b0a61SColin Percival done < $1-paths 2538db6b0a61SColin Percival 2539db6b0a61SColin Percival # Copy in files 2540db6b0a61SColin Percival while read F; do 2541db6b0a61SColin Percival # Currently installed file 2542db6b0a61SColin Percival V=`look "${F}|" $2 | cut -f 7 -d '|'` 2543db6b0a61SColin Percival gunzip < files/${V}.gz > merge/old/${F} 2544db6b0a61SColin Percival 2545db6b0a61SColin Percival # Old release 2546db6b0a61SColin Percival if look "${F}|" $1 | fgrep -q "|f|"; then 2547db6b0a61SColin Percival V=`look "${F}|" $1 | cut -f 3 -d '|'` 2548db6b0a61SColin Percival gunzip < files/${V}.gz \ 2549db6b0a61SColin Percival > merge/${OLDRELNUM}/${F} 2550db6b0a61SColin Percival fi 2551db6b0a61SColin Percival 2552db6b0a61SColin Percival # New release 2553db6b0a61SColin Percival if look "${F}|" $3 | cut -f 1,2,7 -d '|' | 2554db6b0a61SColin Percival fgrep -q "|f|"; then 2555db6b0a61SColin Percival V=`look "${F}|" $3 | cut -f 7 -d '|'` 2556db6b0a61SColin Percival gunzip < files/${V}.gz \ 2557db6b0a61SColin Percival > merge/${RELNUM}/${F} 2558db6b0a61SColin Percival fi 2559db6b0a61SColin Percival done < $1-paths 2560db6b0a61SColin Percival 2561db6b0a61SColin Percival # Attempt to automatically merge changes 2562db6b0a61SColin Percival echo -n "Attempting to automatically merge " 2563db6b0a61SColin Percival echo -n "changes in files..." 2564db6b0a61SColin Percival : > failed.merges 2565db6b0a61SColin Percival while read F; do 2566db6b0a61SColin Percival # If the file doesn't exist in the new release, 2567db6b0a61SColin Percival # the result of "merging changes" is having the file 2568db6b0a61SColin Percival # not exist. 2569db6b0a61SColin Percival if ! [ -f merge/${RELNUM}/${F} ]; then 2570db6b0a61SColin Percival continue 2571db6b0a61SColin Percival fi 2572db6b0a61SColin Percival 2573db6b0a61SColin Percival # If the file didn't exist in the old release, we're 2574db6b0a61SColin Percival # going to throw away the existing file and hope that 2575db6b0a61SColin Percival # the version from the new release is what we want. 2576db6b0a61SColin Percival if ! [ -f merge/${OLDRELNUM}/${F} ]; then 2577db6b0a61SColin Percival cp merge/${RELNUM}/${F} merge/new/${F} 2578db6b0a61SColin Percival continue 2579db6b0a61SColin Percival fi 2580db6b0a61SColin Percival 2581db6b0a61SColin Percival # Some files need special treatment. 2582db6b0a61SColin Percival case ${F} in 2583db6b0a61SColin Percival /etc/spwd.db | /etc/pwd.db | /etc/login.conf.db) 2584db6b0a61SColin Percival # Don't merge these -- we're rebuild them 2585db6b0a61SColin Percival # after updates are installed. 2586db6b0a61SColin Percival cp merge/old/${F} merge/new/${F} 2587db6b0a61SColin Percival ;; 2588db6b0a61SColin Percival *) 2589073dd712SBaptiste Daroussin if ! diff3 -E -m -L "current version" \ 2590db6b0a61SColin Percival -L "${OLDRELNUM}" -L "${RELNUM}" \ 2591db6b0a61SColin Percival merge/old/${F} \ 2592db6b0a61SColin Percival merge/${OLDRELNUM}/${F} \ 2593db6b0a61SColin Percival merge/${RELNUM}/${F} \ 2594db6b0a61SColin Percival > merge/new/${F} 2>/dev/null; then 2595db6b0a61SColin Percival echo ${F} >> failed.merges 2596db6b0a61SColin Percival fi 2597db6b0a61SColin Percival ;; 2598db6b0a61SColin Percival esac 2599db6b0a61SColin Percival done < $1-paths 2600db6b0a61SColin Percival echo " done." 2601db6b0a61SColin Percival 2602db6b0a61SColin Percival # Ask the user to handle any files which didn't merge. 2603db6b0a61SColin Percival while read F; do 26047449d2f5SColin Percival # If the installed file differs from the version in 26056d514f10SDag-Erling Smørgrav # the old release only due to RCS tag expansion 26067449d2f5SColin Percival # then just use the version in the new release. 26077449d2f5SColin Percival if samef merge/old/${F} merge/${OLDRELNUM}/${F}; then 26087449d2f5SColin Percival cp merge/${RELNUM}/${F} merge/new/${F} 26097449d2f5SColin Percival continue 26107449d2f5SColin Percival fi 26117449d2f5SColin Percival 2612db6b0a61SColin Percival cat <<-EOF 2613db6b0a61SColin Percival 2614db6b0a61SColin PercivalThe following file could not be merged automatically: ${F} 2615db6b0a61SColin PercivalPress Enter to edit this file in ${EDITOR} and resolve the conflicts 2616db6b0a61SColin Percivalmanually... 2617db6b0a61SColin Percival EOF 2618ceb5f28bSEd Maste while true; do 26193d442415SEd Maste read response </dev/tty 26203d442415SEd Maste if expr "${response}" : '[Aa][Cc][Cc][Ee][Pp][Tt]' > /dev/null; then 26213d442415SEd Maste echo 26223d442415SEd Maste break 26233d442415SEd Maste fi 2624db6b0a61SColin Percival ${EDITOR} `pwd`/merge/new/${F} < /dev/tty 2625ceb5f28bSEd Maste 2626e27ded83SEd Maste if ! grep -qE '^(<<<<<<<|=======|>>>>>>>)([[:space:]].*)?$' $(pwd)/merge/new/${F} ; then 2627ceb5f28bSEd Maste break 2628ceb5f28bSEd Maste fi 2629ceb5f28bSEd Maste cat <<-EOF 2630ceb5f28bSEd Maste 2631ceb5f28bSEd MasteMerge conflict markers remain in: ${F} 2632ceb5f28bSEd MasteThese must be resolved for the system to be functional. 2633ceb5f28bSEd Maste 26343d442415SEd MastePress Enter to return to editing this file, or type "ACCEPT" to carry on with 26353d442415SEd Mastethese lines remaining in the file. 2636ceb5f28bSEd Maste EOF 2637ceb5f28bSEd Maste done 2638db6b0a61SColin Percival done < failed.merges 2639db6b0a61SColin Percival rm failed.merges 2640db6b0a61SColin Percival 2641db6b0a61SColin Percival # Ask the user to confirm that he likes how the result 2642db6b0a61SColin Percival # of merging files. 2643db6b0a61SColin Percival while read F; do 26447449d2f5SColin Percival # Skip files which haven't changed except possibly 26456d514f10SDag-Erling Smørgrav # in their RCS tags. 26467449d2f5SColin Percival if [ -f merge/old/${F} ] && [ -f merge/new/${F} ] && 26477449d2f5SColin Percival samef merge/old/${F} merge/new/${F}; then 26487449d2f5SColin Percival continue 26497449d2f5SColin Percival fi 26507449d2f5SColin Percival 26517449d2f5SColin Percival # Skip files where the installed file differs from 26526d514f10SDag-Erling Smørgrav # the old file only due to RCS tags. 26537449d2f5SColin Percival if [ -f merge/old/${F} ] && 26547449d2f5SColin Percival [ -f merge/${OLDRELNUM}/${F} ] && 26557449d2f5SColin Percival samef merge/old/${F} merge/${OLDRELNUM}/${F}; then 2656db6b0a61SColin Percival continue 2657db6b0a61SColin Percival fi 2658db6b0a61SColin Percival 2659db6b0a61SColin Percival # Warn about files which are ceasing to exist. 2660db6b0a61SColin Percival if ! [ -f merge/new/${F} ]; then 2661db6b0a61SColin Percival cat <<-EOF 2662db6b0a61SColin Percival 2663db6b0a61SColin PercivalThe following file will be removed, as it no longer exists in 2664db6b0a61SColin PercivalFreeBSD ${RELNUM}: ${F} 2665db6b0a61SColin Percival EOF 2666db6b0a61SColin Percival continuep < /dev/tty || return 1 2667db6b0a61SColin Percival continue 2668db6b0a61SColin Percival fi 2669db6b0a61SColin Percival 2670db6b0a61SColin Percival # Print changes for the user's approval. 2671db6b0a61SColin Percival cat <<-EOF 2672db6b0a61SColin Percival 2673db6b0a61SColin PercivalThe following changes, which occurred between FreeBSD ${OLDRELNUM} and 2674db6b0a61SColin PercivalFreeBSD ${RELNUM} have been merged into ${F}: 2675db6b0a61SColin PercivalEOF 2676db6b0a61SColin Percival diff -U 5 -L "current version" -L "new version" \ 2677db6b0a61SColin Percival merge/old/${F} merge/new/${F} || true 2678db6b0a61SColin Percival continuep < /dev/tty || return 1 2679db6b0a61SColin Percival done < $1-paths 2680db6b0a61SColin Percival 2681db6b0a61SColin Percival # Store merged files. 2682db6b0a61SColin Percival while read F; do 2683c58b62efSColin Percival if [ -f merge/new/${F} ]; then 2684db6b0a61SColin Percival V=`${SHA256} -q merge/new/${F}` 2685db6b0a61SColin Percival 2686db6b0a61SColin Percival gzip -c < merge/new/${F} > files/${V}.gz 2687db6b0a61SColin Percival echo "${F}|${V}" 2688db6b0a61SColin Percival fi 2689db6b0a61SColin Percival done < $1-paths > newhashes 2690db6b0a61SColin Percival 2691db6b0a61SColin Percival # Pull lines out from $3 which need to be updated to 2692db6b0a61SColin Percival # reflect merged files. 2693db6b0a61SColin Percival while read F; do 2694db6b0a61SColin Percival look "${F}|" $3 2695db6b0a61SColin Percival done < $1-paths > $3-oldlines 2696db6b0a61SColin Percival 2697db6b0a61SColin Percival # Update lines to reflect merged files 2698db6b0a61SColin Percival join -t '|' -o 1.1,1.2,1.3,1.4,1.5,1.6,2.2,1.8 \ 2699db6b0a61SColin Percival $3-oldlines newhashes > $3-newlines 2700db6b0a61SColin Percival 2701db6b0a61SColin Percival # Remove old lines from $3 and add new lines. 2702db6b0a61SColin Percival sort $3-oldlines | 2703db6b0a61SColin Percival comm -13 - $3 | 2704db6b0a61SColin Percival sort - $3-newlines > $3.tmp 2705db6b0a61SColin Percival mv $3.tmp $3 2706db6b0a61SColin Percival 2707db6b0a61SColin Percival # Clean up 2708db6b0a61SColin Percival rm $1-paths newhashes $3-oldlines $3-newlines 2709db6b0a61SColin Percival rm -rf merge/ 2710db6b0a61SColin Percival fi 2711db6b0a61SColin Percival 2712db6b0a61SColin Percival # We're done with merging files. 2713db6b0a61SColin Percival rm $1 2714db6b0a61SColin Percival} 2715db6b0a61SColin Percival 2716db6b0a61SColin Percival# Do the work involved in fetching upgrades to a new release 2717db6b0a61SColin Percivalupgrade_run () { 2718db6b0a61SColin Percival workdir_init || return 1 2719db6b0a61SColin Percival 2720db6b0a61SColin Percival # Prepare the mirror list. 2721db6b0a61SColin Percival fetch_pick_server_init && fetch_pick_server 2722db6b0a61SColin Percival 2723db6b0a61SColin Percival # Try to fetch the public key until we run out of servers. 2724db6b0a61SColin Percival while ! fetch_key; do 2725db6b0a61SColin Percival fetch_pick_server || return 1 2726db6b0a61SColin Percival done 2727db6b0a61SColin Percival 2728db6b0a61SColin Percival # Try to fetch the metadata index signature ("tag") until we run 2729db6b0a61SColin Percival # out of available servers; and sanity check the downloaded tag. 2730db6b0a61SColin Percival while ! fetch_tag; do 2731db6b0a61SColin Percival fetch_pick_server || return 1 2732db6b0a61SColin Percival done 2733db6b0a61SColin Percival fetch_tagsanity || return 1 2734db6b0a61SColin Percival 2735db6b0a61SColin Percival # Fetch the INDEX-OLD and INDEX-ALL. 2736db6b0a61SColin Percival fetch_metadata INDEX-OLD INDEX-ALL || return 1 2737db6b0a61SColin Percival 2738db6b0a61SColin Percival # If StrictComponents is not "yes", generate a new components list 2739db6b0a61SColin Percival # with only the components which appear to be installed. 2740db6b0a61SColin Percival upgrade_guess_components INDEX-ALL || return 1 2741db6b0a61SColin Percival 2742db6b0a61SColin Percival # Generate filtered INDEX-OLD and INDEX-ALL files containing only 2743db6b0a61SColin Percival # the components we want and without anything marked as "Ignore". 2744db6b0a61SColin Percival fetch_filter_metadata INDEX-OLD || return 1 2745db6b0a61SColin Percival fetch_filter_metadata INDEX-ALL || return 1 2746db6b0a61SColin Percival 2747db6b0a61SColin Percival # Merge the INDEX-OLD and INDEX-ALL files into INDEX-OLD. 2748db6b0a61SColin Percival sort INDEX-OLD INDEX-ALL > INDEX-OLD.tmp 2749db6b0a61SColin Percival mv INDEX-OLD.tmp INDEX-OLD 2750db6b0a61SColin Percival rm INDEX-ALL 2751db6b0a61SColin Percival 2752db6b0a61SColin Percival # Adjust variables for fetching files from the new release. 2753db6b0a61SColin Percival OLDRELNUM=${RELNUM} 2754db6b0a61SColin Percival RELNUM=${TARGETRELEASE} 2755db6b0a61SColin Percival OLDFETCHDIR=${FETCHDIR} 2756db6b0a61SColin Percival FETCHDIR=${RELNUM}/${ARCH} 2757db6b0a61SColin Percival 2758db6b0a61SColin Percival # Try to fetch the NEW metadata index signature ("tag") until we run 2759db6b0a61SColin Percival # out of available servers; and sanity check the downloaded tag. 2760db6b0a61SColin Percival while ! fetch_tag; do 2761db6b0a61SColin Percival fetch_pick_server || return 1 2762db6b0a61SColin Percival done 2763db6b0a61SColin Percival 2764db6b0a61SColin Percival # Fetch the new INDEX-ALL. 2765db6b0a61SColin Percival fetch_metadata INDEX-ALL || return 1 2766db6b0a61SColin Percival 2767db6b0a61SColin Percival # If StrictComponents is not "yes", COMPONENTS contains an entry 2768db6b0a61SColin Percival # corresponding to the currently running kernel, and said kernel 2769db6b0a61SColin Percival # does not exist in the new release, add "kernel/generic" to the 2770db6b0a61SColin Percival # list of components. 2771db6b0a61SColin Percival upgrade_guess_new_kernel INDEX-ALL || return 1 2772db6b0a61SColin Percival 2773db6b0a61SColin Percival # Filter INDEX-ALL to contain only the components we want and without 2774db6b0a61SColin Percival # anything marked as "Ignore". 2775db6b0a61SColin Percival fetch_filter_metadata INDEX-ALL || return 1 2776db6b0a61SColin Percival 2777db6b0a61SColin Percival # Convert INDEX-OLD (last release) and INDEX-ALL (new release) into 2778db6b0a61SColin Percival # INDEX-OLD and INDEX-NEW files (in the sense of normal upgrades). 2779db6b0a61SColin Percival upgrade_oldall_to_oldnew INDEX-OLD INDEX-ALL INDEX-NEW 2780db6b0a61SColin Percival 2781db6b0a61SColin Percival # Translate /boot/${KERNCONF} or /boot/${NKERNCONF} into ${KERNELDIR} 2782db6b0a61SColin Percival fetch_filter_kernel_names INDEX-NEW ${NKERNCONF} 2783db6b0a61SColin Percival fetch_filter_kernel_names INDEX-OLD ${KERNCONF} 2784db6b0a61SColin Percival 2785db6b0a61SColin Percival # For all paths appearing in INDEX-OLD or INDEX-NEW, inspect the 2786db6b0a61SColin Percival # system and generate an INDEX-PRESENT file. 2787db6b0a61SColin Percival fetch_inspect_system INDEX-OLD INDEX-PRESENT INDEX-NEW || return 1 2788db6b0a61SColin Percival 2789db6b0a61SColin Percival # Based on ${MERGECHANGES}, generate a file tomerge-old with the 2790db6b0a61SColin Percival # paths and hashes of old versions of files to merge. 2791c55b7e52SColin Percival fetch_filter_mergechanges INDEX-OLD INDEX-PRESENT INDEX-NEW tomerge-old 2792db6b0a61SColin Percival 2793db6b0a61SColin Percival # Based on ${UPDATEIFUNMODIFIED}, remove lines from INDEX-* which 2794db6b0a61SColin Percival # correspond to lines in INDEX-PRESENT with hashes not appearing 2795db6b0a61SColin Percival # in INDEX-OLD or INDEX-NEW. Also remove lines where the entry in 2796db6b0a61SColin Percival # INDEX-PRESENT has type - and there isn't a corresponding entry in 2797db6b0a61SColin Percival # INDEX-OLD with type -. 2798db6b0a61SColin Percival fetch_filter_unmodified_notpresent \ 2799db6b0a61SColin Percival INDEX-OLD INDEX-PRESENT INDEX-NEW tomerge-old 2800db6b0a61SColin Percival 2801db6b0a61SColin Percival # For each entry in INDEX-PRESENT of type -, remove any corresponding 2802db6b0a61SColin Percival # entry from INDEX-NEW if ${ALLOWADD} != "yes". Remove all entries 2803db6b0a61SColin Percival # of type - from INDEX-PRESENT. 2804db6b0a61SColin Percival fetch_filter_allowadd INDEX-PRESENT INDEX-NEW 2805db6b0a61SColin Percival 2806db6b0a61SColin Percival # If ${ALLOWDELETE} != "yes", then remove any entries from 2807db6b0a61SColin Percival # INDEX-PRESENT which don't correspond to entries in INDEX-NEW. 2808db6b0a61SColin Percival fetch_filter_allowdelete INDEX-PRESENT INDEX-NEW 2809db6b0a61SColin Percival 2810db6b0a61SColin Percival # If ${KEEPMODIFIEDMETADATA} == "yes", then for each entry in 2811db6b0a61SColin Percival # INDEX-PRESENT with metadata not matching any entry in INDEX-OLD, 2812db6b0a61SColin Percival # replace the corresponding line of INDEX-NEW with one having the 2813db6b0a61SColin Percival # same metadata as the entry in INDEX-PRESENT. 2814db6b0a61SColin Percival fetch_filter_modified_metadata INDEX-OLD INDEX-PRESENT INDEX-NEW 2815db6b0a61SColin Percival 2816db6b0a61SColin Percival # Remove lines from INDEX-PRESENT and INDEX-NEW which are identical; 2817db6b0a61SColin Percival # no need to update a file if it isn't changing. 2818db6b0a61SColin Percival fetch_filter_uptodate INDEX-PRESENT INDEX-NEW 2819db6b0a61SColin Percival 2820db6b0a61SColin Percival # Fetch "clean" files from the old release for merging changes. 2821db6b0a61SColin Percival fetch_files_premerge tomerge-old 2822db6b0a61SColin Percival 2823db6b0a61SColin Percival # Prepare to fetch files: Generate a list of the files we need, 2824db6b0a61SColin Percival # copy the unmodified files we have into /files/, and generate 2825db6b0a61SColin Percival # a list of patches to download. 2826db6b0a61SColin Percival fetch_files_prepare INDEX-OLD INDEX-PRESENT INDEX-NEW || return 1 2827db6b0a61SColin Percival 2828db6b0a61SColin Percival # Fetch patches from to-${RELNUM}/${ARCH}/bp/ 2829db6b0a61SColin Percival PATCHDIR=to-${RELNUM}/${ARCH}/bp 2830db6b0a61SColin Percival fetch_files || return 1 2831db6b0a61SColin Percival 2832db6b0a61SColin Percival # Merge configuration file changes. 2833db6b0a61SColin Percival upgrade_merge tomerge-old INDEX-PRESENT INDEX-NEW || return 1 2834db6b0a61SColin Percival 2835db6b0a61SColin Percival # Create and populate install manifest directory; and report what 2836db6b0a61SColin Percival # updates are available. 2837db6b0a61SColin Percival fetch_create_manifest || return 1 2838db6b0a61SColin Percival 2839db6b0a61SColin Percival # Leave a note behind to tell the "install" command that the kernel 2840db6b0a61SColin Percival # needs to be installed before the world. 2841db6b0a61SColin Percival touch ${BDHASH}-install/kernelfirst 284285451f90SColin Percival 284385451f90SColin Percival # Remind the user that they need to run "freebsd-update install" 284485451f90SColin Percival # to install the downloaded bits, in case they didn't RTFM. 284559b02bb4SMichael Osipov echo "To install the downloaded upgrades, run '`basename $0` [options] install'." 2846db6b0a61SColin Percival} 2847db6b0a61SColin Percival 284848ffe56aSColin Percival# Make sure that all the file hashes mentioned in $@ have corresponding 284948ffe56aSColin Percival# gzipped files stored in /files/. 285048ffe56aSColin Percivalinstall_verify () { 285148ffe56aSColin Percival # Generate a list of hashes 285248ffe56aSColin Percival cat $@ | 285348ffe56aSColin Percival cut -f 2,7 -d '|' | 285448ffe56aSColin Percival grep -E '^f' | 285548ffe56aSColin Percival cut -f 2 -d '|' | 285648ffe56aSColin Percival sort -u > filelist 285748ffe56aSColin Percival 285848ffe56aSColin Percival # Make sure all the hashes exist 285948ffe56aSColin Percival while read HASH; do 286048ffe56aSColin Percival if ! [ -f files/${HASH}.gz ]; then 286148ffe56aSColin Percival echo -n "Update files missing -- " 286248ffe56aSColin Percival echo "this should never happen." 286359b02bb4SMichael Osipov echo "Re-run '`basename $0` [options] fetch'." 286448ffe56aSColin Percival return 1 286548ffe56aSColin Percival fi 286648ffe56aSColin Percival done < filelist 286748ffe56aSColin Percival 286848ffe56aSColin Percival # Clean up 286948ffe56aSColin Percival rm filelist 287048ffe56aSColin Percival} 287148ffe56aSColin Percival 287248ffe56aSColin Percival# Remove the system immutable flag from files 287348ffe56aSColin Percivalinstall_unschg () { 287448ffe56aSColin Percival # Generate file list 287548ffe56aSColin Percival cat $@ | 287648ffe56aSColin Percival cut -f 1 -d '|' > filelist 287748ffe56aSColin Percival 287848ffe56aSColin Percival # Remove flags 287948ffe56aSColin Percival while read F; do 2880e829ed67SColin Percival if ! [ -e ${BASEDIR}/${F} ]; then 288148ffe56aSColin Percival continue 28825a74378cSXin LI else 28835a74378cSXin LI echo ${BASEDIR}/${F} 288448ffe56aSColin Percival fi 28855a74378cSXin LI done < filelist | xargs chflags noschg || return 1 288648ffe56aSColin Percival 288748ffe56aSColin Percival # Clean up 288848ffe56aSColin Percival rm filelist 288948ffe56aSColin Percival} 289048ffe56aSColin Percival 289123d827efSSimon L. B. Nielsen# Decide which directory name to use for kernel backups. 289223d827efSSimon L. B. Nielsenbackup_kernel_finddir () { 289323d827efSSimon L. B. Nielsen CNT=0 289423d827efSSimon L. B. Nielsen while true ; do 289523d827efSSimon L. B. Nielsen # Pathname does not exist, so it is OK use that name 289623d827efSSimon L. B. Nielsen # for backup directory. 2897c4a0c62cSThomas Quinot if [ ! -e $BASEDIR/$BACKUPKERNELDIR ]; then 289823d827efSSimon L. B. Nielsen return 0 289923d827efSSimon L. B. Nielsen fi 290023d827efSSimon L. B. Nielsen 290123d827efSSimon L. B. Nielsen # If directory do exist, we only use if it has our 290223d827efSSimon L. B. Nielsen # marker file. 2903c4a0c62cSThomas Quinot if [ -d $BASEDIR/$BACKUPKERNELDIR -a \ 2904c4a0c62cSThomas Quinot -e $BASEDIR/$BACKUPKERNELDIR/.freebsd-update ]; then 290523d827efSSimon L. B. Nielsen return 0 290623d827efSSimon L. B. Nielsen fi 290723d827efSSimon L. B. Nielsen 290823d827efSSimon L. B. Nielsen # We could not use current directory name, so add counter to 290923d827efSSimon L. B. Nielsen # the end and try again. 291023d827efSSimon L. B. Nielsen CNT=$((CNT + 1)) 291123d827efSSimon L. B. Nielsen if [ $CNT -gt 9 ]; then 2912c4a0c62cSThomas Quinot echo "Could not find valid backup dir ($BASEDIR/$BACKUPKERNELDIR)" 291323d827efSSimon L. B. Nielsen exit 1 291423d827efSSimon L. B. Nielsen fi 291523d827efSSimon L. B. Nielsen BACKUPKERNELDIR="`echo $BACKUPKERNELDIR | sed -Ee 's/[0-9]\$//'`" 291623d827efSSimon L. B. Nielsen BACKUPKERNELDIR="${BACKUPKERNELDIR}${CNT}" 291723d827efSSimon L. B. Nielsen done 291823d827efSSimon L. B. Nielsen} 291923d827efSSimon L. B. Nielsen 292023d827efSSimon L. B. Nielsen# Backup the current kernel using hardlinks, if not disabled by user. 292123d827efSSimon L. B. Nielsen# Since we delete all files in the directory used for previous backups 292223d827efSSimon L. B. Nielsen# we create a marker file called ".freebsd-update" in the directory so 292323d827efSSimon L. B. Nielsen# we can determine on the next run that the directory was created by 292423d827efSSimon L. B. Nielsen# freebsd-update and we then do not accidentally remove user files in 292523d827efSSimon L. B. Nielsen# the unlikely case that the user has created a directory with a 292623d827efSSimon L. B. Nielsen# conflicting name. 292723d827efSSimon L. B. Nielsenbackup_kernel () { 292823d827efSSimon L. B. Nielsen # Only make kernel backup is so configured. 292923d827efSSimon L. B. Nielsen if [ $BACKUPKERNEL != yes ]; then 293023d827efSSimon L. B. Nielsen return 0 293123d827efSSimon L. B. Nielsen fi 293223d827efSSimon L. B. Nielsen 293323d827efSSimon L. B. Nielsen # Decide which directory name to use for kernel backups. 293423d827efSSimon L. B. Nielsen backup_kernel_finddir 293523d827efSSimon L. B. Nielsen 293623d827efSSimon L. B. Nielsen # Remove old kernel backup files. If $BACKUPKERNELDIR was 293723d827efSSimon L. B. Nielsen # "not ours", backup_kernel_finddir would have exited, so 293823d827efSSimon L. B. Nielsen # deleting the directory content is as safe as we can make it. 2939c4a0c62cSThomas Quinot if [ -d $BASEDIR/$BACKUPKERNELDIR ]; then 2940c4a0c62cSThomas Quinot rm -fr $BASEDIR/$BACKUPKERNELDIR 294123d827efSSimon L. B. Nielsen fi 294223d827efSSimon L. B. Nielsen 2943ab7d0151SJaakko Heinonen # Create directories for backup. 2944c4a0c62cSThomas Quinot mkdir -p $BASEDIR/$BACKUPKERNELDIR 2945c4a0c62cSThomas Quinot mtree -cdn -p "${BASEDIR}/${KERNELDIR}" | \ 2946c4a0c62cSThomas Quinot mtree -Ue -p "${BASEDIR}/${BACKUPKERNELDIR}" > /dev/null 294723d827efSSimon L. B. Nielsen 294823d827efSSimon L. B. Nielsen # Mark the directory as having been created by freebsd-update. 2949c4a0c62cSThomas Quinot touch $BASEDIR/$BACKUPKERNELDIR/.freebsd-update 295023d827efSSimon L. B. Nielsen if [ $? -ne 0 ]; then 295123d827efSSimon L. B. Nielsen echo "Could not create kernel backup directory" 295223d827efSSimon L. B. Nielsen exit 1 295323d827efSSimon L. B. Nielsen fi 295423d827efSSimon L. B. Nielsen 295523d827efSSimon L. B. Nielsen # Disable pathname expansion to be sure *.symbols is not 295623d827efSSimon L. B. Nielsen # expanded. 295723d827efSSimon L. B. Nielsen set -f 295823d827efSSimon L. B. Nielsen 295923d827efSSimon L. B. Nielsen # Use find to ignore symbol files, unless disabled by user. 296023d827efSSimon L. B. Nielsen if [ $BACKUPKERNELSYMBOLFILES = yes ]; then 296123d827efSSimon L. B. Nielsen FINDFILTER="" 296223d827efSSimon L. B. Nielsen else 29637e1ed2c7SEd Maste FINDFILTER="-a ! -name *.debug -a ! -name *.symbols" 296423d827efSSimon L. B. Nielsen fi 296523d827efSSimon L. B. Nielsen 296623d827efSSimon L. B. Nielsen # Backup all the kernel files using hardlinks. 2967c4a0c62cSThomas Quinot (cd ${BASEDIR}/${KERNELDIR} && find . -type f $FINDFILTER -exec \ 2968c4a0c62cSThomas Quinot cp -pl '{}' ${BASEDIR}/${BACKUPKERNELDIR}/'{}' \;) 296923d827efSSimon L. B. Nielsen 297091811711Sa-biardi # Re-enable pathname expansion. 297123d827efSSimon L. B. Nielsen set +f 297223d827efSSimon L. B. Nielsen} 297323d827efSSimon L. B. Nielsen 2974c0f52443SEd Maste# Check for and remove an existing directory that conflicts with the file or 2975c0f52443SEd Maste# symlink that we are going to install. 2976c0f52443SEd Mastedir_conflict () { 2977c0f52443SEd Maste if [ -d "$1" ]; then 2978c0f52443SEd Maste echo "Removing conflicting directory $1" 2979c0f52443SEd Maste rm -rf -- "$1" 2980c0f52443SEd Maste fi 2981c0f52443SEd Maste} 2982c0f52443SEd Maste 298348ffe56aSColin Percival# Install new files 298448ffe56aSColin Percivalinstall_from_index () { 298548ffe56aSColin Percival # First pass: Do everything apart from setting file flags. We 298648ffe56aSColin Percival # can't set flags yet, because schg inhibits hard linking. 298748ffe56aSColin Percival sort -k 1,1 -t '|' $1 | 298848ffe56aSColin Percival tr '|' ' ' | 298948ffe56aSColin Percival while read FPATH TYPE OWNER GROUP PERM FLAGS HASH LINK; do 299048ffe56aSColin Percival case ${TYPE} in 299148ffe56aSColin Percival d) 2992f6d37c9cSEd Maste # Create a directory. A file may change to a directory 2993f6d37c9cSEd Maste # on upgrade (PR273661). If that happens, remove the 2994f6d37c9cSEd Maste # file first. 2995f6d37c9cSEd Maste if [ -e "${BASEDIR}/${FPATH}" ] && \ 2996f6d37c9cSEd Maste ! [ -d "${BASEDIR}/${FPATH}" ]; then 2997f6d37c9cSEd Maste rm -f -- "${BASEDIR}/${FPATH}" 2998f6d37c9cSEd Maste fi 299948ffe56aSColin Percival install -d -o ${OWNER} -g ${GROUP} \ 300048ffe56aSColin Percival -m ${PERM} ${BASEDIR}/${FPATH} 300148ffe56aSColin Percival ;; 300248ffe56aSColin Percival f) 3003c0f52443SEd Maste dir_conflict "${BASEDIR}/${FPATH}" 300448ffe56aSColin Percival if [ -z "${LINK}" ]; then 300548ffe56aSColin Percival # Create a file, without setting flags. 300648ffe56aSColin Percival gunzip < files/${HASH}.gz > ${HASH} 300748ffe56aSColin Percival install -S -o ${OWNER} -g ${GROUP} \ 300848ffe56aSColin Percival -m ${PERM} ${HASH} ${BASEDIR}/${FPATH} 300948ffe56aSColin Percival rm ${HASH} 301048ffe56aSColin Percival else 301148ffe56aSColin Percival # Create a hard link. 3012e829ed67SColin Percival ln -f ${BASEDIR}/${LINK} ${BASEDIR}/${FPATH} 301348ffe56aSColin Percival fi 301448ffe56aSColin Percival ;; 301548ffe56aSColin Percival L) 3016c0f52443SEd Maste dir_conflict "${BASEDIR}/${FPATH}" 301748ffe56aSColin Percival # Create a symlink 301848ffe56aSColin Percival ln -sfh ${HASH} ${BASEDIR}/${FPATH} 301948ffe56aSColin Percival ;; 302048ffe56aSColin Percival esac 302148ffe56aSColin Percival done 302248ffe56aSColin Percival 302348ffe56aSColin Percival # Perform a second pass, adding file flags. 302448ffe56aSColin Percival tr '|' ' ' < $1 | 302548ffe56aSColin Percival while read FPATH TYPE OWNER GROUP PERM FLAGS HASH LINK; do 302648ffe56aSColin Percival if [ ${TYPE} = "f" ] && 302748ffe56aSColin Percival ! [ ${FLAGS} = "0" ]; then 302848ffe56aSColin Percival chflags ${FLAGS} ${BASEDIR}/${FPATH} 302948ffe56aSColin Percival fi 303048ffe56aSColin Percival done 303148ffe56aSColin Percival} 303248ffe56aSColin Percival 303348ffe56aSColin Percival# Remove files which we want to delete 303448ffe56aSColin Percivalinstall_delete () { 303548ffe56aSColin Percival # Generate list of new files 303648ffe56aSColin Percival cut -f 1 -d '|' < $2 | 303748ffe56aSColin Percival sort > newfiles 303848ffe56aSColin Percival 303948ffe56aSColin Percival # Generate subindex of old files we want to nuke 304048ffe56aSColin Percival sort -k 1,1 -t '|' $1 | 304148ffe56aSColin Percival join -t '|' -v 1 - newfiles | 3042bce02f98SColin Percival sort -r -k 1,1 -t '|' | 304348ffe56aSColin Percival cut -f 1,2 -d '|' | 304448ffe56aSColin Percival tr '|' ' ' > killfiles 304548ffe56aSColin Percival 304648ffe56aSColin Percival # Remove the offending bits 304748ffe56aSColin Percival while read FPATH TYPE; do 304848ffe56aSColin Percival case ${TYPE} in 304948ffe56aSColin Percival d) 305048ffe56aSColin Percival rmdir ${BASEDIR}/${FPATH} 305148ffe56aSColin Percival ;; 305248ffe56aSColin Percival f) 3053c0f52443SEd Maste if [ -f "${BASEDIR}/${FPATH}" ]; then 3054c0f52443SEd Maste rm "${BASEDIR}/${FPATH}" 3055c0f52443SEd Maste fi 305648ffe56aSColin Percival ;; 305748ffe56aSColin Percival L) 3058c0f52443SEd Maste if [ -L "${BASEDIR}/${FPATH}" ]; then 3059c0f52443SEd Maste rm "${BASEDIR}/${FPATH}" 3060c0f52443SEd Maste fi 306148ffe56aSColin Percival ;; 306248ffe56aSColin Percival esac 306348ffe56aSColin Percival done < killfiles 306448ffe56aSColin Percival 306548ffe56aSColin Percival # Clean up 306648ffe56aSColin Percival rm newfiles killfiles 306748ffe56aSColin Percival} 306848ffe56aSColin Percival 30692b17527cSKyle Evans# Install new files, delete old files, and update generated files 3070db6b0a61SColin Percivalinstall_files () { 3071db6b0a61SColin Percival # If we haven't already dealt with the kernel, deal with it. 3072db6b0a61SColin Percival if ! [ -f $1/kerneldone ]; then 3073db6b0a61SColin Percival grep -E '^/boot/' $1/INDEX-OLD > INDEX-OLD 3074db6b0a61SColin Percival grep -E '^/boot/' $1/INDEX-NEW > INDEX-NEW 3075db6b0a61SColin Percival 307623d827efSSimon L. B. Nielsen # Backup current kernel before installing a new one 307723d827efSSimon L. B. Nielsen backup_kernel || return 1 307823d827efSSimon L. B. Nielsen 3079db6b0a61SColin Percival # Install new files 3080db6b0a61SColin Percival install_from_index INDEX-NEW || return 1 3081db6b0a61SColin Percival 3082db6b0a61SColin Percival # Remove files which need to be deleted 3083db6b0a61SColin Percival install_delete INDEX-OLD INDEX-NEW || return 1 3084db6b0a61SColin Percival 3085db6b0a61SColin Percival # Update linker.hints if necessary 3086db6b0a61SColin Percival if [ -s INDEX-OLD -o -s INDEX-NEW ]; then 3087c4a0c62cSThomas Quinot kldxref -R ${BASEDIR}/boot/ 2>/dev/null 308848ffe56aSColin Percival fi 3089db6b0a61SColin Percival 3090db6b0a61SColin Percival # We've finished updating the kernel. 3091db6b0a61SColin Percival touch $1/kerneldone 3092db6b0a61SColin Percival 3093db6b0a61SColin Percival # Do we need to ask for a reboot now? 3094db6b0a61SColin Percival if [ -f $1/kernelfirst ] && 3095db6b0a61SColin Percival [ -s INDEX-OLD -o -s INDEX-NEW ]; then 3096db6b0a61SColin Percival cat <<-EOF 3097db6b0a61SColin Percival 3098db6b0a61SColin PercivalKernel updates have been installed. Please reboot and run 309959b02bb4SMichael Osipov'`basename $0` [options] install' again to finish installing updates. 3100db6b0a61SColin Percival EOF 3101db6b0a61SColin Percival exit 0 3102db6b0a61SColin Percival fi 3103db6b0a61SColin Percival fi 3104db6b0a61SColin Percival 3105db6b0a61SColin Percival # If we haven't already dealt with the world, deal with it. 3106db6b0a61SColin Percival if ! [ -f $1/worlddone ]; then 3107cd1ab228SColin Percival # Create any necessary directories first 3108cd1ab228SColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3109cd1ab228SColin Percival grep -E '^[^|]+\|d\|' > INDEX-NEW 3110cd1ab228SColin Percival install_from_index INDEX-NEW || return 1 3111cd1ab228SColin Percival 3112722d81b5SBrooks Davis # Install new runtime linker 3113722d81b5SBrooks Davis grep -vE '^/boot/' $1/INDEX-NEW | 3114722d81b5SBrooks Davis grep -vE '^[^|]+\|d\|' | 3115722d81b5SBrooks Davis grep -E '^/libexec/ld-elf[^|]*\.so\.[0-9]+\|' > INDEX-NEW 3116722d81b5SBrooks Davis install_from_index INDEX-NEW || return 1 3117722d81b5SBrooks Davis 3118db6b0a61SColin Percival # Install new shared libraries next 3119db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3120cd1ab228SColin Percival grep -vE '^[^|]+\|d\|' | 3121722d81b5SBrooks Davis grep -vE '^/libexec/ld-elf[^|]*\.so\.[0-9]+\|' | 31229546dbd1SColin Percival grep -E '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' > INDEX-NEW 3123db6b0a61SColin Percival install_from_index INDEX-NEW || return 1 3124db6b0a61SColin Percival 3125db6b0a61SColin Percival # Deal with everything else 3126db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-OLD | 3127cd1ab228SColin Percival grep -vE '^[^|]+\|d\|' | 3128722d81b5SBrooks Davis grep -vE '^/libexec/ld-elf[^|]*\.so\.[0-9]+\|' | 31299546dbd1SColin Percival grep -vE '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' > INDEX-OLD 3130db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3131cd1ab228SColin Percival grep -vE '^[^|]+\|d\|' | 3132722d81b5SBrooks Davis grep -vE '^/libexec/ld-elf[^|]*\.so\.[0-9]+\|' | 31339546dbd1SColin Percival grep -vE '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' > INDEX-NEW 3134db6b0a61SColin Percival install_from_index INDEX-NEW || return 1 3135db6b0a61SColin Percival install_delete INDEX-OLD INDEX-NEW || return 1 3136db6b0a61SColin Percival 31378ee97b19SEd Maste # Restart host sshd if running (PR263489). Note that this does 31388ee97b19SEd Maste # not affect child sshd processes handling existing sessions. 31398ee97b19SEd Maste if [ "$BASEDIR" = / ] && \ 31408ee97b19SEd Maste service sshd status >/dev/null 2>/dev/null; then 31416cd1bc53SEd Maste echo 31426cd1bc53SEd Maste echo "Restarting sshd after upgrade" 31436cd1bc53SEd Maste service sshd restart 31446cd1bc53SEd Maste fi 31456cd1bc53SEd Maste 31462b17527cSKyle Evans # Rehash certs if we actually have certctl installed. 31472b17527cSKyle Evans if which certctl>/dev/null; then 31482b17527cSKyle Evans env DESTDIR=${BASEDIR} certctl rehash 31492b17527cSKyle Evans fi 31502b17527cSKyle Evans 3151ebebc41eSKyle Evans # Rebuild generated pwd files and /etc/login.conf.db. 31529b659110SEd Maste pwd_mkdb -d ${BASEDIR}/etc -p ${BASEDIR}/etc/master.passwd 3153c4a0c62cSThomas Quinot cap_mkdb ${BASEDIR}/etc/login.conf 3154db6b0a61SColin Percival 31559c812c8dSEd Maste # Rebuild man page databases, if necessary. 31569c812c8dSEd Maste for D in /usr/share/man /usr/share/openssl/man; do 31579c812c8dSEd Maste if [ ! -d ${BASEDIR}/$D ]; then 31589c812c8dSEd Maste continue 31599c812c8dSEd Maste fi 3160741223a6SEd Maste if [ -f ${BASEDIR}/$D/mandoc.db ] && \ 3161741223a6SEd Maste [ -z "$(find ${BASEDIR}/$D -type f -newer ${BASEDIR}/$D/mandoc.db)" ]; then 31629c812c8dSEd Maste continue; 31639c812c8dSEd Maste fi 31649c812c8dSEd Maste makewhatis ${BASEDIR}/$D 31659c812c8dSEd Maste done 31669c812c8dSEd Maste 3167db6b0a61SColin Percival # We've finished installing the world and deleting old files 3168db6b0a61SColin Percival # which are not shared libraries. 3169db6b0a61SColin Percival touch $1/worlddone 3170db6b0a61SColin Percival 3171db6b0a61SColin Percival # Do we need to ask the user to portupgrade now? 3172db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 31739546dbd1SColin Percival grep -E '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' | 3174db6b0a61SColin Percival cut -f 1 -d '|' | 3175db6b0a61SColin Percival sort > newfiles 3176db6b0a61SColin Percival if grep -vE '^/boot/' $1/INDEX-OLD | 31779546dbd1SColin Percival grep -E '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' | 3178db6b0a61SColin Percival cut -f 1 -d '|' | 3179db6b0a61SColin Percival sort | 3180db6b0a61SColin Percival join -v 1 - newfiles | 3181db6b0a61SColin Percival grep -q .; then 3182db6b0a61SColin Percival cat <<-EOF 3183db6b0a61SColin Percival 3184db6b0a61SColin PercivalCompleting this upgrade requires removing old shared object files. 3185db6b0a61SColin PercivalPlease rebuild all installed 3rd party software (e.g., programs 318659b02bb4SMichael Osipovinstalled from the ports tree) and then run 318759b02bb4SMichael Osipov'`basename $0` [options] install' again to finish installing updates. 3188db6b0a61SColin Percival EOF 3189db6b0a61SColin Percival rm newfiles 3190db6b0a61SColin Percival exit 0 3191db6b0a61SColin Percival fi 3192db6b0a61SColin Percival rm newfiles 3193db6b0a61SColin Percival fi 3194db6b0a61SColin Percival 3195db6b0a61SColin Percival # Remove old shared libraries 3196db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3197cd1ab228SColin Percival grep -vE '^[^|]+\|d\|' | 31989546dbd1SColin Percival grep -E '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' > INDEX-NEW 3199db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-OLD | 3200cd1ab228SColin Percival grep -vE '^[^|]+\|d\|' | 32019546dbd1SColin Percival grep -E '^[^|]*/lib/[^|]*\.so\.[0-9]+\|' > INDEX-OLD 3202db6b0a61SColin Percival install_delete INDEX-OLD INDEX-NEW || return 1 3203db6b0a61SColin Percival 3204cd1ab228SColin Percival # Remove old directories 3205ebc1d19cSColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3206ebc1d19cSColin Percival grep -E '^[^|]+\|d\|' > INDEX-NEW 3207cd1ab228SColin Percival grep -vE '^/boot/' $1/INDEX-OLD | 3208cd1ab228SColin Percival grep -E '^[^|]+\|d\|' > INDEX-OLD 3209cd1ab228SColin Percival install_delete INDEX-OLD INDEX-NEW || return 1 3210cd1ab228SColin Percival 3211db6b0a61SColin Percival # Remove temporary files 3212db6b0a61SColin Percival rm INDEX-OLD INDEX-NEW 321348ffe56aSColin Percival} 321448ffe56aSColin Percival 321548ffe56aSColin Percival# Rearrange bits to allow the installed updates to be rolled back 321648ffe56aSColin Percivalinstall_setup_rollback () { 3217db6b0a61SColin Percival # Remove the "reboot after installing kernel", "kernel updated", and 3218db6b0a61SColin Percival # "finished installing the world" flags if present -- they are 3219db6b0a61SColin Percival # irrelevant when rolling back updates. 3220db6b0a61SColin Percival if [ -f ${BDHASH}-install/kernelfirst ]; then 3221db6b0a61SColin Percival rm ${BDHASH}-install/kernelfirst 3222db6b0a61SColin Percival rm ${BDHASH}-install/kerneldone 3223db6b0a61SColin Percival fi 3224db6b0a61SColin Percival if [ -f ${BDHASH}-install/worlddone ]; then 3225db6b0a61SColin Percival rm ${BDHASH}-install/worlddone 3226db6b0a61SColin Percival fi 3227db6b0a61SColin Percival 322848ffe56aSColin Percival if [ -L ${BDHASH}-rollback ]; then 322948ffe56aSColin Percival mv ${BDHASH}-rollback ${BDHASH}-install/rollback 323048ffe56aSColin Percival fi 323148ffe56aSColin Percival 323248ffe56aSColin Percival mv ${BDHASH}-install ${BDHASH}-rollback 323348ffe56aSColin Percival} 323448ffe56aSColin Percival 323548ffe56aSColin Percival# Actually install updates 323648ffe56aSColin Percivalinstall_run () { 323748ffe56aSColin Percival echo -n "Installing updates..." 323848ffe56aSColin Percival 323948ffe56aSColin Percival # Make sure we have all the files we should have 324048ffe56aSColin Percival install_verify ${BDHASH}-install/INDEX-OLD \ 324148ffe56aSColin Percival ${BDHASH}-install/INDEX-NEW || return 1 324248ffe56aSColin Percival 324348ffe56aSColin Percival # Remove system immutable flag from files 324448ffe56aSColin Percival install_unschg ${BDHASH}-install/INDEX-OLD \ 324548ffe56aSColin Percival ${BDHASH}-install/INDEX-NEW || return 1 324648ffe56aSColin Percival 3247db6b0a61SColin Percival # Install new files, delete old files, and update linker.hints 3248db6b0a61SColin Percival install_files ${BDHASH}-install || return 1 324948ffe56aSColin Percival 325048ffe56aSColin Percival # Rearrange bits to allow the installed updates to be rolled back 325148ffe56aSColin Percival install_setup_rollback 325248ffe56aSColin Percival 325348ffe56aSColin Percival echo " done." 325448ffe56aSColin Percival} 325548ffe56aSColin Percival 325648ffe56aSColin Percival# Rearrange bits to allow the previous set of updates to be rolled back next. 325748ffe56aSColin Percivalrollback_setup_rollback () { 325848ffe56aSColin Percival if [ -L ${BDHASH}-rollback/rollback ]; then 325948ffe56aSColin Percival mv ${BDHASH}-rollback/rollback rollback-tmp 326048ffe56aSColin Percival rm -r ${BDHASH}-rollback/ 326148ffe56aSColin Percival rm ${BDHASH}-rollback 326248ffe56aSColin Percival mv rollback-tmp ${BDHASH}-rollback 326348ffe56aSColin Percival else 326448ffe56aSColin Percival rm -r ${BDHASH}-rollback/ 326548ffe56aSColin Percival rm ${BDHASH}-rollback 326648ffe56aSColin Percival fi 326748ffe56aSColin Percival} 326848ffe56aSColin Percival 3269db6b0a61SColin Percival# Install old files, delete new files, and update linker.hints 3270db6b0a61SColin Percivalrollback_files () { 32716b27e1f2SEd Maste # Create directories first. They may be needed by files we will 32726b27e1f2SEd Maste # install in subsequent steps (PR273950). 32736b27e1f2SEd Maste awk -F \| '{if ($2 == "d") print }' $1/INDEX-OLD > INDEX-OLD 32746b27e1f2SEd Maste install_from_index INDEX-OLD || return 1 32756b27e1f2SEd Maste 32761ec4fb3aSColin Percival # Install old shared library files which don't have the same path as 32771ec4fb3aSColin Percival # a new shared library file. 32781ec4fb3aSColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3279fd0963d1SColin Percival grep -E '/lib/.*\.so\.[0-9]+\|' | 32801ec4fb3aSColin Percival cut -f 1 -d '|' | 32811ec4fb3aSColin Percival sort > INDEX-NEW.libs.flist 3282db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-OLD | 3283fd0963d1SColin Percival grep -E '/lib/.*\.so\.[0-9]+\|' | 32841ec4fb3aSColin Percival sort -k 1,1 -t '|' - | 32851ec4fb3aSColin Percival join -t '|' -v 1 - INDEX-NEW.libs.flist > INDEX-OLD 3286db6b0a61SColin Percival install_from_index INDEX-OLD || return 1 3287db6b0a61SColin Percival 3288db6b0a61SColin Percival # Deal with files which are neither kernel nor shared library 3289db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-OLD | 3290fd0963d1SColin Percival grep -vE '/lib/.*\.so\.[0-9]+\|' > INDEX-OLD 3291db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3292fd0963d1SColin Percival grep -vE '/lib/.*\.so\.[0-9]+\|' > INDEX-NEW 3293db6b0a61SColin Percival install_from_index INDEX-OLD || return 1 3294db6b0a61SColin Percival install_delete INDEX-NEW INDEX-OLD || return 1 3295db6b0a61SColin Percival 32961ec4fb3aSColin Percival # Install any old shared library files which we didn't install above. 32971ec4fb3aSColin Percival grep -vE '^/boot/' $1/INDEX-OLD | 3298fd0963d1SColin Percival grep -E '/lib/.*\.so\.[0-9]+\|' | 32991ec4fb3aSColin Percival sort -k 1,1 -t '|' - | 33001ec4fb3aSColin Percival join -t '|' - INDEX-NEW.libs.flist > INDEX-OLD 33011ec4fb3aSColin Percival install_from_index INDEX-OLD || return 1 33021ec4fb3aSColin Percival 3303db6b0a61SColin Percival # Delete unneeded shared library files 3304db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-OLD | 3305fd0963d1SColin Percival grep -E '/lib/.*\.so\.[0-9]+\|' > INDEX-OLD 3306db6b0a61SColin Percival grep -vE '^/boot/' $1/INDEX-NEW | 3307fd0963d1SColin Percival grep -E '/lib/.*\.so\.[0-9]+\|' > INDEX-NEW 3308db6b0a61SColin Percival install_delete INDEX-NEW INDEX-OLD || return 1 3309db6b0a61SColin Percival 3310db6b0a61SColin Percival # Deal with kernel files 3311db6b0a61SColin Percival grep -E '^/boot/' $1/INDEX-OLD > INDEX-OLD 3312db6b0a61SColin Percival grep -E '^/boot/' $1/INDEX-NEW > INDEX-NEW 3313db6b0a61SColin Percival install_from_index INDEX-OLD || return 1 3314db6b0a61SColin Percival install_delete INDEX-NEW INDEX-OLD || return 1 3315db6b0a61SColin Percival if [ -s INDEX-OLD -o -s INDEX-NEW ]; then 3316db6b0a61SColin Percival kldxref -R /boot/ 2>/dev/null 3317db6b0a61SColin Percival fi 3318db6b0a61SColin Percival 3319db6b0a61SColin Percival # Remove temporary files 33200e0d8d5aSColin Percival rm INDEX-OLD INDEX-NEW INDEX-NEW.libs.flist 3321db6b0a61SColin Percival} 3322db6b0a61SColin Percival 332348ffe56aSColin Percival# Actually rollback updates 332448ffe56aSColin Percivalrollback_run () { 332548ffe56aSColin Percival echo -n "Uninstalling updates..." 332648ffe56aSColin Percival 332748ffe56aSColin Percival # If there are updates waiting to be installed, remove them; we 332848ffe56aSColin Percival # want the user to re-run 'fetch' after rolling back updates. 332948ffe56aSColin Percival if [ -L ${BDHASH}-install ]; then 333048ffe56aSColin Percival rm -r ${BDHASH}-install/ 333148ffe56aSColin Percival rm ${BDHASH}-install 333248ffe56aSColin Percival fi 333348ffe56aSColin Percival 333448ffe56aSColin Percival # Make sure we have all the files we should have 333548ffe56aSColin Percival install_verify ${BDHASH}-rollback/INDEX-NEW \ 333648ffe56aSColin Percival ${BDHASH}-rollback/INDEX-OLD || return 1 333748ffe56aSColin Percival 333848ffe56aSColin Percival # Remove system immutable flag from files 333948ffe56aSColin Percival install_unschg ${BDHASH}-rollback/INDEX-NEW \ 334048ffe56aSColin Percival ${BDHASH}-rollback/INDEX-OLD || return 1 334148ffe56aSColin Percival 3342db6b0a61SColin Percival # Install old files, delete new files, and update linker.hints 3343db6b0a61SColin Percival rollback_files ${BDHASH}-rollback || return 1 334448ffe56aSColin Percival 334548ffe56aSColin Percival # Remove the rollback directory and the symlink pointing to it; and 334648ffe56aSColin Percival # rearrange bits to allow the previous set of updates to be rolled 334748ffe56aSColin Percival # back next. 334848ffe56aSColin Percival rollback_setup_rollback 334948ffe56aSColin Percival 335048ffe56aSColin Percival echo " done." 335148ffe56aSColin Percival} 335248ffe56aSColin Percival 335308e23beeSColin Percival# Compare INDEX-ALL and INDEX-PRESENT and print warnings about differences. 335408e23beeSColin PercivalIDS_compare () { 3355bb10a826SColin Percival # Get all the lines which mismatch in something other than file 3356bb10a826SColin Percival # flags. We ignore file flags because sysinstall doesn't seem to 3357bb10a826SColin Percival # set them when it installs FreeBSD; warning about these adds a 3358bb10a826SColin Percival # very large amount of noise. 3359bb10a826SColin Percival cut -f 1-5,7-8 -d '|' $1 > $1.noflags 3360bb10a826SColin Percival sort -k 1,1 -t '|' $1.noflags > $1.sorted 3361bb10a826SColin Percival cut -f 1-5,7-8 -d '|' $2 | 3362bb10a826SColin Percival comm -13 $1.noflags - | 3363bb10a826SColin Percival fgrep -v '|-|||||' | 336408e23beeSColin Percival sort -k 1,1 -t '|' | 336508e23beeSColin Percival join -t '|' $1.sorted - > INDEX-NOTMATCHING 336608e23beeSColin Percival 336708e23beeSColin Percival # Ignore files which match IDSIGNOREPATHS. 336808e23beeSColin Percival for X in ${IDSIGNOREPATHS}; do 336908e23beeSColin Percival grep -E "^${X}" INDEX-NOTMATCHING 337008e23beeSColin Percival done | 337108e23beeSColin Percival sort -u | 337208e23beeSColin Percival comm -13 - INDEX-NOTMATCHING > INDEX-NOTMATCHING.tmp 337308e23beeSColin Percival mv INDEX-NOTMATCHING.tmp INDEX-NOTMATCHING 337408e23beeSColin Percival 337508e23beeSColin Percival # Go through the lines and print warnings. 3376aa60062eSColin Percival local IFS='|' 3377aa60062eSColin Percival while read FPATH TYPE OWNER GROUP PERM HASH LINK P_TYPE P_OWNER P_GROUP P_PERM P_HASH P_LINK; do 337808e23beeSColin Percival # Warn about different object types. 337908e23beeSColin Percival if ! [ "${TYPE}" = "${P_TYPE}" ]; then 338008e23beeSColin Percival echo -n "${FPATH} is a " 338108e23beeSColin Percival case "${P_TYPE}" in 338208e23beeSColin Percival f) echo -n "regular file, " 338308e23beeSColin Percival ;; 338408e23beeSColin Percival d) echo -n "directory, " 338508e23beeSColin Percival ;; 338608e23beeSColin Percival L) echo -n "symlink, " 338708e23beeSColin Percival ;; 338808e23beeSColin Percival esac 338908e23beeSColin Percival echo -n "but should be a " 339008e23beeSColin Percival case "${TYPE}" in 339108e23beeSColin Percival f) echo -n "regular file." 339208e23beeSColin Percival ;; 339308e23beeSColin Percival d) echo -n "directory." 339408e23beeSColin Percival ;; 339508e23beeSColin Percival L) echo -n "symlink." 339608e23beeSColin Percival ;; 339708e23beeSColin Percival esac 339808e23beeSColin Percival echo 339908e23beeSColin Percival 340008e23beeSColin Percival # Skip other tests, since they don't make sense if 340108e23beeSColin Percival # we're comparing different object types. 340208e23beeSColin Percival continue 340308e23beeSColin Percival fi 340408e23beeSColin Percival 340508e23beeSColin Percival # Warn about different owners. 340608e23beeSColin Percival if ! [ "${OWNER}" = "${P_OWNER}" ]; then 340708e23beeSColin Percival echo -n "${FPATH} is owned by user id ${P_OWNER}, " 340808e23beeSColin Percival echo "but should be owned by user id ${OWNER}." 340908e23beeSColin Percival fi 341008e23beeSColin Percival 341108e23beeSColin Percival # Warn about different groups. 341208e23beeSColin Percival if ! [ "${GROUP}" = "${P_GROUP}" ]; then 341308e23beeSColin Percival echo -n "${FPATH} is owned by group id ${P_GROUP}, " 341408e23beeSColin Percival echo "but should be owned by group id ${GROUP}." 341508e23beeSColin Percival fi 341608e23beeSColin Percival 341708e23beeSColin Percival # Warn about different permissions. We do not warn about 341808e23beeSColin Percival # different permissions on symlinks, since some archivers 341908e23beeSColin Percival # don't extract symlink permissions correctly and they are 342008e23beeSColin Percival # ignored anyway. 342108e23beeSColin Percival if ! [ "${PERM}" = "${P_PERM}" ] && 342208e23beeSColin Percival ! [ "${TYPE}" = "L" ]; then 342308e23beeSColin Percival echo -n "${FPATH} has ${P_PERM} permissions, " 342408e23beeSColin Percival echo "but should have ${PERM} permissions." 342508e23beeSColin Percival fi 342608e23beeSColin Percival 342708e23beeSColin Percival # Warn about different file hashes / symlink destinations. 342808e23beeSColin Percival if ! [ "${HASH}" = "${P_HASH}" ]; then 342908e23beeSColin Percival if [ "${TYPE}" = "L" ]; then 343008e23beeSColin Percival echo -n "${FPATH} is a symlink to ${P_HASH}, " 343108e23beeSColin Percival echo "but should be a symlink to ${HASH}." 343208e23beeSColin Percival fi 343308e23beeSColin Percival if [ "${TYPE}" = "f" ]; then 343408e23beeSColin Percival echo -n "${FPATH} has SHA256 hash ${P_HASH}, " 343508e23beeSColin Percival echo "but should have SHA256 hash ${HASH}." 343608e23beeSColin Percival fi 343708e23beeSColin Percival fi 343808e23beeSColin Percival 343908e23beeSColin Percival # We don't warn about different hard links, since some 344008e23beeSColin Percival # some archivers break hard links, and as long as the 344108e23beeSColin Percival # underlying data is correct they really don't matter. 344208e23beeSColin Percival done < INDEX-NOTMATCHING 344308e23beeSColin Percival 344408e23beeSColin Percival # Clean up 3445bb10a826SColin Percival rm $1 $1.noflags $1.sorted $2 INDEX-NOTMATCHING 344608e23beeSColin Percival} 344708e23beeSColin Percival 344808e23beeSColin Percival# Do the work involved in comparing the system to a "known good" index 344908e23beeSColin PercivalIDS_run () { 345008e23beeSColin Percival workdir_init || return 1 345108e23beeSColin Percival 345208e23beeSColin Percival # Prepare the mirror list. 345308e23beeSColin Percival fetch_pick_server_init && fetch_pick_server 345408e23beeSColin Percival 345508e23beeSColin Percival # Try to fetch the public key until we run out of servers. 345608e23beeSColin Percival while ! fetch_key; do 345708e23beeSColin Percival fetch_pick_server || return 1 345808e23beeSColin Percival done 345908e23beeSColin Percival 346008e23beeSColin Percival # Try to fetch the metadata index signature ("tag") until we run 346108e23beeSColin Percival # out of available servers; and sanity check the downloaded tag. 346208e23beeSColin Percival while ! fetch_tag; do 346308e23beeSColin Percival fetch_pick_server || return 1 346408e23beeSColin Percival done 346508e23beeSColin Percival fetch_tagsanity || return 1 346608e23beeSColin Percival 346708e23beeSColin Percival # Fetch INDEX-OLD and INDEX-ALL. 346808e23beeSColin Percival fetch_metadata INDEX-OLD INDEX-ALL || return 1 346908e23beeSColin Percival 347008e23beeSColin Percival # Generate filtered INDEX-OLD and INDEX-ALL files containing only 347108e23beeSColin Percival # the components we want and without anything marked as "Ignore". 347208e23beeSColin Percival fetch_filter_metadata INDEX-OLD || return 1 347308e23beeSColin Percival fetch_filter_metadata INDEX-ALL || return 1 347408e23beeSColin Percival 347508e23beeSColin Percival # Merge the INDEX-OLD and INDEX-ALL files into INDEX-ALL. 347608e23beeSColin Percival sort INDEX-OLD INDEX-ALL > INDEX-ALL.tmp 347708e23beeSColin Percival mv INDEX-ALL.tmp INDEX-ALL 347808e23beeSColin Percival rm INDEX-OLD 347908e23beeSColin Percival 348008e23beeSColin Percival # Translate /boot/${KERNCONF} to ${KERNELDIR} 348108e23beeSColin Percival fetch_filter_kernel_names INDEX-ALL ${KERNCONF} 348208e23beeSColin Percival 348308e23beeSColin Percival # Inspect the system and generate an INDEX-PRESENT file. 348408e23beeSColin Percival fetch_inspect_system INDEX-ALL INDEX-PRESENT /dev/null || return 1 348508e23beeSColin Percival 348608e23beeSColin Percival # Compare INDEX-ALL and INDEX-PRESENT and print warnings about any 348708e23beeSColin Percival # differences. 348808e23beeSColin Percival IDS_compare INDEX-ALL INDEX-PRESENT 348908e23beeSColin Percival} 349008e23beeSColin Percival 349148ffe56aSColin Percival#### Main functions -- call parameter-handling and core functions 349248ffe56aSColin Percival 349348ffe56aSColin Percival# Using the command line, configuration file, and defaults, 349448ffe56aSColin Percival# set all the parameters which are needed later. 349548ffe56aSColin Percivalget_params () { 349648ffe56aSColin Percival init_params 349748ffe56aSColin Percival parse_cmdline $@ 349848ffe56aSColin Percival parse_conffile 349948ffe56aSColin Percival default_params 350048ffe56aSColin Percival} 350148ffe56aSColin Percival 350248ffe56aSColin Percival# Fetch command. Make sure that we're being called 350348ffe56aSColin Percival# interactively, then run fetch_check_params and fetch_run 350448ffe56aSColin Percivalcmd_fetch () { 35059a63bbc9SColin Percival finalize_components_config ${COMPONENTS} 35068bf2dcceSAllan Jude if [ ! -t 0 -a $NOTTYOK -eq 0 ]; then 350748ffe56aSColin Percival echo -n "`basename $0` fetch should not " 350848ffe56aSColin Percival echo "be run non-interactively." 350948ffe56aSColin Percival echo "Run `basename $0` cron instead." 351048ffe56aSColin Percival exit 1 351148ffe56aSColin Percival fi 351248ffe56aSColin Percival fetch_check_params 351348ffe56aSColin Percival fetch_run || exit 1 351433bd05c3SGuangyuan Yang ISFETCHED=1 351548ffe56aSColin Percival} 351648ffe56aSColin Percival 351748ffe56aSColin Percival# Cron command. Make sure the parameters are sensible; wait 351848ffe56aSColin Percival# rand(3600) seconds; then fetch updates. While fetching updates, 351948ffe56aSColin Percival# send output to a temporary file; only print that file if the 352048ffe56aSColin Percival# fetching failed. 352148ffe56aSColin Percivalcmd_cron () { 352248ffe56aSColin Percival fetch_check_params 352348ffe56aSColin Percival sleep `jot -r 1 0 3600` 352448ffe56aSColin Percival 352548ffe56aSColin Percival TMPFILE=`mktemp /tmp/freebsd-update.XXXXXX` || exit 1 35269a63bbc9SColin Percival finalize_components_config ${COMPONENTS} >> ${TMPFILE} 352748ffe56aSColin Percival if ! fetch_run >> ${TMPFILE} || 352848ffe56aSColin Percival ! grep -q "No updates needed" ${TMPFILE} || 352948ffe56aSColin Percival [ ${VERBOSELEVEL} = "debug" ]; then 353048ffe56aSColin Percival mail -s "`hostname` security updates" ${MAILTO} < ${TMPFILE} 353148ffe56aSColin Percival fi 353285c3ef77SMichael Osipov ISFETCHED=1 353348ffe56aSColin Percival 353448ffe56aSColin Percival rm ${TMPFILE} 353548ffe56aSColin Percival} 353648ffe56aSColin Percival 3537db6b0a61SColin Percival# Fetch files for upgrading to a new release. 3538db6b0a61SColin Percivalcmd_upgrade () { 3539*cf1aba28SEd Maste check_pkgbase 35409a63bbc9SColin Percival finalize_components_config ${COMPONENTS} 3541db6b0a61SColin Percival upgrade_check_params 3542bc0c6c9cSFernando Apesteguía upgrade_check_kmod_ports 3543db6b0a61SColin Percival upgrade_run || exit 1 3544db6b0a61SColin Percival} 3545db6b0a61SColin Percival 3546101d33b8SMichael Gmelin# Check if there are fetched updates ready to install. 3547101d33b8SMichael Gmelin# Chdir into the working directory. 35488cfda118SMichael Gmelincmd_updatesready () { 35499a63bbc9SColin Percival finalize_components_config ${COMPONENTS} 3550101d33b8SMichael Gmelin # Check if working directory exists (if not, no updates pending) 3551101d33b8SMichael Gmelin if ! [ -e "${WORKDIR}" ]; then 3552101d33b8SMichael Gmelin echo "No updates are available to install." 3553101d33b8SMichael Gmelin exit 2 3554101d33b8SMichael Gmelin fi 3555101d33b8SMichael Gmelin 3556101d33b8SMichael Gmelin # Change into working directory (fail if no permission/directory etc.) 3557101d33b8SMichael Gmelin cd ${WORKDIR} || exit 1 3558101d33b8SMichael Gmelin 35598cfda118SMichael Gmelin # Construct a unique name from ${BASEDIR} 35608cfda118SMichael Gmelin BDHASH=`echo ${BASEDIR} | sha256 -q` 35618cfda118SMichael Gmelin 35628cfda118SMichael Gmelin # Check that we have updates ready to install 35638cfda118SMichael Gmelin if ! [ -L ${BDHASH}-install ]; then 35648cfda118SMichael Gmelin echo "No updates are available to install." 35658cfda118SMichael Gmelin exit 2 35668cfda118SMichael Gmelin fi 35678cfda118SMichael Gmelin 35688cfda118SMichael Gmelin echo "There are updates available to install." 356959b02bb4SMichael Osipov echo "Run '`basename $0` [options] install' to proceed." 35708cfda118SMichael Gmelin} 35718cfda118SMichael Gmelin 357248ffe56aSColin Percival# Install downloaded updates. 357348ffe56aSColin Percivalcmd_install () { 3574*cf1aba28SEd Maste check_pkgbase 35759a63bbc9SColin Percival finalize_components_config ${COMPONENTS} 357648ffe56aSColin Percival install_check_params 3577f28f1389SDave Fullard install_create_be 357848ffe56aSColin Percival install_run || exit 1 357948ffe56aSColin Percival} 358048ffe56aSColin Percival 358148ffe56aSColin Percival# Rollback most recently installed updates. 358248ffe56aSColin Percivalcmd_rollback () { 3583*cf1aba28SEd Maste check_pkgbase 35849a63bbc9SColin Percival finalize_components_config ${COMPONENTS} 358548ffe56aSColin Percival rollback_check_params 358648ffe56aSColin Percival rollback_run || exit 1 358748ffe56aSColin Percival} 358848ffe56aSColin Percival 358908e23beeSColin Percival# Compare system against a "known good" index. 359008e23beeSColin Percivalcmd_IDS () { 35919a63bbc9SColin Percival finalize_components_config ${COMPONENTS} 359208e23beeSColin Percival IDS_check_params 359308e23beeSColin Percival IDS_run || exit 1 359408e23beeSColin Percival} 359508e23beeSColin Percival 35968cfda118SMichael Gmelin# Output configuration. 35978cfda118SMichael Gmelincmd_showconfig () { 35989a63bbc9SColin Percival finalize_components_config ${COMPONENTS} 35998cfda118SMichael Gmelin for X in ${CONFIGOPTIONS}; do 36008cfda118SMichael Gmelin echo $X=$(eval echo \$${X}) 36018cfda118SMichael Gmelin done 36028cfda118SMichael Gmelin} 36038cfda118SMichael Gmelin 360448ffe56aSColin Percival#### Entry point 360548ffe56aSColin Percival 360648ffe56aSColin Percival# Make sure we find utilities from the base system 360748ffe56aSColin Percivalexport PATH=/sbin:/bin:/usr/sbin:/usr/bin:${PATH} 360848ffe56aSColin Percival 36099c990fb2SGordon Tetlow# Set a pager if the user doesn't 36109c990fb2SGordon Tetlowif [ -z "$PAGER" ]; then 361147cc9ee1SAlan Somers PAGER=/usr/bin/less 36129c990fb2SGordon Tetlowfi 36139c990fb2SGordon Tetlow 3614f2890dbdSColin Percival# Set LC_ALL in order to avoid problems with character ranges like [A-Z]. 3615f2890dbdSColin Percivalexport LC_ALL=C 3616f2890dbdSColin Percival 3617e093c61bSEd Maste# Clear environment variables that may affect operation of tools that we use. 3618e093c61bSEd Masteunset GREP_OPTIONS 3619e093c61bSEd Maste 362048ffe56aSColin Percivalget_params $@ 362148ffe56aSColin Percivalfor COMMAND in ${COMMANDS}; do 362248ffe56aSColin Percival cmd_${COMMAND} 362348ffe56aSColin Percivaldone 3624