#!/ventoy/busybox/sh
#************************************************************************************
# Copyright (c) 2020, longpanda <admin@ventoy.net>
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
# 
#************************************************************************************


####################################################################
#                                                                  #
# Step 1 : extract real initramfs to /                             #
#                                                                  #
####################################################################
cd /
rm -rf /init /linuxrc /dev/  /root

vtSbinFileNum=$(ls -1 /sbin | wc -l)
if [ $vtSbinFileNum -eq 1 ]; then
    echo "remove whole sbin directory" >> $VTLOG
    rm -rf /sbin
else
    echo "remove only sbin/init file" >> $VTLOG
    ls -l /sbin >> $VTLOG
    rm -f /sbin/init
fi

ventoy_is_initrd_ramdisk() {
    #As I known, PCLinuxOS/smgl use ramdisk
    if echo $vtkerver | grep -i -q 'PCLinuxOS'; then
        true
    elif echo $vtkerver | grep -i -q 'SMGL-'; then
        true
    else
        false
    fi
}

ventoy_mount_squashfs() {
    mkdir /dev
    mount -t devtmpfs devtmpfs /dev    
    dd if=$1 of=/dev/ram0 status=none
    umount /dev && rm -rf /dev
}

# param: file skip magic tmp
ventoy_unpack_initramfs() {        
    vtfile=$1; vtskip=$2; vtmagic=$3; vttmp=$4    
    echo "=====ventoy_unpack_initramfs: #$*#" >> $VTLOG
    
    #special process
    #if [ "${vtmagic:0:4}" = '5678' ]; then
    #    echo -en '\x1F\x8B' | dd status=none of=$vtfile bs=1 count=2 conv=notrunc
    #    vtmagic='1F8B'
    #fi
    
    if [ "${vtmagic:0:4}" = '6873' ]; then
        ventoy_mount_squashfs $vtfile
        return
    fi
    
    for vtx in '1F8B zcat' '1F9E zcat' '425A bzcat' '5D00 lzcat' 'FD37 xzcat' '894C lzopcat' '0221 lz4cat' '28B5 zstdcat' '3037 cat' '4C5A lunzip -c'; do
        if [ "${vtx:0:4}" = "${vtmagic:0:4}" ]; then
            echo "vtx=$vtx" >> $VTLOG            
            if [ $vtskip -eq 0 ]; then            
                if [ "${vtx:5}" = "xzcat" ]; then
                    rm -f $VTOY_PATH/xzlog
                    ${vtx:5} $vtfile 2> $VTOY_PATH/xzlog | (cpio -idmu 2>>$VTLOG; cat > $vttmp)
                    if grep -q 'corrupted data' $VTOY_PATH/xzlog; then
                        echo 'xzcat failed, now try xzminidec...' >> $VTLOG                        
                        rm -f $VTOY_PATH/xzlog
                        cat $vtfile | xzminidec 2> $VTOY_PATH/xzlog | (cpio -idmu 2>>$VTLOG; cat > $vttmp)

                        if grep -q 'limit' $VTOY_PATH/xzlog; then                    
                            echo 'xzminidec failed, now try xzcat_musl ...' >> $VTLOG  
                            xzcat_musl $vtfile | (cpio -idmu 2>>$VTLOG; cat > $vttmp)
                        fi
                    fi
                else
                    ${vtx:5} $vtfile | (cpio -idmu 2>>$VTLOG; cat > $vttmp)
                fi
            else
                dd if=$vtfile skip=$vtskip iflag=skip_bytes status=none | ${vtx:5} | (cpio -idmu 2>>$VTLOG; cat > $vttmp)
            fi
            break
        fi
    done
}

# param: file magic tmp
ventoy_unpack_initrd() {        
    vtfile=$1; vtmagic=$2; vttmp=$3    
    echo "=====ventoy_unpack_initrd: #$*#" >> $VTLOG
    
    for vtx in '1F8B zcat' '1F9E zcat' '425A bzcat' '5D00 lzcat' 'FD37 xzcat' '894C lzopcat' '0221 lz4cat' '28B5 zstdcat' '3037 cat'; do
        if [ "${vtx:0:4}" = "${vtmagic:0:4}" ]; then
            echo "vtx=$vtx" >> $VTLOG            
            ${vtx:5} $vtfile > $vttmp
            break
        fi
    done    
}

vtfile_head_zero() {
    local vsize
    local voffset
    local vfile
    local vzero
    local vdump
    
    voffset=0
    vfile=$1
    vsize=$(stat -c '%s' ${vfile})
    vzero=$(hexdump -n 512 -e '512/1 "%02X"' $vfile)
    
    while [ $voffset -lt $vsize ]; do
        vdump=$(hexdump -s $voffset -n 512 -e '512/1 "%02X"' $vfile)
        if [ "$vdump" != "$vzero" ]; then
            echo $voffset
            return
        fi
        voffset=$($BUSYBOX_PATH/expr $voffset + 512)
    done    
    echo 0
}

