Files
scratchpkg/removepkg
2017-12-21 23:50:37 +08:00

336 lines
7.6 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
}
removepkg() {
msg "Removing ${color_green}$ipackagename${color_reset}..."
### CHECK DEPENDENCY ###
if [ ! "$IGNORE_DEP" ]; then
msg2 "Checking dependencies..."
checkdeps $RMNAME
fi
# create lock file prevent simultaneous install/remove process running
spkglock
# source .install script
if [ -f $INDEX_DIR/$1/.pkginstall ]; then
source $INDEX_DIR/$1/.pkginstall
fi
if [ ! "$NO_PREREMOVE" ]; then
run_preremove
fi
msg2 "Removing files & dirs..."
pushd $ROOT_DIR
while IFS=' ' read -r line; do
if [ "$VERBOSE_REMOVE" = "yes" ]; then
rm_silent "$line" && echo "$line" || msgwarn "Failed remove $line"
else
rm_silent "$line" || msgwarn "Failed remove $line"
fi
done < <(tac $INDEX_DIR/$1/.files | grep -v '/$')
popd
pushd $ROOT_DIR
while IFS=' ' read -r line; do
if [ ! "$(grep -R --exclude-dir="$1" -w "$line" "$INDEX_DIR")" ]; then
if [ "$VERBOSE_REMOVE" = "yes" ]; then
rmdir_silent "$line" && echo "$line" || msgwarn "Failed remove $line"
else
rmdir_silent "$line" || msgwarn "Failed remove $line"
fi
fi
done < <(tac $INDEX_DIR/$1/.files | grep '/$')
popd
if [ ! "$NO_POSTREMOVE" ]; then
run_postremove
fi
runpreremovehooks $1
rm -R $INDEX_DIR/$1
if [ -d $INDEX_DIR/$1 ]; then
msgerr "Error occured while removing ${color_red}$ipackagename${color_reset}."
spkglock
exit 1
else
msg "Successfully remove ${color_green}$ipackagename${color_reset}."
fi
case $PREREMOVE_STATUS in
OK) msg "preremove : ${color_green}OK${color_reset}" ;;
KO) msg "preremove : ${color_red}FAIL${color_reset}" ;;
esac
case $POSTREMOVE_STATUS in
OK) msg "postremove : ${color_green}OK${color_reset}" ;;
KO) msg "postremove : ${color_red}FAIL${color_reset}" ;;
esac
runremovehooks
# remove lock file
spkglock
}
run_preremove() {
if [ "`type -t pre_remove`" = "function" ]; then
msg "Running preremove script..."
pre_remove "$iversion" && PREREMOVE_STATUS=OK || PREREMOVE_STATUS=KO
fi
}
run_postremove() {
if [ "`type -t post_remove`" = "function" ]; then
msg "Running postremove script..."
post_remove "$iversion" && POSTREMOVE_STATUS=OK || POSTREMOVE_STATUS=KO
fi
}
getoldname() {
iname=$(cat $INDEX_DIR/$1/.pkginfo | grep ^name | cut -d " " -f3)
iversion=$(cat $INDEX_DIR/$1/.pkginfo | grep ^version | cut -d " " -f3)
irelease=$(cat $INDEX_DIR/$1/.pkginfo | grep ^release | cut -d " " -f3)
ibackup=$(cat $INDEX_DIR/$1/.pkginfo | grep ^backup | cut -d " " -f3-)
idepends=$(cat $INDEX_DIR/$1/.pkginfo | grep ^depends | cut -d " " -f3-)
imakedepends=$(cat $INDEX_DIR/$1/.pkginfo | grep ^makedepends | cut -d " " -f3-)
ipackagename=$iname-$iversion-$irelease
}
checkdeps() {
for installed in $(ls $INDEX_DIR); do
name=$(cat $INDEX_DIR/$installed/.pkginfo | grep ^name | cut -d " " -f3)
version=$(cat $INDEX_DIR/$installed/.pkginfo | grep ^version | cut -d " " -f3)
release=$(cat $INDEX_DIR/$installed/.pkginfo | grep ^release | cut -d " " -f3)
pkgname="$name-$version-$release"
depends=$(cat $INDEX_DIR/$installed/.pkginfo | grep ^depends | cut -d " " -f3-)
for dep in ${depends[@]}; do
if [ "$dep" = "$1" ]; then
ERRDEP+=($pkgname)
fi
done
done
if [ "${#ERRDEP[@]}" -gt 0 ]; then
msgwarn "Package ${color_yellow}$iname-$iversion-$irelease${color_reset} is needed for:"
for pkg in ${ERRDEP[@]}; do
msg2 "$pkg"
done
exit 1
fi
}
checkneworphan() {
for dpd in ${idepends[@]}; do
saferemove $dpd
done
for mdpd in ${imakedepends[@]}; do
saferemove $mdpd
done
if [ "${#neworphan[@]}" -gt 0 ]; then
msg "New orphaned package:"
for list in ${neworphan[@]}; do
msg2 $list
done
fi
}
saferemove() {
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 ] && neworphan+=($1)
}
runremovehooks() {
if [ "${#runthishook[@]}" -gt 0 ]; then
for hook in ${runthishook[@]}; 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
msg "$description"
. $hook
if [ "`type -t exechook`" = "function" ]; then
exechook
fi
fi
unset description operation target
done
fi
}
runpreremovehooks() {
if [ "$(ls $HOOK_DIR/*.hook 2>/dev/null)" ]; then
for hook in $(ls $HOOK_DIR/*.hook); do
operation=$(cat "$hook" | grep ^"# operation" | sed 's/\://' | cut -d ' ' -f 3-)
target=$(cat "$hook" | grep ^"# target" | sed 's/\://' | cut -d ' ' -f 3-)
if [ "$(echo $operation | grep -w "remove" )" ]; then
if [ "$(grep -E $target $INDEX_DIR/$1/.files)" ]; then
runthishook+=($hook)
fi
fi
unset operation target
done
fi
}
help() {
echo "Usage:"
echo " $(basename $0) package name [ <options> <arguments> ]"
echo
echo "Options:"
echo " -id, --ignore-dependency skip dependency check"
echo " -v, --verbose verbose install process"
echo " --no-preremove don't run pre-remove script"
echo " --no-postremove don't run post-remove script"
echo " --no-orphan-check skip orphaned package check after install package"
echo " --no-color disable colour for output"
echo " -h, --help show this help message"
echo
echo "Example:"
echo " $(basename $0) firefox -id -v remove package firefox, skipping dependency check"
echo " and verbose deleted file"
}
parse_options() {
while [ "$1" ]; do
case $1 in
-id|--ignore-dependency)
IGNORE_DEP=yes
;;
-v|--verbose)
VERBOSE_REMOVE=yes
;;
-h|--help)
SHOW_HELP=yes
;;
--no-preremove)
NO_PREREMOVE=yes
;;
--no-postremove)
NO_POSTREMOVE=yes
;;
--no-color)
NO_COLOR=yes
;;
--no-orphan-check)
NO_ORPHAN_CHECK=yes
;;
*)
RMNAME=$1
;;
esac
shift
done
}
main() {
parse_options "$@"
### DISABLE COLOR ###
if [ "$NO_COLOR" ]; then
nocolor
fi
### SHOW HELP ###
if [ "$SHOW_HELP" ]; then
help
exit 0
fi
### CHECK FOR ROOT ACCESS ###
needroot "Removing package"
### CHECK DIRECTORY ###
checkdirexist "$INDEX_DIR" "$BACKUP_DIR" "$REJECTED_DIR"
checkdirwrite "$INDEX_DIR" "$BACKUP_DIR" "$REJECTED_DIR"
checkdirread "$INDEX_DIR" "$BACKUP_DIR" "$REJECTED_DIR"
### PACKAGE NAME ###
if [ -z $RMNAME ]; then
msgerr "Please state package name for remove."
exit 1
fi
### CHECK PACKAGE IN DATABASE ###
if [ ! -d $INDEX_DIR/$RMNAME ]; then
msg "Package ${color_red}$RMNAME${color_reset} not installed."
exit 1
fi
### 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 INSTALLED PACKAGE DATABASE ###
getoldname $RMNAME
### REMOVE PACKAGE ###
removepkg $RMNAME
### CHECK NEW ORPHANED PACKAGE ###
if [ ! "$NO_ORPHAN_CHECK" ]; then
checkneworphan
fi
# msg2 "Running ldconfig..."
if [ -x /sbin/ldconfig ]; then
/sbin/ldconfig
fi
exit 0
}
main "$@"