#
# Customization script for the Magisk Module with network tools
#
# History
#   18.08.2024 /bs
#     initial release
#   25.08.2024 /bs
#     the wrapper script now also works for other binaries
#
#
# Notes:
#
# This Magisk Module contains various network tools for arm64 CPUs
#
# Documentation for creating Magisk Modules: https://topjohnwu.github.io/Magisk/guides.html
#
# Environment variables that can be used:
#
#    MAGISK_VER (string): the version string of current installed Magisk (e.g. v20.0)
#    MAGISK_VER_CODE (int): the version code of current installed Magisk (e.g. 20000)
#    BOOTMODE (bool): true if the module is being installed in the Magisk app
#    MODPATH (path): the path where your module files should be installed
#    TMPDIR (path): a place where you can temporarily store files
#    ZIPFILE (path): your module’s installation zip
#    ARCH (string): the CPU architecture of the device. Value is either arm, arm64, x86, or x64
#    IS64BIT (bool): true if $ARCH is either arm64 or x64
#    API (int): the API level (Android version) of the device (e.g. 21 for Android 5.0)
#

# -----------------------------------------------------------------------------

# define constants
#
__TRUE=0
__FALSE=1


# -----------------------------------------------------------------------------
# init global variables
#

MODULE_VERSION="$( grep "^version=" $MODPATH/module.prop  | cut -f2 -d "=" )"

WRAPPER_SCRIPT="/system/bin/network_tools_bin_wrapper"
WRAPPER_SCRIPT_NAME="${WRAPPER_SCRIPT##*/}"

CMD_PARAMETER=""

# -----------------------------------------------------------------------------

function LogMsg {
  ui_print "$*"
}

function LogInfo {
  LogMsg "INFO: $*"
}

function LogWarning {
  LogMsg "WARNING: $*"
}

function LogError {
  LogMsg "ERROR: $*"
}


# -----------------------------------------------------------------------------

LogMsg "The current environment for this installation is"

LogMsg "The version of the installed Magisk is \"${MAGISK_VER}\" (${MAGISK_VER_CODE})"

LogInfo "BOOTMODE is \"${BOOTMODE}\" "
LogInfo "MODPATH is \"${MODPATH}\" "
LogInfo "TMPDIR is \"${TMPDIR}\" "
LogInfo "ZIPFILE is \"${ZIPFILE}\" "
LogInfo "ARCH is \"${ARCH}\" "
LogInfo "IS64BIT is \"${IS64BIT}\" "
LogInfo "API is \"${API}\" "

# -----------------------------------------------------------------------------

# example output for the variables:


#  The version of the installed Magisk is "25.0" (25000)
#  INFO: BOOTMODE is "true" 
#  INFO: MODPATH is "/data/adb/modules_update/PlayStore_for_MicroG" 
#  INFO: TMPDIR is "/dev/tmp" 
#  INFO: ZIPFILE is "/data/user/0/com.topjohnwu.magisk/cache/flash/install.zip" 
#  INFO: ARCH is "arm64" 
#  INFO: IS64BIT is "true" 
#  INFO: API is "32"


# -----------------------------------------------------------------------------

LogMsg "Installing the Magisk Module with the network tools version \"${MODULE_VERSION}\" ..."

# LogMsg "Checking the OS configuration ..."

ERRORS_FOUND=${__FALSE}

MACHINE_TYPE="$( uname -m )"

# check the current CPU
#
LogMsg "Checking the type of the CPU used in this device ...."
LogMsg "The CPU in this device is a ${ARCH} CPU"
LogMsg "The machine type reported by \"uname -m\" is \"${MACHINE_TYPE}\" "

if [ "${ARCH}"x != "arm64"x ] ; then
  abort "This Magisk module is for arm and x86 CPUs only"
fi

# ---------------------------------------------------------------------

ALT_TERMINFO_DIR="/data/local/tmp/usr/share/terminfo"

TERMINFO_DIR="/system/etc/terminfo"
EXT_TERMINFO_DIR="/system_ext/etc/terminfo"

NEW_TERMINFO_DIR=""

# ---------------------------------------------------------------------
#

TEMPVAR="$( grep -v localhost /etc/hosts )"
if [ "${TEMPVAR}"x != ""x ] ; then
  echo "Looks like there is already a bind mount for \"/system/etc/hosts\" in place -- will not create a bind mount for that file"
else  
  [ -r $MODPATH/system/etc/hosts.template ] && mv $MODPATH/system/etc/hosts.template  $MODPATH/system/etc/hosts
fi

LogMsg "Creating the certificates ..."

