#!/bin/bash
#
# VERSION=2
# CHANGES="install the php-cgi shipped in this package (patched PHP 5.2.6) to /home/admin/bin"

# global variables #
BEROCONF=/usr/fallback/beroconf
export PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/fallback"

## udhcpc link to busybox
## the link should be removed from REM_LIST of VERSION.rootfs
## but if package missing from mtdblock7, the udhcpc link/script is always removed
## without beeing replaced by the one present in the package.
## so, we removing the link is managed only here since this part now is only executed if the
## package exists in mtdblock7
if [ -L /sbin/udhcpc ]; then
	mount -o remount,rw /
	rm -rf /sbin/udhcpc
	mount -o remount,ro /
fi

## move php-cgi from mtdblock5 (/) to mtdblock7 (/home/admin)
## upgrade from 20.05 (and lower) to 21.02 (and higher)
if [ ! -f /home/admin/bin/php-cgi ]; then
	minimal=2500
	available=$(/bin/df | /bin/grep /home/admin | /usr/bin/awk '{ print $4; }')
	## check if enough space
	if [ ${available} -lt ${minimal} ]; then
		diff=$(expr ${minimal} - ${available})
		${BEROCONF} set root rootfs-phpcgi-failed FREEING_ROOTFS_FAILED:HOMEADMIN_NOTENOUGH_SPACE:${diff}
	## move php-cgi
	else
		IS_FREED=0
		mount -o remount,rw /home/admin
		mkdir -p /home/admin/bin
		mount -o remount,rw /
		if cp /usr/bin/php-cgi /home/admin/bin; then
			if [ "$(/usr/bin/md5sum /usr/bin/php-cgi | /usr/bin/awk '{ print $1; }')" = "$(/usr/bin/md5sum /home/admin/bin/php-cgi | /usr/bin/awk '{ print $1; }')" ]; then
				## force to remount several times / to avoid unexpected behavior
				mount -o remount,rw /
				rm /usr/bin/php-cgi
				sleep 1; sync; sleep 1
				mount -o remount,rw /
				ln -sf /home/admin/bin/php-cgi /usr/bin
				IS_FREED=1
			fi
		fi
		if [ "${IS_FREED}" = "0" ]; then
			rm /home/admin/bin/php-cgi
			${BEROCONF} set root rootfs-phpcgi-failed FREEING_ROOTFS_FAILED:HOMEADMIN_NOTENOUGH_SPACE
		fi
		mount -o remount,ro /
		mount -o remount,ro /home/admin
	fi
fi

## install the php-cgi shipped in this package
#### pkg/rootfs/home/admin/bin/php-cgi is the patched PHP 5.2.6 (src/arm/Makefile-php,
#### patches in src/arm/patches). It is handled here, not by the generic copy
#### loop of rootfs_pkg_install.sh, and always removed from the package before
#### that loop runs: the loop would cp it over the live binary with no space
#### check, and a short write would leave the GUI, the recovery GUI and
#### beroconf without a PHP. php-cgi runs nowhere yet (pre-install runs ON_BOOT
#### from S35pkginst, before S60httpd); /usr/bin/php-cgi already links here.
PHPCGI=/home/admin/bin/php-cgi
PHPCGI_PKG=/home/admin/conf/rootfs/pkg/rootfs${PHPCGI}
PHPCGI_LOG=/usr/conf/permlog/pkginst-rootfs-phpcgi.log

function phpcgi_log {
	echo "[pkginst_rootfs_pre] $(date): ${1}" >> ${PHPCGI_LOG}
}

function md5_of {
	/usr/bin/md5sum ${1} 2>/dev/null | /usr/bin/awk '{ print $1; }'
}

## does a php-cgi run and have the extensions the GUI and beroconf need
function phpcgi_works {
	${1} -v 2>/dev/null | /bin/grep -q '^PHP 5' || return 1
	## built in, without php.ini
	mods=$(${1} -n -m 2>/dev/null)
	for mod in session pcre SQLite PDO; do
		echo "${mods}" | /bin/grep -q "^${mod}\$" || return 1
	done
	## with the php.ini the GUI runs with: curl.so (extension=) has to load
	## into this binary, and nothing may complain on stderr (a PHP Warning
	## there - extension API mismatch, bad ini line - would end up in every
	## CGI response and every beroconf call)
	mods=$(${1} -m 2>/dev/null)
	echo "${mods}" | /bin/grep -q '^curl$' || return 1
	[ -z "$(${1} -m 2>&1 >/dev/null)" ] || return 1
	return 0
}

