#!/bin/sh
# This script collects all relevant binaries (executable + shared libraries) as determined
# from the given core file.
# Usage: ./appoptics-php-packcore.sh <COREFILE>

if [ -z "$1" ]; then
    echo "Please provide the path to the core file."
    exit 1
fi
if [ ! -f "$1" ]; then
    echo "Core file $1 not found."
    exit 1
fi
if [ -z "$(file $1 | grep "core file")" ]; then
    echo "File $1 does not appear to be a core file."
    exit 1
fi

CORE=$1

if [ -z "$(which strings 2>/dev/null)" ]; then
    echo "Could not find 'strings' command, please install package binutils."
    exit 1
fi
if [ -z "$(which xz 2>/dev/null)" ]; then
    echo "Could not find 'xz' command, please install package xz-utils."
    exit 1
fi

echo -n "Extracting executable path from core file... "

# various attempts to determine the executable path from core file
EXE=$(file $CORE | grep "execfn: " | sed "s/.*execfn: '\([^']*\)'.*/\1/")
if [ -z "$EXE" ]; then
    EXE=$(file $CORE | grep "from " | sed "s/.*from '\([^']*\)'.*/\1/" | awk '{print $1}' | sed "s/://g")
fi
if [ -z "$EXE" ]; then
    EXE=$(strings $CORE | grep ^/ | tail -1)
    if [ ! -f $EXE ] || [ -z "$(file $EXE | grep executable)" ]; then
        EXE=
    fi
fi
if [ -n "$EXE" ]; then
    if [ ! -f $EXE ] || [ -z "$(file $EXE | grep executable)" ]; then
        # get full path to executable
        EXE=$(which $EXE 2>/dev/null)
    fi
fi
if [ -z "$EXE" ]; then
    echo "could not determine the executable path from core file."
    exit 1
fi

echo $EXE
echo -n "Determine shared object dependencies... "

# determine shared object dependencies and record their path
LIBS=$(
    ldd $EXE |
    awk '
    /=> \// {print $3}
        ! /=>/ {print $1}
    '
    )

LIBPHP=$(strings $CORE | grep libphp | grep ^/ | head -1)

echo "done"
echo -n "Get list of PHP extensions... "

# grab extensions and output of 'php -i'
EXTENSION_DIR=$(php -i 2>/dev/null | grep "^extension_dir" | awk {'print $5'})
if [ -n "$EXTENSION_DIR" ]; then
    EXTENSIONS=$(ls -d $EXTENSION_DIR/*)
    echo "done"
else
    EXTENSIONS=
    echo "failed (not packing extensions)"
fi

echo -n "Get output of 'php -i'... "

# grab output of 'php -i'
PHPINFO_FILE=phpinfo.txt
php -i > $PHPINFO_FILE 2>&1

echo "saved to $PHPINFO_FILE"

PKG_INFO_FILE=
if [ -n "$(which dpkg 2>/dev/null)" ]; then
    PKG_INFO_FILE=pkginfo.txt
    echo -n "Get packages info... "

    echo "$EXE:" > $PKG_INFO_FILE
    dpkg -S $EXE 2>&1 | awk -F: {'print $1'} | xargs dpkg -l 2>/dev/null | grep ^ii >> $PKG_INFO_FILE
    echo "$LIBPHP:" >> $PKG_INFO_FILE
    dpkg -S $LIBPHP 2>&1 | awk -F: {'print $1'} | xargs dpkg -l 2>/dev/null | grep ^ii >> $PKG_INFO_FILE
    for L in $LIBS; do
        echo "$L:" >> $PKG_INFO_FILE
        dpkg -S $L 2>&1 | awk -F: {'print $1'} | xargs dpkg -l 2>/dev/null | grep ^ii >> $PKG_INFO_FILE
    done
    for E in $EXTENSIONS; do
        echo "$E:" >> $PKG_INFO_FILE
        dpkg -S $E 2>&1 | awk -F: {'print $1'} | xargs dpkg -l 2>/dev/null | grep ^ii >> $PKG_INFO_FILE
    done

    echo "saved to $PKG_INFO_FILE"
elif [ -n "$(which rpm 2>/dev/null)" ]; then
    PKG_INFO_FILE=pkginfo.txt
    echo -n "Get packages info... "

    echo "$EXE:" > $PKG_INFO_FILE
    rpm -qf $EXE 2>/dev/null >> $PKG_INFO_FILE
    echo "$LIBPHP:" >> $PKG_INFO_FILE
    rpm -qf $LIBPHP 2>/dev/null >> $PKG_INFO_FILE
    for L in $LIBS; do
        echo "$L:" >> $PKG_INFO_FILE
        rpm -qf $L 2>/dev/null >> $PKG_INFO_FILE
    done
    for E in $EXTENSIONS; do
        echo "$E:" >> $PKG_INFO_FILE
        rpm -qf $E 2>/dev/null >> $PKG_INFO_FILE
    done

    echo "saved to $PKG_INFO_FILE"
fi

echo "Archive all relevant binaries and core file..."

# archive all relevant binaries
ARCHIVE=$(basename $CORE)-all.tar.xz
cat <<EOF | tar -vcah -T- -f $ARCHIVE
$EXE
$LIBS
$LIBPHP
$EXTENSIONS
$PHPINFO_FILE
$PKG_INFO_FILE
$CORE
EOF

# delete generated file
rm -f $PHPINFO_FILE $PKG_INFO_FILE

echo
echo "Done: $ARCHIVE"
