#!/bin/bash
# mkdistrolib
# Generic functions to be used inside mkDistro
# By nelsongs
# Date of first release: 20060307
# Last update: 20060516

declare T1="MkDistro"
declare T2="Constroi a iso final"
declare T3="Constroi a iso base"
declare PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin
declare SOURCENET="http://www.dreamlinux.com.br/downloads"
declare SOURCESLIST="$WORKDIR/etc/apt/sources.list"
declare CURRENTDIR=$(pwd)
declare KERNEL=$(uname -r)
declare CLOOP_DEV="/lib/modules/$KERNEL/kernel/drivers/block/cloop.*o"
declare HOSTDISTRO=$(uname -n)
declare DISTRO="Dreamlinux"
declare COMP=""
declare IMG_CD="MorphixCD"
declare NAMEHOST="Morphix"
declare BASEMOD_NAME="morphix" #ou dream.mod
declare CONTROL_DIR="morphix"
declare PART_DIR="media"
export PATH T1 T2 CURRENTDIR SOURCENET SOURCESLIST CLOOP_DEV KERNEL

case "`tty`" in
/dev/tty[1-8]) 	MODE=text
		DIALOG=dialog ;;
/dev/pts/*|/dev/ttyp*) 	MODE=x
			export XDIALOG_HIGH_DIALOG_COMPAT=1
			[ -x /usr/bin/gdialog ] && DIALOG=gdialog
			[ -x /usr/bin/Xdialog ] && DIALOG=Xdialog
			[ $DIALOG = dialog ] && MODE=text ;;
*)
esac

function choice () 
{
retval=$?
case $retval in
 1) exit 0 ;;
 255) exit 0 ;;
esac
}

function progressBar ()
{
 msg="Copiando...Aguarde, por favor."
 interval=1
 percent=0
 origin="${1%/}"
 destiny="${2%/}"
 die() { echo "Error: $*"; exit 1; }
 sizeof() { du -s "$1" | cut -f1; }
 running() { ps $1 | grep $1 > /dev/null; }
 dir_destiny="$destiny/${origin##*/}"
 msg=$(eval echo $msg)
 total=$(sizeof $origin)
 cp -Rp $origin $destiny &
 cppid=$!
 trap "kill $cppid" 2 15
 (
  while running $cppid; do
   copied=$(sizeof $dir_destiny)
   percentage=$((copied*100/total))
   echo $percentage
   sleep $interval
  done
  echo 100
 ) | $DIALOG --title "$title" --gauge "$msg" 8 60 0
}

function choose_part_dir ()
{
$DIALOG --title "$T2" --yesno "\n\nSeu diretorio de montagem atual e $PART_DIR. Deseja mante-lo?" 10 75
retval=$?
choice
if [ $retval -ne 0 ]; then
  NEW_PART_DIR=$($DIALOG --stdout --wrap --title "$T1"  --radiolist "Escolha o diretorio que servira como raiz da particao." 15 75 5\
   "a"  "media" on \
   "b"  "mnt" off)
   choice
   case "$NEW_PART_DIR" in
    "a") PART_DIR="media";;
    "b") PART_DIR="mnt";;
   esac
fi 
}

function distro_tree ()
{
  distro_tree=$(find / -maxdepth 1 -mindepth 1 -type d)
}

function dir_in_tree ()
{
  tree=$(find / -maxdepth 1 -mindepth 1 -type d | grep "$1" | wc -l)
[ "$tree" = "1" ] && echo "$1 pertence a arvore" || echo "$1 nao pertence a estrutura"
}

# Use it to build an iso image file
# Parameters: 	$1=Folder to become the iso image;
#		$2=Folder to hold the iso file
#		$3=name of the iso file
# Use: iso_build $1 $2 $3

function iso_build () 
{ 
cd $1/ 
#echo "Construindo a iso final..."
if [ "$4" = "Morphix" ]; then
  rm -f md5sums.txt 2>/dev/null
  find -type f -not -name md5sums.txt -exec md5sum {} \; >> md5sums.txt
  mkisofs -pad -l -r -J -v -V "DreamLinux" -P "Projeto DreamLinux" -b boot/grub/iso9660_stage1_5 -c base/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -hide-rr-moved -o $2/$3 $1
else
  cd KNOPPIX/
  rm -f md5sums.txt 2>/dev/null
  find -type f -not -name md5sums.txt -exec md5sum {} \; >> md5sums.txt
  mkisofs -pad -l -r -J -v -V "DreamLinux" -P "Projeto DreamLinux" -b boot/grub/iso9660_stage1_5 -c boot/grub/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -hide-rr-moved -o $2/$3 $1
fi
$DIALOG --wrap --title "$T2" --msgbox "\n\nSua imagem iso final $3 esta pronta em $2." 15 75
cd $CURRENTDIR
}