if [ -f ${PHPCGI_PKG} ]; then
	mount -o remount,rw /home/admin
	new_md5=$(md5_of ${PHPCGI_PKG})
	if [ ! -f ${PHPCGI} ] || [ -L ${PHPCGI} ]; then
		## not moved to /home/admin (see above, or pre_install.sh blocked the update)
		phpcgi_log "no ${PHPCGI} to replace, shipped php-cgi not installed"
	elif [ "$(md5_of ${PHPCGI})" = "${new_md5}" ]; then
		phpcgi_log "${PHPCGI} already up to date (${new_md5})"
	elif ! /bin/grep -q "^${new_md5}\$" /home/admin/conf/rootfs/md5sum.list; then
		phpcgi_log "shipped php-cgi does not match md5sum.list, keeping ${PHPCGI}"
		${BEROCONF} set root rootfs-phpcgi-failed UPDATE_PHPCGI_MD5
	elif ! phpcgi_works ${PHPCGI_PKG}; then
		phpcgi_log "shipped php-cgi does not run or lacks extensions, keeping ${PHPCGI}"
		${BEROCONF} set root rootfs-phpcgi-failed UPDATE_PHPCGI_BROKEN
	elif ! /bin/grep -q " /home/admin/" /proc/mounts; then
		## package and target are on the same filesystem (mtdblock7): rename()
		## swaps the file in one step and needs no extra space - the new
		## binary already sits on this partition. On failure the old one stays.
		if /bin/mv -f ${PHPCGI_PKG} ${PHPCGI}; then
			phpcgi_log "${PHPCGI} replaced (${new_md5})"
			${BEROCONF} delete root rootfs-phpcgi-failed
		else
			phpcgi_log "renaming the shipped php-cgi failed, keeping ${PHPCGI}"
			${BEROCONF} set root rootfs-phpcgi-failed UPDATE_PHPCGI_RENAME
		fi
	else
		## something is mounted below /home/admin: copy, which needs the
		## space of a second php-cgi, like the minimal check above
		minimal=$(( $(/bin/ls -l ${PHPCGI_PKG} | /usr/bin/awk '{ print $5; }') / 1024 + 500 ))
		## free space of the filesystem /home/admin/bin is on - "df | grep
		## /home/admin" would also list the mounts below it
		available=$(/bin/df ${PHPCGI%/*} | /usr/bin/awk 'NR==2{ print $4; }')
		case "${available}" in ''|*[!0-9]*) available=0 ;; esac
		if [ ${available} -lt ${minimal} ]; then
			diff=$(expr ${minimal} - ${available})
			phpcgi_log "not enough space to copy php-cgi (${diff} KB missing), keeping ${PHPCGI}"
			${BEROCONF} set root rootfs-phpcgi-failed UPDATE_PHPCGI_NOTENOUGH_SPACE:${diff}
		elif /bin/cp ${PHPCGI_PKG} ${PHPCGI}.new && [ "$(md5_of ${PHPCGI}.new)" = "${new_md5}" ] \
			&& /bin/chmod 755 ${PHPCGI}.new && /bin/mv -f ${PHPCGI}.new ${PHPCGI}; then
			phpcgi_log "${PHPCGI} replaced by copy (${new_md5})"
			${BEROCONF} delete root rootfs-phpcgi-failed
		else
			rm -f ${PHPCGI}.new
			phpcgi_log "copying the shipped php-cgi failed, keeping ${PHPCGI}"
			${BEROCONF} set root rootfs-phpcgi-failed UPDATE_PHPCGI_COPY
		fi
	fi
	## never leave it to the generic copy loop
	rm -f ${PHPCGI_PKG}
	rmdir /home/admin/conf/rootfs/pkg/rootfs/home/admin/bin /home/admin/conf/rootfs/pkg/rootfs/home/admin \
		/home/admin/conf/rootfs/pkg/rootfs/home 2>/dev/null
	sync
	mount -o remount,ro /home/admin
fi

## mounting mtd5 space
mount -oremount,rw /
