#!/bin/sh
# Author: Blake, Kuo-Lien Huang
# License: GPL
# Description:
#  1. a tool to create bootable cd from DRBL root (/var/lib/diskless/default/root)
#  2. use bootcd_2.32_all.deb 

drblroot="/var/lib/diskless/default/root"
isoimage=""
user=""
logo=""
speed="12"
blankcd="no"
clean="no"
createcd="no"

# must be root
ID=`id -u`
if [ "$ID" != "0" ]; then
  echo "You must be root to use this script."
  echo "Use sudo to enable it for users."
  exit 1
fi

usage() {
  echo "Usage:"
  echo "  $0 -u username [-l logo] [--blank] [-f]"
  echo "  $0 --burncd isoimage [--blank]"
  echo
  echo "    --blank  blank CD before burn it (for CDRW)"
  echo "    -f       clean cache before create ISO image"
  echo "    -l logo  logo is a 640x450, 16 colors (24 bits RGB) PNG or PNM or LSS image"
}

# function: install_bootcd_if_necessary
install_bootcd_if_necessary() {
  has_bootcd=$(dpkg -l | grep "bootcd" | awk '{print $3;}')
  if [ "$has_bootcd" = "" ]; then
    #dpkg -i bootcd/bootcd_2.32_all.deb
    deb=`ls bootcd/bootcd*.deb`
    dpkg -i $deb
  else
    deb=`ls bootcd/bootcd*.deb`
    deb=${deb##*/}
    debver=`echo "$deb" | cut -d_ -f2`
    has_oldver=$(perl -e "if($has_bootcd < $debver) { print 'YES';}")
    if [ "$has_oldver" != "" ]; then
      #dpkg -i bootcd/bootcd_2.32_all.deb
      dpkg -i bootcd/$deb
    fi
  fi
}

# function: createcd
createcd() {

  # bootcd/display.txt
  if [ -f /etc/drbl_version ]; then
    drbl_version=`cat /etc/drbl_version | grep -e "^Version:" | awk '{ print $2; }'`
  else
    drbl_version=""
  fi
  /usr/bin/perl -p -i -e "s/VERSION/$drbl_version/g" bootcd/display.txt
  /usr/bin/perl -p -i -e "s/USER/$user/g" bootcd/display.txt

  # bootcd/logo.lss
  if [ "$logo" != "" -a -f "$logo" ]; then
    logo_name=${logo%%.*}
    logo_sub=${logo#$logo_name.}
    case "$sub" in
      "png")
        /usr/bin/pngtopnm $logo | ppmtolss16 > bootcd/$logo_name.lss
        ;;
      "pnm")
        /usr/bin/ppmtolss16 < $logo > bootcd/$logo_name.lss
        ;;
      "lss")
        cp $logo bootcd/$logo_name.lss
        ;;
      *)
        ;;
    esac
  else
    /usr/bin/pngtopnm bootcd/logo.png | ppmtolss16 \#b6b6b6=0 \#020202=7 > bootcd/logo.lss
  fi

  ## create CD isoimage
  if [ "$clean" = "yes" ]; then 
    rm -f /var/spool/bootcd/cloop/CDIMAGE
    rm -f /var/spool/bootcd/cloop/CDIMAGE_OPT
  fi
  cp bootcd/busybox-0.60.3.tar.bz2 .
  bootcd/bootcdwrite -c bootcd/
  rm -f busybox-0.60.3.tar.bz2
}

# function: burncd
# parameters: $1 - isoimage
#             $2 - blank cd before burn it (yes or no)
burncd() {
  if [ "$1" != "" -a -f "$1" ]; then
    /usr/bin/cdrecord -scanbus
    echo -n "Which one is your CDRW device [0]? "
    read device
    if [ "$device" = "" ]; then device=0; fi
    echo -n "How fast does this CDRW device burn a CD [12]? "
    read speed
    if [ "$speed" = "" ]; then speed=12; fi

    # blank cd
    if [ "$2" = "yes" ]; then
      /usr/bin/cdrecord -dev 0,$device,0 -blank=fast
    fi
    # burn cd
    /usr/bin/cdrecord -dev 0,$device,0 speed=$speed -eject -data $1
  else
    usage
  fi
}