mkdir -p $MODPATH/system/etc/security
for i in /system/etc/security/cacerts*/*.0; do
  echo "$(sed -n "/BEGIN CERTIFICATE/,/END CERTIFICATE/p" $i)" >> $MODPATH/system/etc/security/ca-certificates.crt
done

LogMsg "Searching the terminfo directory ..."

if [ -d "${ALT_TERMINFO_DIR}" ] ; then
  LogMsg "The terminfo directory \"${ALT_TERMINFO_DIR}\" exists - now using that directory"
  CUR_TERMINFO_DIR="${ALT_TERMINFO_DIR}"
elif [ -d "${TERMINFO_DIR}" ] ; then
  LogMsg "The terminfo directory \"${TERMINFO_DIR}\" exists in this OS"
  CUR_TERMINFO_DIR="${TERMINFO_DIR}"

elif [ -d "${EXT_TERMINFO_DIR}" ] ; then
  LogMsg "The terminfo directory \"${EXT_TERMINFO_DIR}\" exists in this OS"
  CUR_TERMINFO_DIR="${EXT_TERMINFO_DIR}"
else
  LogMsg "The terminfo directory does not exist in the running OS."

  LogMsg "Now creating the terminfo directory \"${ALT_TERMINFO_DIR}\" ..."
  mkdir -p "${ALT_TERMINFO_DIR}" && \
    cd "${ALT_TERMINFO_DIR%/*}" && \
    tar -xf $MODPATH/terminfo_files.tar 
  if [ $? -ne 0 ] ; then
    LogError "Error creating the terminfo directory \"${ALT_TERMINFO_DIR}\" "
  else 
    NEW_TERMINFO_DIR="${ALT_TERMINFO_DIR}"

    CUR_TERMINFO_DIR="${ALT_TERMINFO_DIR}"
  fi  
fi

# ---------------------------------------------------------------------


LogMsg "Creating the wrapper script \"${WRAPPER_SCRIPT}\" ..."

cat >${MODPATH}${WRAPPER_SCRIPT} <<EOT
#!/system/bin/sh

if [ \${0##*/} = ${WRAPPER_SCRIPT_NAME} ] ; then
  echo "ERROR: Do not call this script - this is only a wrapper used to call the executables with a well defined enviroment"
  exit 254
fi


# settings for all binaries
# 
export TERMINFO="${CUR_TERMINFO_DIR}"

case \${0##*/} in

# settings for lynx
  lynx* )
    if [ "${SSL_CERT_FILE}"x = ""x ] ; then
      if [ -r /system/etc/security/ca-certificates.crt ] ; then
        export SSL_CERT_FILE=/system/etc/security/ca-certificates.crt
      fi
    fi
    ;;

  links )
    export HOME=/data/local/tmp
    export CMD_PARAMETER="\${CMD_PARAMETER} -ssl.builtin-certificates 1 "
    ;;

esac

eval 'exec  /system/bin/\${0##*/}.bin \${CMD_PARAMETER} \${1+"\$@"}'

EOT

set_perm "${WRAPPER_SCRIPT}" 0 0 0755 u:object_r:system_file:s0

# get the list of binaries that should be used via wrapper script
#
BINARIES_FOR_THE_WRAPPER="$( cd ${MODPATH}/system/bin && ls *.bin )"

# create the symoblic links for the binaries
#
for i in ${BINARIES_FOR_THE_WRAPPER} ; do
  LogMsg "Creating the symbolic link for ${i%*.bin} ..."
  ln -s "./${WRAPPER_SCRIPT##*/}" "${MODPATH}/system/bin/${i%*.bin}"
done


LogMsg "Correcting the permissions for the new files ..."

for i in bin lib lib64 ; do
  [ ! -d "${MODPATH}/system/$i" ] && continue
  LogMsg "Processing the files in the directory ${MODPATH}/system/$i ..."

  set_perm_recursive "${MODPATH}/system/$i" 0 0 0755 0755 u:object_r:system_file:s0

  chcon -R -h  u:object_r:system_file:s0 "${MODPATH}/system/$i"

done

for i in usr/share etc ${NEW_TERMINFO_DIR} ; do
  
  [[ $i != /* ]] && CUR_ENTRY="${MODPATH}/system/$i" || CUR_ENTRY="$i"

  [ ! -d "${CUR_ENTRY}" ] && continue 
  
  LogMsg "Processing the files in the directory ${CUR_ENTRY} ..."
  set_perm_recursive "${CUR_ENTRY}" 0 0 0755 0644 u:object_r:system_file:s0
  chcon -R -h u:object_r:system_file:s0 "${CUR_ENTRY}"
done


