#!/bin/bash
# Extract a package from either a running Porteus or a base module.
# This script is also called from the Porteus Modtools <xmodtools>
# Author: Brokenman  <brokenman@porteus.org>


TMP=/tmp/tmp$$
WRK=/tmp/wrk$$
LOG=$TMP/proc.log
TITLE="Porteus Module Tools"
VLP=var/log/packages
EXT=xzm
UNPACK=xzm2dir
PACK=dir2xzm
DIALOG=Xdialog
MPOINT=/mnt/loop
x=`ls -1 /dev/loop* | awk -F/ '{print$3}' | tr -d [:alpha:] | sort -n | tail -n1`
LOOPOINT=$(($x+1))

# Find who started this
if [ -f /tmp/.username ]; then
  user1=`cat /tmp/.username`
  user=/home/$user1
    else
  user=/`whoami`
fi

# Check that we have an X session
if [ ! $DISPLAY ]; then
  echo
  echo "You need to have the lxde or kde environment to run this!"
  echo
  exit
fi

# Check we are root
if [ $UID -ne 0 ]; then
    Xdialog --title "Root is required!" --msgbox "Sorry, only root can run that" 0 0 &
    exit
fi

# Create a progress gauge
gauge(){
p=0
while true; do
  p=`grep == $LOG | awk '{print$NF}' | sed 's/%//'`
  echo $p
  if [ "$p" == "100" ]; then
    p="100"
    echo $p
    sleep 2
    break
      else
    echo $p
  fi
done | $DIALOG --title "$TITLE" --gauge "$1" 8 70 $p
}

# Create a progress bar
progress(){

p=0
while true; do
  p=`grep % $LOG | awk '{print$NF}' | sed 's/%//'`
  echo $p
  [ "$p" == "100" ] && break
done | $DIALOG --title "$TITLE" --progress "Processing" 8 70 100 30
}

# Catch output from dialog answer
catch () {
ANSW=`cat $LOG` && rm $LOG
}

# Check which button was clicked from dialog
chkbut(){
[ $? -eq 1 ] && cleanup
}

# Clean the mess
cleanup() {
[ -d $TMP ] && rm -rf $TMP
[ -d $WRK ] && rm -rf $WRK
[ -f $LOG ] && rm -f $LOG
[ -f /tmp/.username ] && rm /tmp/.username
exit
}

# Create a new loop
make_loop() {
# Mount module on loopback
# Check for loop mount dir
if [ ! -d $MPOINT ]; then
        mkdir $MPOINT
                else
        XLS=`ls $MPOINT`
fi

if [ "$XLS" != "" ]; then
        umount $MPOINT
fi

#Create a new loop
mknod /dev/loop$LOOPOINT b 7 $LOOPOINT
}

# Error report
err() {
echo "A fatal error occured in: $FUNCNAME" > /tmp/rempkg-error.log
$DIALOG --title "$TITLE" --msgbox "An error occured and we cannot continue. \
- Show quoted text -

\n A log was created at /tmp/rempkg-error.log" 0 0
cleanup
}

# Check package for package index
check_package(){
CHK=`ls $VLP`
if [ ! -d $VLP -o -z "$VLP" ]; then
  $DIALOG --title "$TITLE" --msgbox "There doesn't appear to be a package list file. \n We cannot continue. Exiting." 0 0 &
  exit
fi
}

# Choose a package to remove
extract_package(){
nl $TMP/.list1 > $TMP/.list
$DIALOG --title "$TITLE" \
--menubox "Please choose a package to extract from module:" \
0 0 10 `cat $TMP/.list` 2> $LOG
chkbut
catch && PKGNUM=${ANSW}
PKG=`awk 'NR=='$PKGNUM'' $TMP/.list|awk '{print$NF}'`

# Get short package name
FLDS=`echo $PKG | awk -F- '{print NF}'`
if [ $FLDS -gt 3 ]; then
  PKGNAM=${PKG%-*-*}
    elif [ $FLDS -lt 4 ]; then
      PKGNAM=${PKG%-*}
fi

# Make folder on desktop
VLT=/$HOME/Desktop/package
mkdir $VLT

# extract package
for a in `sed '/FILE LIST/,$ !d' $VLP/$PKG | grep -v FILE`; do
  cp -d --parents $a $VLT > /dev/null 2>&1
done

# Copy package index file over too
cp --parents $VLP/$PKG $VLT

### Begin symlink assimilation
# Check for /var/log/script file
pushd $VLT
if [ ! -f /var/log/scripts/$PKG ]; then
  $DIALOG --title "$TITLE" \
  --wrap --left --msgbox \
  "No /var/log/scripts/$PKG was found. \nSome symlinks may not be removed/created!" 0 0
    else
  #echo '#!/bin/bash' > $WRK/syms.tmp
  grep "ln -sf" /var/log/scripts/$PKG|sed 's/( //g'|sed 's/ )//g'|awk -F"cd" '{print$NF}'|sed 's/^[ \t]*//;s/[ \t]*$//' >> $WRK/syms.tmp
  for a in `cat $WRK/syms.tmp|awk '{print$1}'`; do
  mkdir -p $VLT/$a > /dev/null 2>&1
  done
  sed -i 's|^|cd $VLT/|' $WRK/syms.tmp
  sed -i '1i\VLT=/$HOME/Desktop/package' $WRK/syms.tmp
  sed -i '1i\#!/bin/bash' $WRK/syms.tmp
  cat $WRK/syms.tmp|sed '1d' > $WRK/dirs.tmp
  chmod +x $WRK/syms.tmp
  sh $WRK/syms.tmp
fi
popd

# Remove package from menu
sed -i '/'$PKG'/d' $TMP/.list1
sed -i '/^$/d' $TMP/.list1

# Create module from desktop package folder
$PACK $VLT $user/Desktop/$PKG.$EXT > $LOG &
gauge "Making module"

# Remove desktop folder
rm -rf $VLT

# Ask if another to remove
$DIALOG --title "$TITLE" --yesno "Would you like to extract another package from this module?" 0 0

[ $? -eq 0 ] && extract_package

$DIALOG --title "$TITLE" --msgbox "All modules are now on your desktop" 0 0 &
cleanup
}