# process command line arguments
while [ "$1" != "" ]
do
  case "$1" in
    "-u"|"--user")
      shift
      user=$1
      ;;
    "-l"|"--logo")
      shift
      logo=$1
      logo_name=${logo%%.*}
      logo_sub=${logo#$logo_name.}
      if [ "$logo_sub" != "png" -a \
           "$logo_sub" != "pnm" -a \
           "$logo_sub" != "lss" ]; then
        echo "LOGO must be PNG or PNM or LSS format. Abort!!"
        exit 0
      fi
      ;;
    "-f"|"--force")
      clean="yes"
      ;;
    "--blank")
      blankcd="yes"
      ;;
    "--burncd")
      shift
      isoimage=$1
      ;;
    "--createcd")
      createcd="yes"
	  shift
	  createcd_srcdir=$1
	  createcd_srcdir=$(echo "$createcd_srcdir" | sed 's/\//\\\//g')
	  shift
	  cdlabel=$1
      ;;
    *)
      usage
      exit 0
      ;;
  esac
  shift
done

if [ "$isoimage" != "" -a -f "$isoimage" ]; then burncd $isoimage $blankcd; exit 0; fi
if [ "$user" = "" -a "$createcd" = "no" ]; then usage; exit 0; fi
if [ "$user" != "" -a ! -d "/home/$user" -a "$createcd" = "no" ]; then usage; exit 0; fi
if [ -f /var/spool/bootcd/cdimage.iso ]; then
  rm -f /var/spool/bootcd/cdimage.iso
fi

trap 'rm -f bootcd.zip; rm -rf bootcd; rm -f busybox-0.60.3.tar.bz2; exit 1' HUP INT QUIT TERM
tail +${LINENO} $0 > bootcd.zip
unzip bootcd.zip

# install package bootcd_2.32_all 
# and remove some files from $drblroot
#install_bootcd_if_necessary
if [ "$createcd" = "yes" -a "$createcd_srcdir" != "" ]; then
  /usr/bin/perl -p -i -e "s/SRCDISK=.*/SRCDISK=$createcd_srcdir/" bootcd/bootcdwrite.conf
  user=$cdlabel
  createcd
  mv /var/spool/bootcd/cdimage.iso $cdlabel.iso
  rm -f bootcd.zip
  rm -rf bootcd
  exit 0
fi
rm -f $drblroot/usr/bin/bootcd2disk
rm -f $drblroot/usr/bin/bootcdflopcp
rm -rf $drblroot/etc/bootcd

## Blake, 2003/09/09
## for creating CD incrementally, use ln instead of cp
mkdir -p /var/spool/bootcd/cloop/DATA
mkdir $drblroot/drbl
cp bootcd/drbl-bootcd.sh $drblroot/etc/init.d/
ln -s ../init.d/drbl-bootcd.sh $drblroot/etc/rcS.d/S38drbl-bootcd.sh

# /opt/drblcd/drblcd-hdinstall
mkdir -p bootcd/opt/drblcd
cp bootcd/drblcd-hdinstall.real bootcd/opt/drblcd/
cp bootcd/drblcd-hdinstall bootcd/opt/drblcd/
# Blake, 2003/09/19, just copy drblcd-hdinstall from drblcd/
#cat <<-EOF > bootcd/opt/drblcd/drblcd-hdinstall
##!/bin/sh
#export ONLY_DEBIAN=1; sudo /opt/drblcd/drblcd-hdinstall.real
#EOF
#chmod 755 bootcd/opt/drblcd/drblcd-hdinstall
cd bootcd
tar czf /var/spool/bootcd/cloop/DATA/opt.tgz opt/
cd ..

# /etc
mkdir -p bootcd/etc/kde3/kdm
cp $drblroot/etc/kde3/kdm/kdmrc bootcd/etc/kde3/kdm
cp $drblroot/etc/hostname bootcd/etc
cp $drblroot/etc/hosts bootcd/etc
cp $drblroot/etc/passwd bootcd/etc
if [ -f $drblroot/etc/shadow ]; then cp $drblroot/etc/shadow bootcd/etc; fi
cp $drblroot/etc/sudoers bootcd/etc

passwd=$(cat /etc/passwd | grep "$user")
if [ -f /etc/shadow ]; then 
  shadow=$(cat /etc/shadow | grep "$user")
