1#!/bin/sh 2# 3# Copyright (C) 2008 Roman Kurakin rik@freebsd.org. All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions 7# are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 14# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 18# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24# SUCH DAMAGE. 25# 26# Merges FreeBSD's several CD installation medias to the single DVD disk. 27# 28 29## Helper functions 30usage () { 31 echo "Usage: $0 <dvd_img_name> <cd_img_name <cd_img_name ..>>" 32} 33 34# Copy data from the cd 35# $1 os name 36# $2 disk image name 37# $3 mount dir 38# $4 destination dir 39copycd () { 40 # Set some variables 41 md="" 42 _os="${1}" 43 _img="${2}" 44 _mnt="${3}" 45 _dst="${4}" 46 if [ $# -ne "4" ] 47 then 48 echo "Error: function ${0} takes exactly four parameters." 49 exit 1 50 fi 51 if [ "${_os}" != "FreeBSD" -a "${_os}" != "Linux" ] 52 then 53 echo "Error: do not know how to handle ${_os} os." 54 exit 1 55 fi 56 if [ ! -f "${_img}" ] 57 then 58 echo "Error: file ${_img} does not exists or not a regula file." 59 exit 1 60 fi 61 if [ ! -r "${_img}" ] 62 then 63 echo "Error: you do not have the read permissions." 64 exit 1 65 fi 66 if [ ! -d "${_mnt}" ] 67 then 68 echo "Error: ${_mnt} is not a directory or does not exists." 69 fi 70 if [ ! -d "${_dst}" ] 71 then 72 echo "Error: ${_dst} is not a directory or does not exists." 73 fi 74 if [ ! -w "${_dst}" ] 75 then 76 echo "Error: you do not have write permissions granted for ${_dst} directory." 77 fi 78 if [ "${_os}" != "Linux" ] 79 then 80 md=`mdconfig -a -t vnode -f ${_img}` || exit 1 81 mount_cd9660 /dev/${md} ${_mnt} || exit 1 82 else 83 mount -o loop ${_img} ${_mnt} || exit 1 84 fi 85 if [ ! -f ${_mnt}/cdrom.inf ] 86 then 87 echo "Error: Failed to find cdrom.inf for ${_img}." 88 exit 1 89 fi 90 cdvol=`grep "^CD_VOLUME.*" ${_mnt}/cdrom.inf | sed "s/CD_VOLUME[[:space:]]*=[[:space:]]*//"` 91 if test -z "${cdvol}" -o ! "${cdvol}" -eq "${cdvol}" 2> /dev/null 92 then 93 echo "Error: failed to get volume id for ${_img}." 94 exit 1 95 fi 96 cdver=`grep "^CD_VERSION.*" ${_mnt}/cdrom.inf | sed "s/CD_VERSION[[:space:]]*=[[:space:]]*//"` 97 if test -z "${cdver}" 98 then 99 echo "Error: failed to get version id for ${_img}." 100 exit 1 101 fi 102 if [ -z "${VERID}" ] 103 then 104 VERID="${cdver}" 105 _exclude="" 106 else 107 if [ "${VERID}" != "${cdver}" ] 108 then 109 echo "Error: cd version ids mismatch while processing ${_img}." 110 exit 1 111 fi 112# _exclude="--exclude ./cdrom.inf --exclude ./packages/INDEX" 113 _exclude="! -regex ./cdrom.inf ! -regex ./packages/INDEX" 114 fi 115 echo "Merging ${_img}:" 116# --quite -u -V 117 (cd "${_mnt}" && find . ${_exclude} | cpio -p -d -m -V --quiet "${_dst}") || exit 1 118# (cd "${_mnt}" && tar ${_exclude} -cvf - .) | (cd "${_dst}" && tar xvf -) || exit 1 119 if [ "${_os}" != "Linux" ] 120 then 121 umount /dev/${md} || exit 1 122 mdconfig -d -u "${md}" || exit 1 123 else 124 umount ${_mnt} || exit 1 125 fi 126# exit 0 127} 128 129# Clear mounted image 130# $1 mounted directory 131# $2 error code 132clearmount () 133{ 134 if [ $# -ne "2" ] 135 then 136 echo "Error: function ${0} takes exactly two parameters." 137 exit 1 138 fi 139 if [ -z "${1}" ] 140 then 141 test -z "${2}" || exit "${2}" 142 else 143 # Ignore errors 144 umount "${1}" 2>/dev/null 145 test -z "${2}" || exit "${2}" 146 fi 147} 148 149# Clear CD image allocation 150# $1 os name 151# $2 md 152# $3 error code 153clearmd () 154{ 155 if [ $# -ne "3" ] 156 then 157 echo "Error: function ${0} takes exactly three parameters." 158 exit 1 159 fi 160 if [ "${1}" != "FreeBSD" -o -z "${2}" ] 161 then 162 test -z "${3}" || exit "${3}" 163 else 164 # Ignore errors 165 mdconfig -d -u "${2}" 2>/dev/null 166 test -z "${3}" || exit "${3}" 167 fi 168} 169 170## Check params 171if [ $# -lt 3 ] 172then 173 usage 174 echo "Error, this script should take more than two parameters." 175 exit 1 176fi 177 178# Check if zero 179if [ -z "${1}" ]; then 180 usage 181 exit 1 182fi 183 184# Check if already exists 185if [ -e "${1}" ]; then 186 if [ ! -f "${1}" ]; then 187 echo "Destination DVD image file already exists and is not a regular file." 188 exit 1 189 fi 190 while echo "The ${1} file exists. Overwrite? (y/n)" 191 do 192 read line 193 case "${line}" in 194 y|Y) 195 rm -rf "${1}" 196 touch "${1}" 197 break 198 ;; 199 n|N) 200 echo "Please, run program again with a new value." 201 exit 1 202 ;; 203 esac 204 done 205fi 206DVDIMAGE="${1}" 207 208shift 209 210count=0 211for i in "$@" 212do 213 # Skip empty params. 214 if test -z "${i}"; then 215 continue 216 fi 217 if [ ! -f "${i}" -o ! -r "${i}" ] 218 then 219 echo "Error: The ${i} is not readable, do not exists or not a regular file." 220 exit 1 221 fi 222 count=`expr ${count} \+ 1` 223done 224 225# Check if we have at the least two CD images 226if [ "${count}" -lt 2 ] 227then 228 echo "Error: less than two CD images specified." 229fi 230 231## Some useful variables 232pwd=`pwd` 233tmpdirin="${pwd}/tmp-$$-in" 234tmpdirout="${pwd}/tmp-$$-out" 235system=`uname -s` 236md="" 237 238# set the trap options 239trap 'echo ""; echo "Cleaning up"; clearmount "${tmpdirin}" ""; clearmd "${system}" "${md}" ""; rm -rf "${tmpdirin}" "${tmpdirout}";' 0 1 2 3 15 240mkdir "${tmpdirin}" || (echo "Error: failed to create tempory ${tmpdirin}"; exit 1) 241mkdir "${tmpdirout}" || (echo "Error: failed to create tempory ${tmpdirout}"; exit 1) 242 243for i in "$@" 244do 245 # Skip empty params. 246 if test -z "${i}"; then 247 continue 248 fi 249 copycd "${system}" "${i}" "${tmpdirin}" "${tmpdirout}" 250 mv "${tmpdirout}"/packages/INDEX "${tmpdirout}"/packages/INDEX~ || exit 1 251 cat "${tmpdirout}"/packages/INDEX~ | sed "s/^\(.*\)|${cdvol}$/\1|1/" > "${tmpdirout}"/packages/INDEX || exit 1 252 rm "${tmpdirout}"/packages/INDEX~ || exit 1 253done 254 255mv "${tmpdirout}"/cdrom.inf "${tmpdirout}"/cdrom.inf~ || exit 1 256cat "${tmpdirout}"/cdrom.inf~ | sed "s/^\(CD_VOLUME[[:space:]]\{0,\}=[[:space:]]\{0,\}\)[[:digit:]]\{1,\}/\11/" > "${tmpdirout}"/cdrom.inf || exit 1 257rm "${tmpdirout}"/cdrom.inf~ || exit 1 258 259mkisofs -b boot/cdboot -no-emul-boot -r -J \ 260 -V "FreeBSD_Install" \ 261 -publisher "The FreeBSD Project. https://www.freebsd.org/" \ 262 -o ${DVDIMAGE} "${tmpdirout}" \ 263 || exit 1 264 265exit 0 266 267