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# $FreeBSD$ 29 30## Helper functions 31usage () { 32 echo "Usage: $0 <dvd_img_name> <cd_img_name <cd_img_name ..>>" 33} 34 35# Copy data from the cd 36# $1 os name 37# $2 disk image name 38# $3 mount dir 39# $4 destination dir 40copycd () { 41 # Set some variables 42 md="" 43 _os="${1}" 44 _img="${2}" 45 _mnt="${3}" 46 _dst="${4}" 47 if [ $# -ne "4" ] 48 then 49 echo "Error: function ${0} takes exactly four parameters." 50 exit 1 51 fi 52 if [ "${_os}" != "FreeBSD" -a "${_os}" != "Linux" ] 53 then 54 echo "Error: do not know how to handle ${_os} os." 55 exit 1 56 fi 57 if [ ! -f "${_img}" ] 58 then 59 echo "Error: file ${_img} does not exists or not a regula file." 60 exit 1 61 fi 62 if [ ! -r "${_img}" ] 63 then 64 echo "Error: you do not have the read permissions." 65 exit 1 66 fi 67 if [ ! -d "${_mnt}" ] 68 then 69 echo "Error: ${_mnt} is not a directory or does not exists." 70 fi 71 if [ ! -d "${_dst}" ] 72 then 73 echo "Error: ${_dst} is not a directory or does not exists." 74 fi 75 if [ ! -w "${_dst}" ] 76 then 77 echo "Error: you do not have write permissions granted for ${_dst} directory." 78 fi 79 if [ "${_os}" != "Linux" ] 80 then 81 md=`mdconfig -a -t vnode -f ${_img}` || exit 1 82 mount_cd9660 /dev/${md} ${_mnt} || exit 1 83 else 84 mount -o loop ${_img} ${_mnt} || exit 1 85 fi 86 if [ ! -f ${_mnt}/cdrom.inf ] 87 then 88 echo "Error: Failed to find cdrom.inf for ${_img}." 89 exit 1 90 fi 91 cdvol=`grep "^CD_VOLUME.*" ${_mnt}/cdrom.inf | sed "s/CD_VOLUME[[:space:]]*=[[:space:]]*//"` 92 if test -z "${cdvol}" -o ! "${cdvol}" -eq "${cdvol}" 2> /dev/null 93 then 94 echo "Error: failed to get volume id for ${_img}." 95 exit 1 96 fi 97 cdver=`grep "^CD_VERSION.*" ${_mnt}/cdrom.inf | sed "s/CD_VERSION[[:space:]]*=[[:space:]]*//"` 98 if test -z "${cdver}" 99 then 100 echo "Error: failed to get version id for ${_img}." 101 exit 1 102 fi 103 if [ -z "${VERID}" ] 104 then 105 VERID="${cdver}" 106 _exclude="" 107 else 108 if [ "${VERID}" != "${cdver}" ] 109 then 110 echo "Error: cd version ids mismatch while processing ${_img}." 111 exit 1 112 fi 113# _exclude="--exclude ./cdrom.inf --exclude ./packages/INDEX" 114 _exclude="! -regex ./cdrom.inf ! -regex ./packages/INDEX" 115 fi 116 echo "Merging ${_img}:" 117# --quite -u -V 118 (cd "${_mnt}" && find . ${_exclude} | cpio -p -d -m -V --quiet "${_dst}") || exit 1 119# (cd "${_mnt}" && tar ${_exclude} -cvf - .) | (cd "${_dst}" && tar xvf -) || exit 1 120 if [ "${_os}" != "Linux" ] 121 then 122 umount /dev/${md} || exit 1 123 mdconfig -d -u "${md}" || exit 1 124 else 125 umount ${_mnt} || exit 1 126 fi 127# exit 0 128} 129 130# Clear mounted image 131# $1 mounted directory 132# $2 error code 133clearmount () 134{ 135 if [ $# -ne "2" ] 136 then 137 echo "Error: function ${0} takes exactly two parameters." 138 exit 1 139 fi 140 if [ -z "${1}" ] 141 then 142 test -z "${2}" || exit "${2}" 143 else 144 # Ignore errors 145 umount "${1}" 2>/dev/null 146 test -z "${2}" || exit "${2}" 147 fi 148} 149 150# Clear CD image allocation 151# $1 os name 152# $2 md 153# $3 error code 154clearmd () 155{ 156 if [ $# -ne "3" ] 157 then 158 echo "Error: function ${0} takes exactly three parameters." 159 exit 1 160 fi 161 if [ "${1}" != "FreeBSD" -o -z "${2}" ] 162 then 163 test -z "${3}" || exit "${3}" 164 else 165 # Ignore errors 166 mdconfig -d -u "${2}" 2>/dev/null 167 test -z "${3}" || exit "${3}" 168 fi 169} 170 171## Check params 172if [ $# -lt 3 ] 173then 174 usage 175 echo "Error, this script should take more than two parameters." 176 exit 1 177fi 178 179# Check if zero 180if [ -z "${1}" ]; then 181 usage 182 exit 1 183fi 184 185# Check if already exists 186if [ -e "${1}" ]; then 187 if [ ! -f "${1}" ]; then 188 echo "Destination DVD image file already exists and is not a regular file." 189 exit 1 190 fi 191 while echo "The ${1} file exists. Overwrite? (y/n)" 192 do 193 read line 194 case "${line}" in 195 y|Y) 196 rm -rf "${1}" 197 touch "${1}" 198 break 199 ;; 200 n|N) 201 echo "Please, run program again with a new value." 202 exit 1 203 ;; 204 esac 205 done 206fi 207DVDIMAGE="${1}" 208 209shift 210 211count=0 212for i in "$@" 213do 214 # Skip empty params. 215 if test -z "${i}"; then 216 continue 217 fi 218 if [ ! -f "${i}" -o ! -r "${i}" ] 219 then 220 echo "Error: The ${i} is not readable, do not exists or not a regular file." 221 exit 1 222 fi 223 count=`expr ${count} \+ 1` 224done 225 226# Check if we have at the least two CD images 227if [ "${count}" -lt 2 ] 228then 229 echo "Error: less than two CD images specified." 230fi 231 232## Some useful variables 233pwd=`pwd` 234tmpdirin="${pwd}/tmp-$$-in" 235tmpdirout="${pwd}/tmp-$$-out" 236system=`uname -s` 237md="" 238 239# set the trap options 240trap 'echo ""; echo "Cleaning up"; clearmount "${tmpdirin}" ""; clearmd "${system}" "${md}" ""; rm -rf "${tmpdirin}" "${tmpdirout}";' 0 1 2 3 15 241mkdir "${tmpdirin}" || (echo "Error: failed to create tempory ${tmpdirin}"; exit 1) 242mkdir "${tmpdirout}" || (echo "Error: failed to create tempory ${tmpdirout}"; exit 1) 243 244for i in "$@" 245do 246 # Skip empty params. 247 if test -z "${i}"; then 248 continue 249 fi 250 copycd "${system}" "${i}" "${tmpdirin}" "${tmpdirout}" 251 mv "${tmpdirout}"/packages/INDEX "${tmpdirout}"/packages/INDEX~ || exit 1 252 cat "${tmpdirout}"/packages/INDEX~ | sed "s/^\(.*\)|${cdvol}$/\1|1/" > "${tmpdirout}"/packages/INDEX || exit 1 253 rm "${tmpdirout}"/packages/INDEX~ || exit 1 254done 255 256mv "${tmpdirout}"/cdrom.inf "${tmpdirout}"/cdrom.inf~ || exit 1 257cat "${tmpdirout}"/cdrom.inf~ | sed "s/^\(CD_VOLUME[[:space:]]\{0,\}=[[:space:]]\{0,\}\)[[:digit:]]\{1,\}/\11/" > "${tmpdirout}"/cdrom.inf || exit 1 258rm "${tmpdirout}"/cdrom.inf~ || exit 1 259 260mkisofs -b boot/cdboot -no-emul-boot -r -J \ 261 -V "FreeBSD_Install" \ 262 -publisher "The FreeBSD Project. https://www.freebsd.org/" \ 263 -o ${DVDIMAGE} "${tmpdirout}" \ 264 || exit 1 265 266exit 0 267 268