# Use it to build a mod image file
# Parameters: 	$1=Folder to become the mod image;
#		$2=Complete path to the mod file
#		$3=Project's name
# Use: iso_build $1 $2 $3
function mod_build ()
{
MODULE=$(basename $2)
MOD_PATH=$(dirname $2)
[ "$#" -eq 3 ] && PROJECT=$3 || PROJECT="DreamLinux"
CLOOP_UTILS="/usr/bin/create_compressed_fs"
if [ -f "$CLOOP_UTILS" ]; then
  echo "Construindo o modulo..."
  `mkisofs -R -U -V "$PROJECT" -hide-rr-moved -cache-inodes -no-bak -pad $1/ | nice -5 create_compressed_fs - 65536 > $2`
  $DIALOG --title "$T2" --msgbox "\n\nSeu modulo $MODULE esta pronto em $MOD_PATH." 10 75
else
  $DIALOG --wrap --left --title "$T1" --msgbox "Voce nao possui o pacote cloop_utils instalado. Por favor, instale-o e refaca a operacao." 12 75 
fi 
} 

# Function check_user, used to verify the type of the user
# Use: check_user
# Se $USER = root, tryes to detect the right user, otherwise asks for one..
function check_user () 
{
if [ "$USER" = "root" ]; then
 USER=`w -h | sed -n -e '1p'| awk '{print $1}'`
 if [ "$USER" = "root" ]; then
  USER=$($DIALOG --stdout --title "$T1" --inputbox "O usuario logado eh root. Entre o nome do usuario normal:" 10 75)
  choice
  [ "$USER" = "root" ] && exit 1 || export USER
 fi
fi
}

