#!/bin/sh -
# Copyright 2001 2002 Edson Brandi <ebrandi.home@uol.com.br>
# All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY EDSON BRANDI ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED.  IN NO EVENT EDSON BRANDI BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.

# Check UID
if [ "`id -u`" != "0" ]; then
        echo "Sorry, this must be done as root."
        exit 1
fi

DIALOG=${DIALOG=/usr/bin/dialog}

# Function to allow user`s choice about the prefered language
idioma() {

rm /tmp/opcao_*

tempfile=`/usr/bin/mktemp -t checklist`

dialog --menu "FreeBSD LiveCD - Choose your Language:" 12 60 4 \
        Br "Portuguese / Portugues" \
        En "English / Ingles" \
        Q "Quit / Sair" \
2> $tempfile 
        
opcao_idioma=`cat $tempfile`

# Lets load the lang files based on users` choice.
# It is such a simple work, nowadays pt_br and eng are expected, any other
# future lang must be added here.
case ${opcao_idioma} in
     Br)
     if [ -f ./lang/livecd_Br ] ; then
     . ./lang/livecd_Br
     touch /tmp/opcao_Br
     configurar
     . ./config
     . ./lang/livecd_Br
     verifica_config
     else
     echo "Idioma selecionado nao disponivel"
     exit 1
     fi
     ;;
     En)
     if [ -f ./lang/livecd_En ] ; then
     . ./lang/livecd_En
     touch /tmp/opcao_En
     configurar
     . ./config
     . ./lang/livecd_En
     verifica_config
     else
     echo "Language not Availble"
     exit 1
     fi
     ;;
     *)
     exit 1
     ;;
esac

}

# This function will create the directories structure that LiveCD will need
# They will all be created under $CHROOTDIR
prepara_diretorios() {

# check if $CHROOTDIR exists, if so, take schg flag out away from executable
# files and remove the directories.
if [ -r $CHROOTDIR ]; then
	echo "I will remove $CHROOTDIR , do you agree ? Press enter to continue or ^C to abort!"
	read junk
	echo "OK, doing rm -rf $CHROOTDIR"
        chflags -R noschg $CHROOTDIR
        rm -rf $CHROOTDIR
fi

# Creates the directory that will be LiveCD's root 
mkdir -p $CHROOTDIR 

# Creates LiveCD related directories

mtree -deU -f $LIVEDIR/files/LIVECD.raiz.dist -p $CHROOTDIR >> $LIVEDIR/log
mkdir /var/spool/clientmqueue

# Creates $CHROOTDIR/dist directory if $LIVECDINSTALL variable value is set to 1
if [ $LIVECDINSTALL -eq 1 ]; then
   mkdir $CHROOTDIR/dist
fi

# Shows dialog information box about the directories creation.
dialog --title "FreeBSD LiveCD" --msgbox "$c_dialogo_1" 5 60

}

# warning routines
aviso() {
dialog --title "FreeBSD LiveCD" --infobox "$g_dialogo_4" -1 -1
echo "$g_dialogo_3"
exit 1
}

