Files
scratchpkg/installpkg
2018-03-03 23:42:34 +08:00

544 lines
14 KiB
Bash
Executable File

#!/bin/bash
export LC_ALL=C
. /usr/share/scratchpkg/functions || exit 1
spkglock() {
if [ ! -f /tmp/spkg.lock ]; then
touch /tmp/spkg.lock
else
rm /tmp/spkg.lock
fi
}
installpkg() {
msg "Installing ${color_green}$packagename${color_reset}..."
# noextract file into system
for noextr in ${NO_EXTRACT[@]}; do
excludefile+=(--exclude=$noextr)
done
#ignore dependency check
if [ ! "$IGNORE_DEP" ]; then
msg2 "Checking package dependencies..."
checkdeps
fi
#ignore conflict
if [ ! "$IGNORE_CONFLICT" ]; then
msg2 "Checking package/file conflict..."
if [ "$UPGRADE_PKG" ] || [ "$REINSTALL_PKG" ]; then
upcheckconflict
else
checkconflict
fi
checkpkgconflict
fi
# create lock file prevent simultaneous install package
spkglock
# backup conf as set in spkgbuld if upgrade or reinstall package
if [ "$UPGRADE_PKG" ] || [ "$REINSTALL_PKG" ]; then
if [ ! "$NO_BACKUP" ]; then
backupconf
fi
fi
# source .install file inside package
if [ $(tar -tf "$PKGNAME" | grep -x ".pkginstall") ] && [ ! "$REINSTALL_PKG" ]; then
source <(tar -xf "$PKGNAME" .pkginstall -O)
fi
# run preinstall script if no --no-preinstall flag and not upgrade package
if [ ! "$NO_PREINSTALL" ] && [ ! "$UPGRADE_PKG" ]; then
run_preinstall
fi
# run preupgrade script if package upgrade
if [ "$UPGRADE_PKG" ] && [ ! "$NO_PREUPGRADE" ]; then
run_preupgrade
fi
#installing package into system
if [[ $(tar -tf "$PKGNAME") ]]; then
msg2 "Extracting package..."
if [ "$VERBOSE_INSTALL" ]; then
tar --keep-directory-symlink --no-overwrite-dir -p -x -v -f $PKGNAME -C $ROOT_DIR --exclude=.pkginfo --exclude=.pkginstall --exclude=.pkgreadme ${excludefile[@]}
else
tar --keep-directory-symlink --no-overwrite-dir -p -x -f $PKGNAME -C $ROOT_DIR --exclude=.pkginfo --exclude=.pkginstall --exclude=.pkgreadme ${excludefile[@]}
fi
else
msgerr "Package is corrupted. Aborted!"
spkglock
exit 1
fi
if [ $? != 0 ]; then
msgerr "Failed install ${color_red}$packagename${color_reset}."
while IFS=' ' read -r line; do
pushd $ROOT_DIR
rm_silent "$line" || rmdir_silent --ignore-fail-on-non-empty "$line"
popd
done < <(tar -tf "$PKGNAME" --exclude=.pkginfo --exclude=.pkginstall --exclude=.pkgreadme ${excludefile[@]} | tac)
spkglock
exit 1
fi
if [ "$UPGRADE_PKG" ] || [ "$REINSTALL_PKG" ]; then
removeoldfiles
fi
registerpkg
if [ ! "$NO_POSTINSTALL" ] && [ ! "$UPGRADE_PKG" ]; then
run_postinstall
fi
if [ "$UPGRADE_PKG" ] && [ ! "$NO_POSTUPGRADE" ]; then
run_postupgrade
fi
restoreconf
case $PREINSTALL_STATUS in
OK) msg "preinstall : ${color_green}OK${color_reset}" ;;
KO) msg "preinstall : ${color_red}FAIL${color_reset}" ;;
esac
case $PREUPGRADE_STATUS in
OK) msg "preupgrade : ${color_green}OK${color_reset}" ;;
KO) msg "preupgrade : ${color_red}FAIL${color_reset}" ;;
esac
case $POSTINSTALL_STATUS in
OK) msg "postinstall : ${color_green}OK${color_reset}" ;;
KO) msg "postinstall : ${color_red}FAIL${color_reset}" ;;
esac
case $POSTUPGRADE_STATUS in
OK) msg "postupgrade : ${color_green}OK${color_reset}" ;;
KO) msg "postupgrade : ${color_red}FAIL${color_reset}" ;;
esac
runhooks
if [ -f $INDEX_DIR/$name/.pkgreadme ]; then
msg "This package has ${color_green}readme${color_reset}"
fi
# remove lock file
spkglock
}
removeoldfiles() {
TMP_TARLIST="/tmp/$name.tarlist.spkg"
tar -tf "$PKGNAME" --exclude=.pkginfo --exclude=.pkginstall --exclude=.pkgreadme ${excludefile[@]} > $TMP_TARLIST
msg2 "Removing old files & dirs..."
grep -v '/$' $INDEX_DIR/$name/.files | while read line; do
if [ ! "$(grep -Fx "$line" $TMP_TARLIST)" ]; then
pushd $ROOT_DIR
if [ "$VERBOSE_INSTALL" = "yes" ]; then
rm_silent "$line" && echo "$line" && OLDFILEREMOVE=yes || msgwarn "Failed remove $line"
else
rm_silent "$line" && OLDFILEREMOVE=yes || msgwarn "Failed remove $line"
fi
popd
fi
done
while IFS=' ' read -r line; do
if [ ! "$(tac $TMP_TARLIST | grep -x "$line")" ] && [ ! "$(grep -Rx --exclude-dir="$name" -w "$line" "$INDEX_DIR")" ]; then
pushd $ROOT_DIR
if [ "$VERBOSE_INSTALL" = "yes" ]; then
rmdir_silent "$line" && echo "$line" || msgwarn "Failed remove $line"
else
rmdir_silent "$line" || msgwarn "Failed remove $line"
fi
popd
fi
done < <(tac $INDEX_DIR/$name/.files | grep '/$')
rm $TMP_TARLIST
}
registerpkg() {
[ ! -d $INDEX_DIR/$name ] && mkdir $INDEX_DIR/$name
tar -x -f $PKGNAME -C $INDEX_DIR/$name .pkginfo
tar -t -f $PKGNAME --exclude=.pkginfo --exclude=.pkginstall --exclude=.pkgreadme ${excludefile[@]} > $INDEX_DIR/$name/.files
tar -x -f $PKGNAME -C $INDEX_DIR/$name .pkginstall .pkgreadme >/dev/null 2>&1
msg "Successfully install ${color_green}$packagename${color_reset}."
}
checkdeps() {
for dep in ${depends[@]}; do
if [ ! -d $INDEX_DIR/$dep ]; then
MSGDEP+=($dep)
fi
done
if [ "${#MSGDEP[@]}" -gt 0 ]; then
msg "Missing dependencies:"
for msdp in ${MSGDEP[@]}; do
msg2 "$msdp"
done
exit 1
fi
}
checkpkgconflict() {
for pkg in ${conflict[@]}; do
if [ -d $INDEX_DIR/$pkg ]; then
msg "Conflict package!: ${color_yellow}$pkg${color_reset}"
PKG_CONFLICT=yes
fi
done
if [ "$PKG_CONFLICT" ]; then
exit 1
fi
}
checkconflict() {
while IFS=' ' read -r line; do
pushd $ROOT_DIR
if [ -e "$line" ]; then
fileconflict+=(${line})
fi
popd
done < <(tar -tf "$PKGNAME" --exclude=.pkginfo --exclude=.pkginstall --exclude=.pkgreadme ${excludefile[@]} | grep -v '/$')
if [ "${#fileconflict[@]}" -gt 0 ]; then
msgerr "File conflict found:"
for fc in ${fileconflict[@]}; do
msg2 "$fc"
done
exit 1
fi
}
upcheckconflict() {
while IFS=' ' read -r line; do
pushd $ROOT_DIR
if [ -e "$line" ]; then
if [ ! "$(grep -Fx "$line" "$INDEX_DIR/$name/.files")" ]; then
fileconflict+=(${line})
fi
fi
popd
done < <(tar -tf "$PKGNAME" --exclude=.pkginfo --exclude=.pkginstall --exclude=.pkgreadme ${excludefile[@]} | grep -v '/$')
if [ "${#fileconflict[@]}" -gt 0 ]; then
msgerr "File conflict found:"
for fc in ${fileconflict[@]}; do
msg2 "$fc"
done
exit 1
fi
}
getname() {
name=$(tar xf $PKGNAME .pkginfo -O | grep ^name | cut -d " " -f3)
version=$(tar xf $PKGNAME .pkginfo -O | grep ^version | cut -d " " -f3)
release=$(tar xf $PKGNAME .pkginfo -O | grep ^release | cut -d " " -f3)
depends=$(tar xf $PKGNAME .pkginfo -O | grep ^depends | cut -d " " -f3-)
makedepends=$(tar xf $PKGNAME .pkginfo -O | grep ^makedepends | cut -d " " -f3-)
conflict=$(tar xf $PKGNAME .pkginfo -O | grep ^conflict | cut -d " " -f3-)
packagename=$name-$version-$release
}
getoldname() {
iname=$(cat $INDEX_DIR/$name/.pkginfo | grep ^name | cut -d " " -f3)
iversion=$(cat $INDEX_DIR/$name/.pkginfo | grep ^version | cut -d " " -f3)
irelease=$(cat $INDEX_DIR/$name/.pkginfo | grep ^release | cut -d " " -f3)
backup=$(cat $INDEX_DIR/$name/.pkginfo | grep ^backup | cut -d " " -f3-)
ipackagename=$iname-$iversion-$irelease
}
backupconf() {
pushd $ROOT_DIR
for bkp in ${backup[@]}; do
if [ -e $bkp ]; then
msg2 "Backup ${color_purple}$bkp${color_reset}"
rm -f $bkp.spkgtmp
cp $bkp $bkp.spkgtmp
FILEBACKUP+=($bkp)
fi
done
popd
}
restoreconf() {
if [ "${#FILEBACKUP[@]}" -gt 0 ]; then
pushd $ROOT_DIR
for b in ${FILEBACKUP[@]}; do
if [ -e $b ]; then
mv $b $b.spkgnew
mv $b.spkgtmp $b
fi
done
popd
fi
}
checkoutdate() {
if [ $packagename = $ipackagename ]; then
msg "Package ${color_green}$packagename${color_reset} is up-to-date."
exit 0
elif [ -f "$INDEX_DIR/$name"/.lock ]; then
msgerr "Package '$name' is locked."
exit 0
fi
}
run_preinstall() {
if [ "`type -t pre_install`" = "function" ]; then
msg "Running preinstall script..."
pre_install "$version" && PREINSTALL_STATUS=OK || PREINSTALL_STATUS=KO
fi
}
run_postinstall() {
if [ "`type -t post_install`" = "function" ]; then
msg "Running postinstall script..."
post_install "$version" && POSTINSTALL_STATUS=OK || POSTINSTALL_STATUS=KO
fi
}
run_preupgrade() {
if [ "`type -t pre_upgrade`" = "function" ]; then
msg "Running preupgrade script..."
pre_upgrade "$version" "$iversion" && PREUPGRADE_STATUS=OK || PREUPGRADE_STATUS=KO
fi
}
run_postupgrade() {
if [ "`type -t post_upgrade`" = "function" ]; then
msg "Running postupgrade script..."
post_upgrade "$version" "$iversion" && POSTUPGRADE_STATUS=OK || POSTUPGRADE_STATUS=KO
fi
}
checkneworphan() {
for md in ${makedepends[@]}; do
removemakedepends $md
done
if [ "${#saferemove[@]}" -gt 0 ]; then
msg "Package safe for remove:"
for saferem in ${saferemove[@]}; do
msg2 "$saferem"
done
fi
}
runhooks() {
if [ "$UPGRADE_PKG" ]; then
opr=upgrade
else
opr=install
fi
if [ "$(ls $HOOK_DIR/*.hook 2>/dev/null)" ]; then
for hook in $(ls $HOOK_DIR/*.hook); do
description=$(cat "$hook" | grep ^"# description" | sed 's/\://' | cut -d ' ' -f 3-)
operation=$(cat "$hook" | grep ^"# operation" | sed 's/\://' | cut -d ' ' -f 3-)
target=$(cat "$hook" | grep ^"# target" | sed 's/\://' | cut -d ' ' -f 3-)
if [ -n "$description" ] && [ -n "$operation" ] && [ -n "$target" ]; then
if [ "$(echo $operation | grep -w "$opr" )" ]; then
if [ "$(grep -E $target $INDEX_DIR/$name/.files)" ]; then
msg "$description"
. $hook
if [ "`type -t exechook`" = "function" ]; then
exechook
fi
fi
fi
fi
unset description operation target
done
fi
}
removemakedepends() {
ORPHAN="yes"
for all_installed in $(ls $INDEX_DIR); do
depend=$(cat $INDEX_DIR/$all_installed/.pkginfo | grep ^depends | cut -d " " -f3-)
for dep in ${depend[@]}; do
if [ $dep = $1 ]; then
ORPHAN="no"
fi
done
done
[ "$ORPHAN" = "yes" ] && [ -d $INDEX_DIR/$1 ] && saferemove+=($1)
}
help() {
cat << EOF
Usage:
installpkg package.spkg.txz [ <options> <arguments> ]
Options:
-u, --upgrade update package
-r, --reinstall reinstall package
-id, --ignore-dependency skip dependency check
-ic, --ignore-conflict ignore conflict when installing package
-v, --verbose verbose install process
--no-preinstall don't run pre-install script
--no-postinstall don't run post-install script
--no-preupgrade don't run pre-upgrade script
--no-postupgrade don't run post-upgrade script
--no-backup skip backup when upgrading package
--no-orphan-check skip orphaned package check after install package
--no-color disable colour for output
-h, --help show this help message
Example:
installpkg foobar-1.0-1.spkg.txz -u --no-backup upgrade package foobar-1.0-1 without backup
its old configuration files
EOF
}
parse_options() {
while [ "$1" ]; do
case $1 in
-u | --upgrade) UPGRADE_PKG=yes; shift ;;
-r | --reinstall) REINSTALL_PKG=yes; shift ;;
-id | --ignore-dependency) IGNORE_DEP=yes; shift ;;
-ic | --ignore-conflict) IGNORE_CONFLICT=yes; shift ;;
-v | --verbose) VERBOSE_INSTALL=yes; shift ;;
--no-preinstall) NO_PREINSTALL=yes; shift ;;
--no-postinstall) NO_POSTINSTALL=yes; shift ;;
--no-preupgrade) NO_PREUPGRADE=yes; shift ;;
--no-postupgrade) NO_POSTUPGRADE=yes; shift ;;
--no-backup) NO_BACKUP=yes; shift ;;
--no-color) nocolor; shift ;;
--no-orphan-check) NO_ORPHAN_CHECK=yes; shift ;;
*.spkg.txz) PKGNAME="$1"; shift ;;
-h | --help) help; exit 0; shift ;;
*) msg "Invalid option!"; exit 1 ;;
esac
done
}
main() {
parse_options "$@"
### NOT STATED PACKAGE ###
if [ -z $PKGNAME ]; then
msgerr "Please state the package to install."
exit 1
fi
### CHECK EXISTANT OF PACKAGE FILE ###
if [ ! -f $PKGNAME ]; then
msgerr "Package ${color_red}$1${color_reset} not exist!"
exit 1
fi
### CHECK FOR ROOT ACCESS ###
needroot "Installing package"
### CHECK DIRECTORY ###
checkdirexist "$INDEX_DIR"
checkdirwrite "$INDEX_DIR"
checkdirread "$INDEX_DIR"
### CHECK FOR LOCK FILE ###
if [ -f /tmp/spkg.lock ]; then
msgerr "Cant install/remove package simultaneously."
msgerr "remove ${color_yellow}/tmp/spkg.lock${color_reset} if no install/remove package process running."
exit 1
fi
### GET NAME, VERSION, RELEASE FROM PACKAGE ###
getname # get info from package
### IF INSTALLED & NO UPGRADE & NO REINSTALL ###
if [ -d $INDEX_DIR/$name ] && [ ! "$UPGRADE_PKG" ] && [ ! "$REINSTALL_PKG" ]; then
getoldname # get info from package index
msg "Package ${color_green}$ipackagename${color_reset} already installed."
exit 0
fi
### IF UPGRADE OR REINSTALL PACKAGE ###
if [ "$UPGRADE_PKG" ] || [ "$REINSTALL_PKG" ]; then
if [ ! -d $INDEX_DIR/$name ]; then
msg "Package ${color_red}$name${color_reset} is not installed."
exit 1
fi
getoldname
# UPGRADE PACKAGE
if [ "$UPGRADE_PKG" ]; then
checkoutdate
msg "Upgrading package: ${color_yellow}$ipackagename${color_reset} -> ${color_green}$packagename${color_reset}"
# REINSTALL PACKAGE
elif [ "$REINSTALL_PKG" ]; then
msg "Reinstall package ${color_green}$packagename${color_reset}."
fi
fi
### INSTALL PACKAGE INTO SYSTEM ###
installpkg
# check orphan package (usually makedepends package)
if [ ! "$NO_ORPHAN_CHECK" ]; then
checkneworphan
fi
# msg2 "Running ldconfig..."
if [ -x /sbin/ldconfig ]; then
/sbin/ldconfig
fi
exit 0
}
main "$@"