# Extract a package from a module
base_module(){
# Choose a base module
$DIALOG --title "$TITLE" \
--backtitle "Please choose a base module" \
--fselect /mnt 0 0 2> $LOG
chkbut
catch && BASEMOD=${ANSW}
BASEMODNAME=${BASEMOD%.*}

make_loop

# Mount module
mount -no loop $BASEMOD $MPOINT > /dev/null 2>&1

# Make packages menu
pushd $MPOINT > /dev/null
check_package
ls $VLP  > $TMP/.list1

# Ask for package to remove
extract_package

$DIALOG --title"$TITLE" --msgbox "All packages are now on your desktop" 0 0 &
cleanup
}

# Extract a package from a running Porteus
running_porteus() {
ls /var/log/packages  > $TMP/.list1
nl $TMP/.list1 > $TMP/.list
$DIALOG --title "$TITLE" \
--menubox "Please choose a package to extract from Porteus:" \
0 0 10 `cat $TMP/.list` 2> $LOG
chkbut
catch && PKGNUM=${ANSW}
PKG=`awk 'NR=='$PKGNUM'' $TMP/.list|awk '{print$NF}'`

# Get short package name
FLDS=`echo $PKG | awk -F- '{print NF}'`
if [ $FLDS -gt 3 ]; then
  PKGNAM=${PKG%-*-*}
    elif [ $FLDS -lt 4 ]; then
      PKGNAM=${PKG%-*}
fi

# Make folder on desktop
VLT=/$HOME/Desktop/package
mkdir $VLT

# Change to root
cd /

# Copy files from chosen package
for a in `sed '/FILE LIST/,$ !d' /var/log/packages/$PKG | grep -v FILE`; do
  cp -d --parents $a $VLT > /dev/null 2>&1
done

### Begin symlink assimilation
# Check for /var/log/script file
pushd $VLT
if [ ! -f /var/log/scripts/$PKG ]; then
  $DIALOG --title "$TITLE" \
  --wrap --left --msgbox \
  "No /var/log/scripts/$PKG was found. Some symlinks may not be created!" 0 0
    else
  LNKS="y"
  grep "ln -sf" /var/log/scripts/$PKG|sed 's/( //g'|sed 's/ )//g'|awk -F"cd" '{print$NF}'|sed 's/^[ \t]*//;s/[ \t]*$//' >> $WRK/syms.tmp
  for a in `cat $WRK/syms.tmp|awk '{print$1}'`; do
  mkdir -p $VLT/$a > /dev/null 2>&1
  done
  sed -i 's|^|cd $VLT/|' $WRK/syms.tmp
  sed -i '1i\VLT=/$HOME/Desktop/package' $WRK/syms.tmp
  sed -i '1i\#!/bin/bash' $WRK/syms.tmp
  cat $WRK/syms.tmp|sed '1d' > $WRK/dirs.tmp
  chmod +x $WRK/syms.tmp
  sh $WRK/syms.tmp
fi
popd

# Copy over package index file and scripts file
cp -d --parents /var/log/packages/$PKG $VLT
if [ $LNKS="y" ]; then
cp -d --parents /var/log/scripts/$PKG $VLT
fi

# Remove package from menu
sed -i '/'$PKG'/d' $TMP/.list1
sed -i '/^$/d' $TMP/.list1

# Create module from desktop package folder
$PACK $VLT $user/Desktop/$PKG.$EXT > $LOG &
gauge "Making module"

# Remove desktop folder
rm -rf $VLT

# Ask if another to remove
$DIALOG --title "$TITLE" --yesno "Would you like to extract another package from Porteus?" 0 0

[ $? -eq 0 ] && running_porteus

$DIALOG --title "$TITLE" --msgbox "All modules are now on your desktop" 0 0 &
cleanup
}

# Cleanup from previous runs
rm -rf /tmp/tmp* > /dev/null 2>&1
rm -rf /tmp/wrk* > /dev/null 2>&1
[ -f $LOG ] && rm -f $LOG
mkdir $TMP
mkdir $WRK

$DIALOG --title "$TITLE" \
--menubox "Please choose one of the two options below: " \
0 0 5 1 "Extract package from running Porteus" 2 "Extract package from a base module" 2> $LOG
chkbut
catch && CHOICE=${ANSW}

[ "$CHOICE" == "1" ] && running_porteus
[ "$CHOICE" == "2" ] && base_module