# This function distributes binaries under $CHROOTDIR
distribui_binarios() {

echo "$z_dialogo_1"
echo "$z_dialogo_2"
read junk

/sbin/mount /cdrom

/bin/cat /cdrom/bin/bin.?? | /usr/bin/tar --unlink -xvpzf - -C $CHROOTDIR >> $LIVEDIR/log
/usr/sbin/mtree -deU -f /cdrom/bin/bin.mtree -p $CHROOTDIR >> $LIVEDIR/log

/bin/cat /cdrom/crypto/crypto.?? | /usr/bin/tar --unlink -xvpzf - -C $CHROOTDIR >> $LIVEDIR/log
mtree -deU -f /cdrom/crypto/crypto.mtree -p $CHROOTDIR >> $LIVEDIR/log

/bin/cat /cdrom/crypto/krb4.?? | /usr/bin/tar --unlink -xvpzf - -C $CHROOTDIR >> $LIVEDIR/log
/usr/sbin/mtree -deU -f /cdrom/crypto/krb4.mtree -p $CHROOTDIR >> $LIVEDIR/log

/bin/cat /cdrom/crypto/krb5.?? | /usr/bin/tar --unlink -xvpzf - -C $CHROOTDIR >> $LIVEDIR/log
/usr/sbin/mtree -deU -f /cdrom/crypto/krb5.mtree -p $CHROOTDIR >> $LIVEDIR/log

/bin/cat /cdrom/compat4x/compat4x.?? | /usr/bin/tar --unlink -xvpzf - -C $CHROOTDIR >> $LIVEDIR/log
/usr/sbin/mtree -deU -f /cdrom/compat4x/compat4x.mtree -p $CHROOTDIR >> $LIVEDIR/log

/bin/cat /cdrom/compat3x/compat3x.?? | /usr/bin/tar --unlink -xvpzf - -C $CHROOTDIR >> $LIVEDIR/log
/usr/sbin/mtree -deU -f /cdrom/compat3x/compat3x.mtree -p $CHROOTDIR >> $LIVEDIR/log

/bin/cat /cdrom/compat22/compat22.?? | /usr/bin/tar --unlink -xvpzf - -C $CHROOTDIR >> $LIVEDIR/log
/usr/sbin/mtree -deU -f /cdrom/compat22/compat22.mtree -p $CHROOTDIR >> $LIVEDIR/log

/bin/cat /cdrom/compat21/compat21.?? | /usr/bin/tar --unlink -xvpzf - -C $CHROOTDIR >> $LIVEDIR/log
/usr/sbin/mtree -deU -f /cdrom/compat21/compat21.mtree -p $CHROOTDIR >> $LIVEDIR/log

/bin/cat /cdrom/compat20/compat20.?? | /usr/bin/tar --unlink -xvpzf - -C $CHROOTDIR >> $LIVEDIR/log
/usr/sbin/mtree -deU -f /cdrom/compat20/compat20.mtree -p $CHROOTDIR >> $LIVEDIR/log

/bin/cat /cdrom/compat1x/compat1x.?? | /usr/bin/tar --unlink -xvpzf - -C $CHROOTDIR >> $LIVEDIR/log
/usr/sbin/mtree -deU -f /cdrom/compat1x/compat1x.mtree -p $CHROOTDIR >> $LIVEDIR/log

/bin/cat /cdrom/manpages/manpages.?? | /usr/bin/tar --unlink -xvpzf - -C $CHROOTDIR >> $LIVEDIR/log
/usr/sbin/mtree -deU -f /cdrom/manpages/manpages.mtree -p $CHROOTDIR >> $LIVEDIR/log

/bin/cat /cdrom/src/sbase.?? | /usr/bin/tar --unlink -xvpzf - -C $CHROOTDIR/usr/src/ >> $LIVEDIR/log
/bin/cat /cdrom/src/ssys.?? | /usr/bin/tar --unlink -xvpzf - -C $CHROOTDIR/usr/src/ >> $LIVEDIR/log

/sbin/umount /cdrom
       
# Copies /etc/resolv.conf to /etc under LiveCD ;-) 

if [ -f /etc/resolv.conf ]; then 
     cp -p /etc/resolv.conf $CHROOTDIR/etc
fi

mkdir $CHROOTDIR/bootstrap
cp -p $CHROOTDIR/sbin/mount $CHROOTDIR/bootstrap
cp -p $CHROOTDIR/sbin/umount $CHROOTDIR/bootstrap

# copies /stand to LiveCD's root
tar -cf - -C /stand . | tar xpf - -C $CHROOTDIR/stand/

# Creates distribution file that allows one to use LiveCD as an installation media.

if [ $LIVECDINSTALL -eq 1 ]; then
   cp $LIVEDIR/files/fstab.install $CHROOTDIR/dist
   cp /usr/src/etc/rc $CHROOTDIR/dist
fi

mkdir  $CHROOTDIR/scripts/lang
cp  $LIVEDIR/lang/*  $CHROOTDIR/scripts/lang
rm  $CHROOTDIR/scripts/lang/livecd_*

# Tells the user that the whole process was done ;-)
dialog --title "FreeBSD LiveCD" --msgbox "$d_dialogo_1" 5 60

cd $LIVEDIR
}

# Now, we will patch GENERIC accordingly to our changes and build LIVECD from it
gera_kernel() {

echo "Removing $COMPILEDIR" >> $LIVEDIR/log
rm -rf $COMPILEDIR >> $LIVEDIR/log

cd $KERNELDIR

# Copies GENERIC to LIVECD
echo "Copy $KERNELDIR/GENERIC $KERNELDIR/LIVECD" >> $LIVEDIR/log && \
cp $KERNELDIR/GENERIC $KERNELDIR/LIVECD >> $LIVEDIR/log && \

# Append LIVECD kernel options to Generic kernel
echo "Append LIVECD kernel options to Generic kernel" >> $LIVEDIR/log && \ 
cat  $LIVEDIR/files/patch_generic  >>  $KERNELDIR/LIVECD && \

# Lets build the kernel 
echo "Building kernel" >> $LIVEDIR/log && \
config LIVECD  >> $LIVEDIR/log && cd $COMPILEDIR && make depend  >> $LIVEDIR/log && \
make  >> $LIVEDIR/log && make install DESTDIR=$CHROOTDIR  >> $LIVEDIR/log || aviso

# Creates the Kernel to be installed if LiveCD will be used as instalation mediao.
if [ $LIVECDINSTALL -eq 1 ]; then
   cd $KERNELDIR 
   config GENERIC >> $LIVEDIR/log && cd $CHROOTDIR/usr/src/sys/compile/GENERIC && make depend >> $LIVEDIR/log && make >> $LIVEDIR/log && make install DESTDIR=$CHROOTDIR/dist  >> $LIVEDIR/log

mtree -c -i -p $CHROOTDIR -k gname,md5digest,mode,nlink,uname,size,link,type > /tmp/LiveCD.mtree
mv  /tmp/LiveCD.mtree $CHROOTDIR/dist

fi

# Tells the user that this process was done.
dialog --title "FreeBSD LiveCD" --msgbox "$k_dialogo_1" 5 60

cd $LIVEDIR

}

# Now we will patch all changed files under /etc
alterar_etc() {

cd $CHROOTDIR/etc && patch -p < $LIVEDIR/files/patch_rc || aviso

if [ -f /tmp/opcao_Br ]
then
cp $LIVEDIR/files/rc.live_Br $CHROOTDIR/etc/rc.live
else
cp $LIVEDIR/files/rc.live_En $CHROOTDIR/etc/rc.live
fi

cp $LIVEDIR/files/rc.conf $CHROOTDIR/etc
cp $LIVEDIR/files/fstab   $CHROOTDIR/etc
cp $LIVEDIR/files/motd   $CHROOTDIR/etc

cd $CHROOTDIR/dev

# We will need some devices if we intend to have virtual nodes, right?
# so lets make them ;-)
for i in 0 1 2 3 4 5 6 7 8 9
 do
   ./MAKEDEV vn$i
done;

# Lets copy all scripts to LiveCD's /
cp -Rp $LIVEDIR/scripts $CHROOTDIR/
rm -rf $CHROOTDIR/scripts/CVS

# Lets tell the user that /etc files were patched
dialog --title "FreeBSD LiveCD" --msgbox "$e_dialogo_1" 5 60

cd $LIVEDIR

}

# This function generates ISOs and files to populate MFS
gera_iso() {

echo "I will remove $CHROOTDIR/usr/src before generate LiveCD.iso."
echo "This operation will go to reduce the final size of the ISO in 142 Mb!"
echo "Do you agree ? Press enter to continue or ^C to abort!"
read junk
echo "OK, doing rm -rf $CHROOTDIR/usr/src"
rm -rf $CHROOTDIR/usr/src

# Lets create the .tgz files that will be used to mount MFS
cd $CHROOTDIR
tar cvzfp mfs/etc.tgz etc >> $LIVEDIR/log
tar cvzfp mfs/dev.tgz dev >> $LIVEDIR/log
tar cvzfp mfs/root.tgz root >> $LIVEDIR/log
tar cvzfp mfs/local_etc.tgz usr/local/etc >> $LIVEDIR/log

# Copies all the necessary files to make a bootable CD
cp $LIVEDIR/files/boot.catalog $CHROOTDIR/boot >> $LIVEDIR/log
cd $CHROOTDIR

# Now we make a Bootable ISO without emulating floppy 2.8 Mb boot style.
if [ -f /usr/local/bin/mkisofs ] ; then

        /usr/local/bin/mkisofs -b boot/cdboot -no-emul-boot -c boot/boot.catalog  -r -l -L -V LiveCD -o $LIVEISODIR/LiveCD.iso . >> $LIVEDIR/log || aviso
	dialog --title "FreeBSD LiveCD" --msgbox "$i_dialogo_1" 5 60

else
        
	dialog --title "FreeBSD LiveCD" --msgbox "$i_dialogo_2" 5 75
	#
	# If mkisofs does not exist, we will install it ;-)
	cd /usr/ports/sysutils/mkisofs
	make >> $LIVEDIR/log
	make install >> $LIVEDIR/log
	make clean >> $LIVEDIR/log
	#
	dialog --title "FreeBSD LiveCD" --msgbox "$i_dialogo_3" 5 75
	#
	# makes ISO image.
	/usr/local/bin/mkisofs -b boot/cdboot -no-emul-boot -c boot/boot.catalog  -r -J -h -V LiveCD -o $LIVEISODIR/LiveCD.iso . >> $LIVEDIR/log || aviso
	dialog --title "FreeBSD LiveCD" --msgbox "$i_dialogo_1" 5 60

fi

# If ISO image was previously created, we tell the user it was done.
if [ -f $LIVEISODIR/LiveCD.iso ]; then
	dialog --title "FreeBSD LiveCD" --msgbox "$i_dialogo_4" 5 60
fi
 
cd $LIVEDIR

}

# Burn the house down! ;-)
# gee, sorry i was just envolved with garbage's lyrics...
# Burns the CD Image.
grava_iso() {

burncd -f $CDRW -s 8 -e data $LIVEISODIR/LiveCD.iso fixate >> $LIVEDIR/log || aviso
dialog --title "FreeBSD LiveCD" --msgbox "$i_dialogo_5" 5 60

cd $LIVEDIR

}

# Let's check if user has already confirm'd his options on config file

configurar() {
$DIALOG --title "FreeBSD LiveCD" --clear --inputbox "$config_1" 8 70 "`pwd`" 2> /tmp/input.tmp.$$
retval=$?

LIVEDIR=`cat /tmp/input.tmp.$$`
rm /tmp/input.tmp.$$

# We will TRAP to allow the user to abort the process...
case $retval in
  0)
    echo "LIVEDIR=$LIVEDIR" > ./config
    ;;
  1)
    echo "Cancel pressed."
    exit 1
    ;;
  255)
    echo "ESC pressed."
    exit 1
    ;;
esac

$DIALOG --title "FreeBSD LiveCD" --clear --inputbox "$config_2" 8 70 "/usr/live_root" 2>/tmp/input.tmp.$$
retval=$?

CHROOTDIR=`cat /tmp/input.tmp.$$`
rm /tmp/input.tmp.$$

# Trap again ;)
case $retval in
  0)
    echo "CHROOTDIR=$CHROOTDIR" >> ./config
    ;;
  1)
    echo "Cancel pressed."
    exit 1
    ;;
  255)
    echo "ESC pressed."
    exit 1
    ;;
esac

$DIALOG --title "FreeBSD LiveCD" --clear --inputbox "$config_3" 8 70 "/usr" 2>/tmp/input.tmp.$$
retval=$?

LIVEISODIR=`cat /tmp/input.tmp.$$`
rm /tmp/input.tmp.$$

# One more Trap, with the same purpose.
case $retval in
  0)
    echo "LIVEISODIR=$LIVEISODIR" >> ./config
    ;;
  1)
    echo "Cancel pressed."
    exit 1
    ;;
  255)
    echo "ESC pressed."
    exit 1
    ;;
esac

$DIALOG --title "FreeBSD LiveCD" --clear --yesno "$config_4" 8 70

case $? in
  0)
    echo "LIVECDINSTALL=1" >> ./config
    ;;
  1)
    echo "LIVECDINSTALL=0" >> ./config
    ;;
  255)
    echo "ESC pressed."
    exit 1
    ;;
esac

$DIALOG --title "FreeBSD LiveCD" --clear --yesno "$config_5" 8 70 

case $? in
  0)
     $DIALOG --title "FreeBSD LiveCD" --clear --inputbox "$config_6" 8 70 "/dev/acd0c" 2>/tmp/input.tmp.$$
     retval=$?

     CDRW=`cat /tmp/input.tmp.$$`
     rm /tmp/input.tmp.$$

     # Trap to allow user to abort process...
     case $retval in
     0)
     echo "CDRW=$CDRW" >> ./config
     ;;
     1)
     echo "Cancel pressed."
     exit 1
     ;;
     255)
     echo "ESC pressed."
     exit 1 
     ;;
     esac 
     ;;
  1)
    echo "CDRW=/dev/null" >> ./config
    ;;
  255)
    echo "ESC pressed."
    exit 1
    ;;
esac

echo "KERNELDIR=$CHROOTDIR/usr/src/sys/i386/conf" >> ./config
echo "COMPILEDIR=$CHROOTDIR/usr/src/sys/compile/LIVECD" >> ./config

}

# checks for config file
verifica_config() {

if [ -f ./config ] ; then
   . ./config
   dialog --title "FreeBSD LiveCD" --yesno "$v_dialogo_1" 18 70 || exit 0
   touch ./config.ok
fi

}

# Lists the packages that are actually installed at the local B0X and asks the
# user if he wants to install any of those packages.
pacotes() {

rm /tmp/opcao_media

tempfile=`/usr/bin/mktemp -t checklist`

dialog --menu "FreeBSD LiveCD - Choose your Media:" 12 60 4 \
        F "FTP" \
        C "CDROM" \
        Q "Quit / Sair" \
2> $tempfile

opcao_media=`cat $tempfile`

case ${opcao_media} in
     F)
     /usr/sbin/chroot $CHROOTDIR /stand/sysinstall mediaSetFTPPassive configPackages
     ;;
     C)
     echo "$z_dialogo_1"
     echo "$z_dialogo_2"
     read junk
     /usr/sbin/chroot $CHROOTDIR /stand/sysinstall mediaSetCDROM configPackages
     ;;
     *)
     exit 1
     ;;
esac

}

# This is the Main Dialog menu :)
main_dialog() {

# exports config file's defined variables
if [ -f ./config ] ; then
   . ./config
fi

if [ -f /tmp/opcao_Br ] ; then
   . ./lang/livecd_Br
fi

if [ -f /tmp/opcao_En ] ; then
   . ./lang/livecd_En
fi

# Defines the temporary file
tempfile=`/usr/bin/mktemp -t checklist`

# Makes main dialog menu...
  log "main_dialog()"
    dialog --menu "FreeBSD LiveCD Tool Set by FUG-BR -- (23/11/2003)" 18 70 11 \
      1 "$m_dialogo_p" \
      2 "$m_dialogo_d" \
      3 "$m_dialogo_k" \
      4 "$m_dialogo_e" \
      5 "$m_dialogo_c" \
      6 "$m_dialogo_i" \
      7 "$m_dialogo_f" \
      8 "$m_dialogo_q" \
2> $tempfile 
        
opcao=`cat $tempfile`

case ${opcao} in
     1)
     prepara_diretorios
     ;;
     2)
     distribui_binarios
     ;;
     3)
     gera_kernel
     ;;
     4)
     alterar_etc
     ;;
     5)
     pacotes
     ;;
     6)
     gera_iso 
     ;;
     7)
     grava_iso
     ;;
     8)
     rm $tempfile
     rm $LIVEDIR/config.ok
     rm /tmp/opcao_*
     exit 0
     ;;
     *) 
     exit 0
     ;;
esac
}

# Makes the Loop :) 
while true
do
if [ -f ./config.ok ] ; then
	main_dialog
else
	idioma
fi
done


syntax highlighted by Code2HTML, v. 0.9.1