#!/bin/sh
# PLD RescueCD modifier 0.2
# (c) areq@pld-linux.org

ISOSIZE=93325312
VERSION=PLDRESCUECDx86_11_02
VER=11.02 

TRAILER1="07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!"
TRAILER2="\0\0\0\0"

usage ()
{
echo Usage:
echo rcdmod -i isofile [-o isofile.out] [-f custom_files] [-d unpack_dir] [-tail\|-dd]
echo rcdmod -r rescue.cpi [-o rescue.cpi.out] [-f custom_files]
echo 
echo "Example:"
echo "  rcdmod -i rescue.iso -f pld000.tar.bz2,pld100.tar.bz2 -o rescue_new.iso"
echo "   Add pld000.tar.bz2 pld100.tar.bz2 to rescue.iso and save as rescue_new.iso."
echo 
echo "  rcdmod -i rescue.iso -d katalog"
echo "   Save all files from rescue.iso to direcory katalog."
echo
echo "  rcdmod -i rescue.iso -d katalog -dd"
echo "   Save all files from rescue.iso to direcory katalog use dd - slow."
echo
echo "  rcdmod -d katalog -o rescue_new.iso"
echo "   Create rescue_new.iso from directory katalog."
echo
echo "  rcdmod -r rescue.cpi -o rescue.cpi.new"
echo "   Create new rescue.cpi.new with."
echo
exit 1
}

un_tail ()
{
 tail -c $(($ISOSIZE-$2)) $ISO | head -c $3 > $1
}
un_dd ()
{
 dd if=$ISO of=$1 skip=$2 count=$3 bs=1 2> /dev/null
}

unpack ()
{
 mkdir -p $(dirname $1)
 un_$METHOD $*
 echo "$4  $1" | md5sum -c
}
mkiso ()
{
LOG=`mktemp /tmp/rcdmod.$$.XXXXXX` || exit 1
echo Save log to $LOG.

mkisofs -v -J -R -D -A "$VERSION" -m "CVS" -m ".cvsignore" -V "$VERSION" -no-emul-boot -boot-info-table \
-boot-load-size 4 -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.catalog \
-publisher "Arkadiusz Patyk <areq@pld-linux.org>" \
-A "PLD Linux RescueCD $VER" \
-p "http://rescuecd.pld-linux.org/" \
-log-file $LOG  -o "$2" $1

echo Saved $2.
}

unpack_all ()
{
while read file start len md5; 
do 
 unpack $DIR/$file $start $len $md5
done << __EOT__
custom/custom.cpi          89614336     1024 84f57c200cf3065e722619298735ec87
rescue.cpi                   106496 89506816 821419ddff34f432f9af4385563f855e
boot/README                89645056      819 f7ffe1669c42088bb25d9f11bcd6c06c
boot/floppy.img.gz         89636864     1475 0de1d2855264fda93edc1b2a7a175c5c
boot/sgd09590.gz           89647104   352768 dbaa071a1e75af3f54160a296e5db50c
boot/ElTorito.img.gz       89618432    17131 f49c4f2db855d2d482d399caacd2d3c3
boot/isolinux/isolinux.cfg 90636288     1685 9a6289dd5b3b083a54336bb1662e5dc3
boot/isolinux/boot.msg.bot 90005504     1673 dcf1f6083c5cb25c74ebbfbc9db25473
boot/isolinux/boot.msg.x86 90007552     1623 d259be81706a0a90a6908d73262136b7
boot/isolinux/memtest      90664960   164504 72789a40fa4737d6c4b8f81e56bbb450
boot/isolinux/memdisk      90638336    25244 f8d50a310eb00dcc3550e56443200b0b
boot/isolinux/isolinux.cfg 90632192     1685 3432cf77852ee3b7f8e9cc1aa92d508a
boot/isolinux/isolinux.cfg 90632192     1685 3432cf77852ee3b7f8e9cc1aa92d508a
boot/isolinux/vmlinuz      90830848  2187264 2cd6e87d0184c9b5deff968995a06991
boot/isolinux/grub.exe     90009600   253449 b138ddd4c9eb131b5ad2345acdf9eeb3
boot/isolinux/boot.msg     90001408     1623 c8570487c7cee95466f523fb6f5f05e4
boot/isolinux/help.msg     90263552     1443 5fde76b5ba78e4a6e94dcb71ad037867
boot/isolinux/initrd.ide   90265600   365231 4fa55c597e9973de8a9eb5d7bfaea978
boot/isolinux/isolinux.bin    81920    24576 eb6c4cb4e2d203c88a75c17d43d18400
boot/isolinux/boot.msg.x86 90003456     1586 4738091becf2a7eb61cfe5d2d9c2b1d4
boot/boot.bat              89616384       83 5a6fc33959be2620bb28c189c916123d
__EOT__
}

panic ()
{
    echo -e "PANIC! $1! quitting.\n"
    exit 1
}

cpio_mod ()
{
 [ "$(head -c 6 "$CPIO")" = "070701" ] || panic "Unexpected file format $CPIO "
 sed "/$TRAILER1.*/d" $CPIO > $OUT
 echo -n "$TRAILER1$TRAILER2" >> $OUT	 
 
 if [ -f $DIR/custom/custom.cpi ]; then
   cat $DIR/custom/custom.cpi >> $OUT
 fi
 echo "$OUT created."
}

echo PLD RescueCD modifier 0.2
echo

[ $# -eq 0 ] && usage

METHOD=tail
RMOUT=0
while [ $# -ge 1 ]; do
  case $1 in
    -i)     shift;  ISO=$1 ;;
    -r)     shift;  CPIO=$1 ;;
    -o)     shift;  OUT=$1 ;;
    -d)     shift;  DIR=$1 ;;
    -f)     shift;  FILE=$1 ;;
    -dd)    METHOD=dd;;
    -tail)  METHOD=tail ;;
    *)     usage ;;
  esac
  shift
done

if [ "$DIR" = "" ] 
then
 DIR=`mktemp -d /tmp/$$.XXXXXX` || exit 1
 RMOUT=1
fi

if [ "$FILE" != "" ] 
then
 FILE=`echo $FILE | tr ',' ' '`
 for F in $FILE
 do
   echo Checking $F...
   [ -f "$F" ] || exit 1
   [ "$(head -c 3 "$F")" = "BZh" ] || exit 1
   bzip2 -dc "$F" | tar tf - | sed 's/\.\///' |\
 	grep -v -q -E "^$|^etc|^tmp|^var|^root|^home|^opt|^srv"
   [ $? == 0 ] && panic "PANIC! $F contains invalid paths! quitting.\n"
   echo OK
 done
fi

if [ -n "$ISO" ]
then
  if ! [ -f "$ISO" ] 
  then
    echo File $ISO not found!
  exit 1
  fi
  if ! [ $(stat -c %s $ISO) -eq $ISOSIZE ]
  then
    echo Bad iso file $ISO!
  exit 1
  fi
  unpack_all
fi

if [ -n "$FILE" ] ; then
  TT=`mktemp -d /tmp/$$.XXXXXX` || exit 1
  DIR=$(cd $DIR;pwd)
  mkdir -p $DIR/custom
  C=`pwd`
  cp $FILE $TT/
  cd $TT
  ls | cpio  -H newc -o > $DIR/custom/custom.cpi
  echo Add $FILE.
  cd $C
  rm -fr $TT
fi

[ -n "$OUT" -a -z "$CPIO" ] && mkiso $DIR $OUT
[ -n "$OUT" -a -n "$CPIO" ] && cpio_mod

[ $RMOUT -eq 1 ] && rm -fr $DIR

exit 0
