1182578Srik#!/bin/sh 2182578Srik# 3182578Srik# Copyright (C) 2008 Roman Kurakin rik@freebsd.org. All rights reserved. 4182578Srik# 5182578Srik# Redistribution and use in source and binary forms, with or without 6182578Srik# modification, are permitted provided that the following conditions 7182578Srik# are met: 8182578Srik# 1. Redistributions of source code must retain the above copyright 9182578Srik# notice, this list of conditions and the following disclaimer. 10182578Srik# 2. Redistributions in binary form must reproduce the above copyright 11182578Srik# notice, this list of conditions and the following disclaimer in the 12182578Srik# documentation and/or other materials provided with the distribution. 13182578Srik# 14182578Srik# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15182578Srik# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16182578Srik# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17182578Srik# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 18182578Srik# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19182578Srik# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20182578Srik# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21182578Srik# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22182578Srik# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23182578Srik# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24182578Srik# SUCH DAMAGE. 25182578Srik# 26182578Srik# Merges FreeBSD's several CD installation medias to the single DVD disk. 27182578Srik# 28182578Srik# $FreeBSD$ 29182578Srik 30182578Srik## Helper functions 31182578Srikusage () { 32182578Srik echo "Usage: $0 <dvd_img_name> <cd_img_name <cd_img_name ..>>" 33182578Srik} 34182578Srik 35182578Srik# Copy data from the cd 36182578Srik# $1 os name 37182578Srik# $2 disk image name 38182578Srik# $3 mount dir 39182578Srik# $4 destination dir 40182578Srikcopycd () { 41182578Srik # Set some variables 42182578Srik md="" 43182578Srik _os="${1}" 44182578Srik _img="${2}" 45182578Srik _mnt="${3}" 46182578Srik _dst="${4}" 47182578Srik if [ $# -ne "4" ] 48182578Srik then 49182578Srik echo "Error: function ${0} takes exactly four parameters." 50182578Srik exit 1 51182578Srik fi 52182578Srik if [ "${_os}" != "FreeBSD" -a "${_os}" != "Linux" ] 53182578Srik then 54182578Srik echo "Error: do not know how to handle ${_os} os." 55182578Srik exit 1 56182578Srik fi 57182578Srik if [ ! -f "${_img}" ] 58182578Srik then 59182578Srik echo "Error: file ${_img} does not exists or not a regula file." 60182578Srik exit 1 61182578Srik fi 62182578Srik if [ ! -r "${_img}" ] 63182578Srik then 64182578Srik echo "Error: you do not have the read permissions." 65182578Srik exit 1 66182578Srik fi 67182578Srik if [ ! -d "${_mnt}" ] 68182578Srik then 69182578Srik echo "Error: ${_mnt} is not a directory or does not exists." 70182578Srik fi 71182578Srik if [ ! -d "${_dst}" ] 72182578Srik then 73182578Srik echo "Error: ${_dst} is not a directory or does not exists." 74182578Srik fi 75182578Srik if [ ! -w "${_dst}" ] 76182578Srik then 77182578Srik echo "Error: you do not have write permissions granted for ${_dst} directory." 78182578Srik fi 79182578Srik if [ "${_os}" != "Linux" ] 80182578Srik then 81182578Srik md=`mdconfig -a -t vnode -f ${_img}` || exit 1 82182578Srik mount_cd9660 /dev/${md} ${_mnt} || exit 1 83182578Srik else 84182578Srik mount -o loop ${_img} ${_mnt} || exit 1 85182578Srik fi 86182578Srik if [ ! -f ${_mnt}/cdrom.inf ] 87182578Srik then 88182578Srik echo "Error: Failed to find cdrom.inf for ${_img}." 89182578Srik exit 1 90182578Srik fi 91182578Srik cdvol=`grep "^CD_VOLUME.*" ${_mnt}/cdrom.inf | sed "s/CD_VOLUME[[:space:]]*=[[:space:]]*//"` 92182578Srik if test -z "${cdvol}" -o ! "${cdvol}" -eq "${cdvol}" 2> /dev/null 93182578Srik then 94182578Srik echo "Error: failed to get volume id for ${_img}." 95182578Srik exit 1 96182578Srik fi 97182578Srik cdver=`grep "^CD_VERSION.*" ${_mnt}/cdrom.inf | sed "s/CD_VERSION[[:space:]]*=[[:space:]]*//"` 98182578Srik if test -z "${cdver}" 99182578Srik then 100182578Srik echo "Error: failed to get version id for ${_img}." 101182578Srik exit 1 102182578Srik fi 103182578Srik if [ -z "${VERID}" ] 104182578Srik then 105182578Srik VERID="${cdver}" 106182578Srik _exclude="" 107182578Srik else 108182578Srik if [ "${VERID}" != "${cdver}" ] 109182578Srik then 110182578Srik echo "Error: cd version ids mismatch while processing ${_img}." 111182578Srik exit 1 112182578Srik fi 113182578Srik# _exclude="--exclude ./cdrom.inf --exclude ./packages/INDEX" 114182578Srik _exclude="! -regex ./cdrom.inf ! -regex ./packages/INDEX" 115182578Srik fi 116182578Srik echo "Merging ${_img}:" 117182578Srik# --quite -u -V 118182578Srik (cd "${_mnt}" && find . ${_exclude} | cpio -p -d -m -V --quiet "${_dst}") || exit 1 119182578Srik# (cd "${_mnt}" && tar ${_exclude} -cvf - .) | (cd "${_dst}" && tar xvf -) || exit 1 120182578Srik if [ "${_os}" != "Linux" ] 121182578Srik then 122182578Srik umount /dev/${md} || exit 1 123182578Srik mdconfig -d -u "${md}" || exit 1 124182578Srik else 125182578Srik umount ${_mnt} || exit 1 126182578Srik fi 127182578Srik# exit 0 128182578Srik} 129182578Srik 130182578Srik# Clear mounted image 131182578Srik# $1 mounted directory 132182578Srik# $2 error code 133182578Srikclearmount () 134182578Srik{ 135182578Srik if [ $# -ne "2" ] 136182578Srik then 137182578Srik echo "Error: function ${0} takes exactly two parameters." 138182578Srik exit 1 139182578Srik fi 140182578Srik if [ -z "${1}" ] 141182578Srik then 142182578Srik test -z "${2}" || exit "${2}" 143182578Srik else 144182578Srik # Ignore errors 145182578Srik umount "${1}" 2>/dev/null 146182578Srik test -z "${2}" || exit "${2}" 147182578Srik fi 148182578Srik} 149182578Srik 150182578Srik# Clear CD image allocation 151182578Srik# $1 os name 152182578Srik# $2 md 153182578Srik# $3 error code 154182578Srikclearmd () 155182578Srik{ 156182578Srik if [ $# -ne "3" ] 157182578Srik then 158182578Srik echo "Error: function ${0} takes exactly three parameters." 159182578Srik exit 1 160182578Srik fi 161182578Srik if [ "${1}" != "FreeBSD" -o -z "${2}" ] 162182578Srik then 163182578Srik test -z "${3}" || exit "${3}" 164182578Srik else 165182578Srik # Ignore errors 166182578Srik mdconfig -d -u "${2}" 2>/dev/null 167182578Srik test -z "${3}" || exit "${3}" 168182578Srik fi 169182578Srik} 170182578Srik 171182578Srik## Check params 172182578Srikif [ $# -lt 3 ] 173182578Srikthen 174182578Srik usage 175182578Srik echo "Error, this script should take more than two parameters." 176182578Srik exit 1 177182578Srikfi 178182578Srik 179182578Srik# Check if zero 180182578Srikif [ -z "${1}" ]; then 181182578Srik usage 182182578Srik exit 1 183182578Srikfi 184182578Srik 185182578Srik# Check if already exists 186182578Srikif [ -e "${1}" ]; then 187182578Srik if [ ! -f "${1}" ]; then 188182578Srik echo "Destination DVD image file already exists and is not a regular file." 189182578Srik exit 1 190182578Srik fi 191182578Srik while echo "The ${1} file exists. Overwrite? (y/n)" 192182578Srik do 193182578Srik read line 194182578Srik case "${line}" in 195182578Srik y|Y) 196182578Srik rm -rf "${1}" 197182578Srik touch "${1}" 198182578Srik break 199182578Srik ;; 200182578Srik n|N) 201182578Srik echo "Please, run program again with a new value." 202182578Srik exit 1 203182578Srik ;; 204182578Srik esac 205182578Srik done 206182578Srikfi 207182578SrikDVDIMAGE="${1}" 208182578Srik 209182578Srikshift 210182578Srik 211182578Srikcount=0 212182578Srikfor i in "$@" 213182578Srikdo 214182578Srik # Skip empty params. 215182578Srik if test -z "${i}"; then 216182578Srik continue 217182578Srik fi 218182578Srik if [ ! -f "${i}" -o ! -r "${i}" ] 219182578Srik then 220182578Srik echo "Error: The ${i} is not readable, do not exists or not a regular file." 221182578Srik exit 1 222182578Srik fi 223182578Srik count=`expr ${count} \+ 1` 224182578Srikdone 225182578Srik 226182578Srik# Check if we have at the least two CD images 227182578Srikif [ "${count}" -lt 2 ] 228182578Srikthen 229182578Srik echo "Error: less than two CD images specified." 230182578Srikfi 231182578Srik 232228975Suqs## Some useful variables 233182578Srikpwd=`pwd` 234182578Sriktmpdirin="${pwd}/tmp-$$-in" 235182578Sriktmpdirout="${pwd}/tmp-$$-out" 236182578Sriksystem=`uname -s` 237182578Srikmd="" 238182578Srik 239182578Srik# set the trap options 240182578Sriktrap 'echo ""; echo "Cleaning up"; clearmount "${tmpdirin}" ""; clearmd "${system}" "${md}" ""; rm -rf "${tmpdirin}" "${tmpdirout}";' 0 1 2 3 15 241182578Srikmkdir "${tmpdirin}" || (echo "Error: failed to create tempory ${tmpdirin}"; exit 1) 242182578Srikmkdir "${tmpdirout}" || (echo "Error: failed to create tempory ${tmpdirout}"; exit 1) 243182578Srik 244182578Srikfor i in "$@" 245182578Srikdo 246182578Srik # Skip empty params. 247182578Srik if test -z "${i}"; then 248182578Srik continue 249182578Srik fi 250182578Srik copycd "${system}" "${i}" "${tmpdirin}" "${tmpdirout}" 251182578Srik mv "${tmpdirout}"/packages/INDEX "${tmpdirout}"/packages/INDEX~ || exit 1 252182578Srik cat "${tmpdirout}"/packages/INDEX~ | sed "s/^\(.*\)|${cdvol}$/\1|1/" > "${tmpdirout}"/packages/INDEX || exit 1 253182578Srik rm "${tmpdirout}"/packages/INDEX~ || exit 1 254182578Srikdone 255182578Srik 256182578Srikmv "${tmpdirout}"/cdrom.inf "${tmpdirout}"/cdrom.inf~ || exit 1 257182578Srikcat "${tmpdirout}"/cdrom.inf~ | sed "s/^\(CD_VOLUME[[:space:]]\{0,\}=[[:space:]]\{0,\}\)[[:digit:]]\{1,\}/\11/" > "${tmpdirout}"/cdrom.inf || exit 1 258182578Srikrm "${tmpdirout}"/cdrom.inf~ || exit 1 259182578Srik 260182578Srikmkisofs -b boot/cdboot -no-emul-boot -r -J \ 261182578Srik -V "FreeBSD_Install" \ 262182578Srik -publisher "The FreeBSD Project. http://www.freebsd.org/" \ 263182578Srik -o ${DVDIMAGE} "${tmpdirout}" \ 264182578Srik || exit 1 265182578Srik 266182578Srikexit 0 267182578Srik 268