#!/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.

# the path to the ncurses dialog program...
DIALOG=${DIALOG=/usr/bin/dialog}

# Function to define the users` choice language
idioma() {

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

dialog --menu "FreeBSD LiveCD - Select 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/install_Br ] ; then
     . ./lang/install_Br
     else
     echo "Idioma selecionado nao disponivel"
     exit 1
     fi
     ;;
     En)
     if [ -f ./lang/install_En ] ; then
     . ./lang/install_En
     else
     echo "Sorry, no such Language file"
     exit 1
     fi
     ;;
     *)
     exit 1
     ;;
esac

}

# Shows dialog menu to allow users to choose the Hard Disk 
disco() {
dis="`dmesg | grep MB`"
disc="`echo $dis | awk -F":" '{print $1}'`"
desc="`echo $dis | awk -F":" '{print $2}'`"
tamanho="`echo $dis | awk '{print $2}' | awk -F"MB" '{print $1}'`"
$DIALOG --title "Escolha do device" --clear --checklist "$i_disco_1" 10 80 1 "$disc" "$desc" off 2> /tmp/input.tmp.$$
retval=$?

# Users` choice will be keept into $disco variable
disco=`cat /tmp/input.tmp.$$ | awk -F"\"" '{print $2}'`
rm /tmp/input.tmp.$$

# Trap to allow users to abort the process
case $retval in
  0)
    raiz;;
  1)
    echo "Cancel pressed.";;
  255)
    echo "ESC pressed.";;

esac

}

# Shows dialog menu asking for users` input about the size (in MB) for the root partition - /
raiz() {

$DIALOG --title "FreeBSD LiveCD" --clear --inputbox "$i_raiz_1" 10 80 "" 2> /tmp/input.tmp.$$
retval=$?

# keep users` input in the $raiz variable
raiz=`cat /tmp/input.tmp.$$`
rm /tmp/input.tmp.$$

# Let's see how much space it is still avaiable.
tamanho=`expr $tamanho - $raiz`

# Trap to allow users to abort the process
case $retval in
  0)
    swap;;
  1)
    echo "Cancel pressed.";;
  255)
    echo "ESC pressed.";;
esac

}

# Shows dialog menu asking for users` input about the size (in MB) for the Swap partition
swap() {

$DIALOG --title "FreeBSD LiveCD" --clear --inputbox "$i_swap_1" 10 80 "" 2> /tmp/input.tmp.$$
retval=$?

# keep users` input into the $swap variable
swap=`cat /tmp/input.tmp.$$`
rm /tmp/input.tmp.$$

# Lets see how much space (MB) it is still avaiable
tamanho=`expr $tamanho - $swap`

# Trap to allow one to abort the process
case $retval in
  0)
    var;;
  1)
    echo "Cancel pressed.";;
  255)
    echo "ESC pressed.";;
esac

}

# Shows dialog menu asking for users` input about the size (in MB) for the var partition - /var
var() {

$DIALOG --title "FreeBSD LiveCD" --clear --inputbox "$i_var_1" 10 80 "" 2> /tmp/input.tmp.$$
retval=$?

# keep users` input into the $var variable
var=`cat /tmp/input.tmp.$$`
rm /tmp/input.tmp.$$

# Lets figure out how much space it is still avaible.
tamanho=`expr $tamanho - $var`

# Trap to allow users to abort the process
case $retval in
  0)
    usr;;
  1)
    echo "Cancel pressed.";;
  255)
    echo "ESC pressed.";;
esac
 
}

# From now on, it is not possible to abort the process anymore!!!
# Shows a dialog menu telling the user that the remaining space will be
# used to the usr partition - /usr

usr() {

$DIALOG --title " Atencao " --clear --msgbox "i_usr_1" -1 -1

# The size for the /usr partition (MB)
usr=$tamanho

# Trap to allow users` to abort the process.
# Last chance to abort...
case $? in
  0)
    confirma;;
  255)
    echo "ESC pressed.";;
esac

}

# Confirm
confirma() {

# Lets show a Final Alert...
dialog --title "FreeBSD LiveCD" --yesno "i_confirma_1" 8 70 || exit 1

# the "get ready" function ;-)
prepara

}