# This export is for busybox cpio command
export EXTRACT_UNSAFE_SYMLINKS=1

for vtfile in $(ls /initrd*); do    
    #decompress first initrd
    vtmagic=$(hexdump -n 2 -e '2/1 "%02X"' $vtfile)

    if ventoy_is_initrd_ramdisk; then
        ventoy_unpack_initrd $vtfile $vtmagic ${vtfile}_tmp
        mv ${vtfile}_tmp $vtfile
        break
    else
        ventoy_unpack_initramfs $vtfile 0 $vtmagic ${vtfile}_tmp
    fi

    #only for cpio,cpio,...,initrd sequence, initrd,cpio or initrd,initrd sequence is not supported
    while [ -e ${vtfile}_tmp ] && [ $(stat -c '%s' ${vtfile}_tmp) -gt 512 ]; do
        mv ${vtfile}_tmp $vtfile
        
        vtdump=$(hexdump -n 512 -e '512/1 "%02X"' $vtfile)
        vtmagic=$(echo $vtdump | sed 's/^\(00\)*//')
        let vtoffset="(${#vtdump}-${#vtmagic})/2"
        
        if [ -z "$vtmagic" ]; then
            vtHeadZero=$(vtfile_head_zero $vtfile)
            if [ $vtHeadZero -gt 0 ]; then
                vtdump=$(hexdump -s $vtHeadZero -n 512 -e '512/1 "%02X"' $vtfile)
                vtmagic=$(echo $vtdump | sed 's/^\(00\)*//')
                let vtoffset="(${#vtdump}-${#vtmagic})/2+$vtHeadZero"                
                echo "skip head $vtHeadZero zeros with magic ${vtmagic:0:4}" >> $VTLOG
            else
                echo "terminate with all zero data file" >> $VTLOG            
                break
            fi            
        fi
        
        ventoy_unpack_initramfs $vtfile $vtoffset ${vtmagic:0:4} ${vtfile}_tmp
    done
    
    rm -f $vtfile ${vtfile}_tmp
done


#break here for debug
if [ "$VTOY_BREAK_LEVEL" = "02" ] || [ "$VTOY_BREAK_LEVEL" = "12" ]; then
    sleep 5    
    echo -e "\n\n\033[32m ################################################# \033[0m"
    echo -e "\033[32m ################ VENTOY DEBUG ################### \033[0m"
    echo -e "\033[32m ################################################# \033[0m \n"   
    if [ "$VTOY_BREAK_LEVEL" = "12" ]; then 
        cat $VTOY_PATH/log
    fi    
    exec $BUSYBOX_PATH/sh
fi


####################################################################
#                                                                  #
# Step 3 : Extract injection archive                               #
#                                                                  #
####################################################################
ventoy_unpack_injection() {
    vtmagic=$(hexdump -n 2 -e '2/1 "%02X"' $VTOY_PATH/ventoy_injection)
    echo "ventoy_unpack_injection  vtmagic=$vtmagic ..."
    
    if [ "1F8B" = "$vtmagic" ] || [ "1F9E" = "$vtmagic" ]; then
        echo "tar.gz  tar -xzvf"
        tar -xzvf $VTOY_PATH/ventoy_injection -C /
    elif [ "425A" = "$vtmagic" ]; then
        echo "tar.bz2  tar -xjvf"
        tar -xjvf $VTOY_PATH/ventoy_injection -C / 
    elif [ "FD37" = "$vtmagic" ]; then
        echo "tar.xz  tar -xJvf"
        tar -xJvf $VTOY_PATH/ventoy_injection -C /
    elif [ "5D00" = "$vtmagic" ]; then
        echo "tar.lzma  tar -xavf"
        tar -xavf $VTOY_PATH/ventoy_injection -C /
    else
        echo "unzip -o"
        unzip -o $VTOY_PATH/ventoy_injection -d /
    fi
}

if [ -e $VTOY_PATH/ventoy_injection ]; then
    echo "### decompress injection ... ###" >>$VTLOG
    ventoy_unpack_injection > $VTOY_PATH/injection.log 2>&1    
fi


####################################################################
#                                                                  #
# Step 4 : Hand over to ventoy_chain.sh                                  #
#                                                                  #
####################################################################
echo "Now hand over to ventoy.sh" >>$VTLOG
. $VTOY_PATH/tool/vtoytool_install.sh

export PATH=$VTOY_ORG_PATH
exec $BUSYBOX_PATH/sh $VTOY_PATH/ventoy_chain.sh