else 
  shadow=""
fi

echo $passwd >> bootcd/etc/passwd
if [ "$shadow" != "" -a -f bootcd/etc/shadow ]; then
  echo $shadow >> bootcd/etc/shadow
fi

echo "$user	ALL=(ALL)	ALL" >> bootcd/etc/sudoers

/usr/bin/perl -p -i -e "s/AutoLoginEnable=.*/AutoLoginEnable=true/g" bootcd/etc/kde3/kdm/kdmrc
/usr/bin/perl -p -i -e "s/AutoLoginUser=.*/AutoLoginUser=$user/g" bootcd/etc/kde3/kdm/kdmrc

echo "$user""'s_cd" > bootcd/etc/hostname
cat <<-EOF > bootcd/etc/hosts
127.0.0.1	$user's_cd	localhost

# The following lines are desirable for IPv6 capable hosts
# (added automatically by netbase upgrade)

::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
EOF

cd bootcd/
tar czf /var/spool/bootcd/cloop/DATA/etc.tgz etc/
cd ..

# /home/$user
if [ "$user" != "" -a -d /home/$user ]; then
  tar --exclude=tmp-$(hostname) --exclude=socket-$(hostname) -czf \
    /var/spool/bootcd/cloop/DATA/home.tgz /home/$user
fi

# calculate tmpfs size for home/$user etc opt
home_size=$(du -sb /home/$user | cut -f1)
etc_size=$(du -sb bootcd/etc | cut -f1)
opt_size=$(du -sb bootcd/opt | cut -f1)
tmpfs_size=`expr $home_size + $etc_size + $opt_size`
tmpfs_size=`expr $tmpfs_size \* 3 / 2`
# 8388608 = 8192 * 1024
if [ $tmpfs_size -lt 8388608 ]; then tmpfs_size=8388608; fi
/usr/bin/perl -p -i -e "s/{TMPFS_SIZE}/$tmpfs_size/g" $drblroot/etc/init.d/drbl-bootcd.sh
#echo "home_size=$home_size, etc_size=$etc_size, opt_size=$opt_size"
#echo "tmpfs_size=$tmpfs_size"
#read pause

## networking and init
mv $drblroot/etc/init.d/networking bootcd/networking.bak
cp bootcd/networking $drblroot/etc/init.d/
cp $drblroot/sbin/init bootcd/init
cp $drblroot/sbin/init.orig $drblroot/sbin/init

## backup and link
mv $drblroot/etc/kde3/kdm/kdmrc bootcd/
mv $drblroot/etc/hostname bootcd/
mv $drblroot/etc/hosts bootcd/
mv $drblroot/etc/passwd bootcd/
if [ -f $drblroot/etc/shadow ]; then mv $drblroot/etc/shadow bootcd/; fi
mv $drblroot/etc/sudoers bootcd/
ln -sf /drbl/etc/kde3/kdm/kdmrc $drblroot/etc/kde3/kdm/kdmrc
ln -sf /drbl/etc/hostname $drblroot/etc/hostname
ln -sf /drbl/etc/hosts $drblroot/etc/hosts
ln -sf /drbl/etc/passwd $drblroot/etc/passwd
if [ -f bootcd/shadow ]; then ln -s /drbl/etc/shadow $drblroot/etc/shadow; fi
#ln -sf /drbl/etc/sudoers $drblroot/etc/sudoers

ln -sf /drbl/opt/drblcd /opt/drblcd

## restore 
cat <<-EOF > restore.sh
rm -f $drblroot/etc/kde3/kdm/kdmrc
rm -f $drblroot/etc/hostname
rm -f $drblroot/etc/hosts
rm -f $drblroot/etc/passwd
rm -f $drblroot/etc/shadow
#rm -f $drblroot/etc/sudoers
mv bootcd/kdmrc $drblroot/etc/kde3/kdm/
mv bootcd/hostname $drblroot/etc/
mv bootcd/hosts $drblroot/etc/
mv bootcd/passwd $drblroot/etc/
if [ -f bootcd/shadow ]; then mv bootcd/shadow $drblroot/etc/; fi
mv bootcd/sudoers $drblroot/etc/
## Blake, 2003/09/09, use ln instead of cp
#rm -rf $drblroot/home/$user
#rm -rf /opt/drblcd
rm -f $drblroot/etc/init.d/drbl-bootcd.sh
rm -f $drblroot/etc/rcS.d/S38drbl-bootcd.sh
rmdir $drblroot/drbl
rm -f /opt/drblcd
rm -rf /var/spool/bootcd/cloop/DATA