# Function that allows instalation to get ready...
prepara() {

# Delete disks partition...
/bin/dd if=/dev/zero of=/dev/$disco count=128
sleep 5

# Tells fdisk to use the whole disk space
/sbin/fdisk -I $disco
sleep 5

# Disklabel stuff to initialize the disk
/sbin/disklabel -rw ${disco}s1 auto
sleep 5

# Define disk partitions.
modelo=/tmp/label.modelo
/sbin/disklabel -r ${disco}s1 > $modelo

# Figure out how much blocks it is still avaiable
setores_disco=`/sbin/disklabel -r ${disco}s1 | /usr/bin/tr -s ' ' | \
          /usr/bin/sed 's/^ //g' | /usr/bin/grep '^c: ' | \
          /usr/bin/cut -f2 -d' '`

# Defines the block number for every slice
b_raiz=`expr $raiz \* 1024 \* 2`
b_swap=`expr $swap \* 1024 \* 2`
b_var=`expr $var \* 1024 \* 2`
b_usr=`expr $setores_disco \- $b_raiz \- $b_swap \- $b_var`

# Defines offset to /var and /usr slices
off_var=`expr $b_raiz \+ $b_swap`
off_usr=`expr $b_raiz \+ $b_swap \+ $b_var`

# The base model to be used by disklabel
echo "a: $b_raiz 0 4.2BSD 0 0 0" >>  $modelo
echo "b: $b_swap $b_raiz swap" >>  $modelo 
echo "e: $b_var $off_var 4.2BSD 0 0 0"  >>  $modelo  
echo "g: $b_usr $off_usr 4.2BSD 0 0 0"  >>  $modelo 

# Create disks partitions and sets it as "bootavel"
/sbin/disklabel -R -B ${disco}s1 $modelo
sleep 5

# Filesystem for /
/sbin/newfs /dev/${disco}s1a
sleep 5

# Filesystem for /var
/sbin/newfs /dev/${disco}s1e
sleep 5

# Filesystem for /usr
/sbin/newfs /dev/${disco}s1g

# Make devices if it does not exists yet.
if [ ! -c /dev/${disco} ]; then
  (cd /dev && MAKEDEV ${disco})
fi

if [ ! -c /dev/${disco}s1 ]; then
  (cd /dev && MAKEDEV ${disco}s1)
fi

if [ ! -c /dev/${disco}s1a ]; then
  (cd /dev && MAKEDEV ${disco}s1a)
fi

if [ ! -c /dev/${disco}s1b ]; then
  (cd /dev && MAKEDEV ${disco}s1b)
fi

if [ ! -c /dev/${disco}s1e ]; then
  (cd /dev && MAKEDEV ${disco}s1e)
fi

if [ ! -c /dev/${disco}s1g ]; then
  (cd /dev && MAKEDEV ${disco}s1g)
fi

# disk mount 
/sbin/mount /dev/${disco}s1a /mnt
sleep 5
mkdir /mnt/usr

/sbin/mount /dev/${disco}s1g /mnt/usr
sleep 5
mkdir /mnt/var

/sbin/mount /dev/${disco}s1e /mnt/var
sleep 5

# turns swap on
swapon /dev/${disco}s1b

# Copies LiveCD files to Hard Disk.
cd /mnt
for i in bin boot bootstrap dev etc home modules root sbin stand tmp var
do
  cp -Rvp /$i .
  sleep 5
done

cp /.cshrc /mnt
sleep 2
cp /.profile /mnt
sleep 2
cp /COPYRIGHT /mnt
sleep 2
cp /dist/fstab.install /mnt/etc/fstab
sleep 2
cp /dist/rc /mnt/etc/rc
sleep 2

cd /mnt/usr
for i in bin games include lib libdata libexec local obj sbin share src
do
  cp -Rvp /usr/$i .
  sleep 5
done

# Remake all devices
cd /mnt/dev
./MAKEDEV all

# Copies LiveCD`s kernel to /
cp /dist/kernel /mnt/kernel
cp /dist/kernel /mnt/kernel.GENERIC

# Set remaining permissions to the files that were just created, and make the necessary directories
mtree -deU -f /dist/LiveCD.mtree -p /mnt > /dev/null &&

# The partition to be used for as / mount point
echo rootdev="${disco}s1a" >> /mnt/boot/loader.conf

cd /

sleep 30

# umount actual disk definitions
/sbin/umount /mnt/usr
/sbin/umount /mnt/var
/sbin/umount /mnt

touch /tmp/install_ok

}

# Info Function
aviso() {

if [ -f /tmp/install_ok ] ; then
# Tells the user the the process was finished
dialog --title "FreeBSD LiveCD" --msgbox "$i_informa_1" 8 70
fi

}

# Caution!!!!
#
# LiveCD`s batch mode instalation does NOT requires user confirmation, take care.
#
# To use the batch mode, you just need to run the script with 4 inputs:
# instalar_freebsd.sh harddisk root swap var (ie:
# instalar_freebsd.sh ad0 200 256 2000, will install freebsd seting 200MB for
# the / partiton, 256MB for swap, 2GB for /var and the remaining disk free space
# to the /usr partitioin
# 
# If the script is ran without the 4 necessary user input parameters, it starts
# the Interative Mode asking for inputs one by one

# Portuguese Caution message just like the above one.
#
# Atencao!!!!
# 
# A execucao em modo batch NAO pede confirmacao, use com cuidado!!!
#
# Para usar em modo batch batch , basta executar o comando com 4 parametros:
# instalar_frebsd.sh disco raiz swap var, por ex: 
# instalar_freebsd.sh ad0 200 256 2000, instala o freebsd criando 
# - / com 200MB
# - swap com 2256MB
# - /var com 2GB
# - /usr com o restante do disco
# Se executar com menos de 4 parametros entra em modo interativo.

if [ "$#" -lt 4 ] ; then
   idioma
   disco 
   aviso
elif then
   disco=$1
   raiz=$2
   swap=$3
   var=$4 
   prepara
fi