# Function explode_iso, usada para expor o conteudo de uma imagem iso
# Uso: explode_iso $1 $2
# Parametros: $1 = o arquivo iso a ser exposto
#	      $2 = o diretorio onde a estrutura da imagem sera montada
function explode_iso ()
{
 mkdir /tmp/tempiso/
 mount -o loop $1 /tmp/tempiso/
 cp -a /tmp/tempiso/* $2/
 umount /tmp/tempiso
 rmdir /tmp/tempiso 
}

# Functiom module_type, usada para identificar o tipo de imagem
# Uso: module type $1, onde $1 contem o nome da imagem a ser verificada
function module_type ()
{
  COMP=""
  case $(dd if=$1 bs=4 count=1 2>/dev/null) in
   "#!/b") COMP="cloop" ;;
   "hsqs") COMP="squashfs" ;;
  esac
  export COMP
}

function explode_mod_cloop () 
{
  if [ -f "$CLOOP_DEV" -a -b "/dev/cloop" ]; then  #Possui suporte a cloop no kernel
    mkdir -p /tmp/temp1 2>/dev/null
    insmod $CLOOP_DEV file=$1
    mount /dev/cloop -o ro /tmp/temp1
    cp -a /tmp/temp1/* $2/
    umount /tmp/temp1
    rmmod cloop
    rmdir /tmp/temp1
  elif [ -f "/usr/bin/extract_compressed_fs" ]; then # Possui cloop_utils instalado
    mkdir -p /tmp/temp1 2>/dev/null
    extract_compressed_fs $1 > /tmp/temp1/main.iso 2>/dev/null 
    echo "Copiando.........."
    explode_iso /tmp/temp1/main.iso $2
    rm -f /tmp/temp1/main.iso
    rmdir /tmp/temp1  
  else
    echo "Voce nao possui o modulo cloop-utils instalado. Por favor, instale-o e retorne para  esta atividade"
    read -p "Pressione uma tecla para prosseguir" readkey 
  fi
}

function explode_mod_squash () 
{
  mkdir -p /tmp/temp1 2>/dev/null
  mount -t squashfs $1 /tmp/temp1 -o loop,ro
  cp -a /tmp/temp1/* $2/
  umount /tmp/temp1
  rmdir /tmp/temp1 
}

function mount_module ()
{
  COMP=""
  module_type $1
  case $COMP in
   "cloop") if [ -f "$CLOOP_DEV" -a -b "/dev/cloop" ]; then  #Possui suporte a cloop no kernel
              mkdir /tmp/cloop 2>/dev/null
	      insmod $CLOOP_DEV file=$1
	      mount /dev/cloop -o ro /tmp/cloop/
	      $DIALOG --wrap --left --title "$T1" --msgbox "Seu arquivo $1 encontra-se montado em /tmp/cloop. Realize o trabalho que tiver que realizar. Apos clicar o botao Ok." 12 75	      
	      umount /tmp/cloop/
	      rmmod cloop
	      rmdir /tmp/cloop
	    elif [ -f "/usr/bin/extract_compressed_fs" ]; then # Possui cloop_utils instalado
	      mkdir /tmp/cloop1 /tmp/cloop2 2>/dev/null
  	      extract_compressed_fs $1 > /tmp/cloop1/main.iso 2>/dev/null 
  	      mount -o loop /tmp/cloop1/main.iso /tmp/cloop2/
	      $DIALOG --wrap --left --title "$T1" --msgbox "Seu arquivo $1 encontra-se montado em /tmp/cloop2. Realize o trabalho que tiver que realizar. Apos clicar o botao Ok." 12 75
	      umount /tmp/cloop2
	      rm -f /tmp/cloop1/main.iso
	      rmdir /tmp/cloop1 /tmp/cloop2
	    else
	      $DIALOG --wrap --left --title "$T1" --msgbox "Voce nao possui os modulos cloop-module e cloop-utils instalados. Por favor, instale-os e retorne para  esta atividade." 12 75
	    fi
   ;;
   "squashfs") mkdir /tmp/squash 2>/dev/null
	       mount -t squashfs $1 /tmp/squash -o loop,ro
	       $DIALOG --wrap --left --title "$T1" --msgbox "Seu arquivo $1 encontra-se montado em /tmp/squash. Realize o trabalho que tiver que realizar. Apos clicar o botao Ok." 12 75
	       umount /tmp/squash
	       rmdir /tmp/squash
   ;;
  esac
}

function mount_iso ()
{
mkdir /tmp/tempiso
mount -o loop $1 /tmp/tempiso
$DIALOG --wrap --left --title "$T1" --msgbox "Seu arquivo $FILE encontra-se montado em /tmp/tempiso. Realize o trabalho que tiver que realizar. Apos clique o botao Ok." 12 75
umount /tmp/tempiso
rmdir /tmp/tempiso
}

function uncompress_module ()
{
 MODULO=$1
# TYPEMOD=$(echo ${MODULO##*.})
 TYPEMOD=$(echo ${MODULO#*.})
 if [ "$TYPEMOD" = "tar.gz" ]; then
   cd $2
   tar -xzf $1 ./
 elif [ "$TYPEMOD" = "tar.bz2" ]; then
   cd $2
   tar -xjf $1 ./
 else
   case $(dd if=$MODULO bs=4 count=1 2>/dev/null) in
   "#!/b") explode_mod_cloop $1 $2 ;; # comprimido em cloop
   "hsqs") explode_mod_squash $1 $2 ;; # comprimido em squashfs
   esac
 fi
}

function skel_to_root ()
{
[ -d $1/etc/skel.org ] && rm -rf $1/etc/skel.org
cp -Rp $1/etc/skel $1/etc/skel.org
rm -rf $1/root
mv $1/etc/skel $1/root
}

function root_to_skel ()
{
mv $1/root $1/etc/skel
mkdir $1/root
}

function deleteuser ()
{
if [ "$2" != "root" ]; then
    grep -v "^$2:" $1/etc/passwd > $1/tmp/passwd
    mv $1/tmp/passwd $1/etc/passwd
    grep -v "^$2:" $1/etc/group > $1/tmp/group
    mv $1/tmp/group $1/etc/group
    grep -v "^$2:" $1/etc/sudoers > $1/tmp/sudoers
    mv $1/tmp/sudoers $1/etc/sudoers
    if [ -f $1/etc/shadow ]; then 
      grep -v "^$2:" $1/etc/shadow > $1/tmp/shadow
      mv $1/tmp/shadow $1/etc/shadow
    fi
    if [ -f $1/etc/gshadow ]; then 
      grep -v "^$2:" $1/etc/gshadow > $1/tmp/gshadow
      mv $1/tmp/gshadow $1/etc/gshadow
    fi
fi
}

#Constroi o modulo principal da Distro
#Parametros:	$1 = Diretorio a ser comprimido
#		$2 = Caminho completo para o nome do arquivo a ser gerado
#		$3 = Nome do projeto, opcional
function build_module ()
{
TYPE_MOD=$($DIALOG --stdout --wrap --left --title "$T1" --cancel-label "Cancela" --radiolist "Tipo de modulo a gerar:" 12 75 2 \
  "a"   "Modulo comprimido em squashfs" on	\
  "b"   "Modulo comprimido em cloop" off) 
  case $TYPE_MOD in
   "a") mksquashfs $1 $2 ;;
   "b")	mod_build $1 $2 $3 ;;
  esac
}