# networking and init
cp bootcd/networking.bak $drblroot/etc/init.d/networking
cp bootcd/init $drblroot/sbin/

rm -f bootcd.zip
rm -rf bootcd
EOF
chmod 755 restore.sh
trap './restore.sh; rm -f restore.sh; exit 1' HUP INT QUIT TERM 

## copy data in the user's home directory 
## setup user's information (passwd, shadow, kdmrc)
#if [ -d /home/$user ]; then
#  # backup the files which will be changed later..
#  cp $drblroot/etc/kde3/kdm/kdmrc bootcd/
#  cp $drblroot/etc/hostname bootcd/
#  cp $drblroot/etc/passwd bootcd/
#  if [ -f $drblroot/etc/shadow ]; then 
#    cp $drblroot/etc/shadow bootcd/
#  fi
#
#  # home directory
#  cp -a /home/$user $drblroot/home
#  rm -rf $drblroot/home/$user/.kde/socket-$(hostname)
#  rm -rf $drblroot/home/$user/.kde/tmp-$(hostname)
#  
#  # passwd, shadow
#  passwd=$(cat /etc/passwd | grep "$user")
#  if [ -f /etc/shadow ]; then 
#    shadow=$(cat /etc/shadow | grep "$user")
#  else 
#    shadow=""
#  fi
#  echo $passwd >> $drblroot/etc/passwd
#  if [ "$shadow" != "" -a -f $drblroot/etc/shadow ]; then
#    echo $shadow >> $drblroot/etc/shadow
#  fi
#  # kdmrc
#  /usr/bin/perl -p -i -e "s/AutoLoginEnable=.*/AutoLoginEnable=true/g" $drblroot/etc/kde3/kdm/kdmrc
#  /usr/bin/perl -p -i -e "s/AutoLoginUser=.*/AutoLoginUser=$user/g" $drblroot/etc/kde3/kdm/kdmrc
#  # hostname
#  echo "$user""'s_cd" > $drblroot/etc/hostname
#fi

## create CD isoimage from $drblroot and /opt
createcd

./restore.sh
rm -f restore.sh
## Blake, 2003/09/22
## put the following housekeeping code to restore.sh
## housekeeping
#rm -f $drblroot/etc/kde3/kdm/kdmrc
#rm -f $drblroot/etc/hostname
#rm -f $drblroot/etc/hosts
#rm -f $drblroot/etc/passwd
#rm -f $drblroot/etc/shadow
#rm -f $drblroot/etc/sudoers
#mv bootcd/kdmrc $drblroot/etc/kde3/kdm/
#mv bootcd/hostname $drblroot/etc/
#mv bootcd/hosts $drblroot/etc/
#mv bootcd/passwd $drblroot/etc/
#if [ -f bootcd/shadow ]; then mv bootcd/shadow $drblroot/etc/; fi
#mv bootcd/sudoers $drblroot/etc/
## Blake, 2003/09/09, use ln instead of cp
#rm -rf $drblroot/home/$user
#rm -rf /opt/drblcd
#rm -f $drblroot/etc/init.d/drbl-bootcd.sh
#rm -f $drblroot/etc/rcS.d/S38drbl-bootcd.sh
#rmdir $drblroot/drbl
#rm -f /opt/drblcd
#rm -rf /var/spool/bootcd/cloop/DATA

# networking and init
#cp bootcd/networking.bak $drblroot/etc/init.d/networking
#cp bootcd/init $drblroot/sbin/

#rm -f bootcd.zip
#rm -rf bootcd

# make cd
mv /var/spool/bootcd/cdimage.iso $user.iso
if [ -f $user.iso ]; then
  echo "The CD ISO image '$user.iso' is created!!"
  echo -n "Do you want to burn the CD [Y|n]? "
  read ANS
  if [ "$ANS" = "Y" -o "$ANS" = "y" -o "$ANS" = "" ]; then
    burncd $user.iso $blankcd
  fi
fi
exit 0
