Files
scratchpkg/removepkg
2017-09-19 08:00:25 +08:00

324 lines
6.7 KiB
Bash
Executable File

#!/bin/bash
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..."
while IFS=' ' read -r line; do
pushd $ROOT_DIR
if [ "$VERBOSE_REMOVE" = "yes" ]; then
rm_silent "$line" && echo "$line" || msgwarn "Failed remove $line"
else
rm_silent "$line" || msgwarn "Failed remove $line"
fi
popd
done < <(tac $INDEX_DIR/$1/.files | grep -v '/$')
msg2 "Removing dirs..."
while IFS=' ' read -r line; do
#NOREMOVE=""
#if [ ! "$(find "$INDEX_DIR" -path "$INDEX_DIR"/$1 -prune -o -name .files -exec grep "$line" {} \;)" ]; then
if [ ! "$(grep -R --exclude-dir="$1" -w "$line" "$INDEX_DIR")" ]; then
pushd $ROOT_DIR
if [ "$VERBOSE_REMOVE" = "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/$1/.files | grep '/$')
if [ ! "$NO_POSTREMOVE" ]; then
run_postremove
fi
if [ "$(grep -w usr/share/info/ $INDEX_DIR/$1/.files)" ]; then
UPDATE_INFO_PAGES=yes
fi
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
# 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
}
updateinfopages() {
pushd /usr/share/info
if [ -f dir ]; then
rm dir
fi
for f in *; do
install-info $f dir 2>/dev/null
done
popd
}
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)
}
check_directory() {
for dir in $INDEX_DIR $BACKUP_DIR $REJECTED_DIR; do
if [ ! -d $dir ]; then
msg "Directory ${color_yellow}$1${color_reset} not exist."
DIR_ERROR=yes
elif [ ! -w $dir ]; then
msg "Directory ${color_yellow}$1${color_reset} not writable."
DIR_ERROR=yes
elif [ ! -x $dir ] || [ ! -r $1 ]; then
msg "Directory ${color_yellow}$1${color_reset} not readable."
DIR_ERROR=yes
fi
done
[ "$DIR_ERROR" ] && exit 1
}
parse_options() {
while [ "$1" ]; do
case $1 in
-id|--ignore-dependency)
IGNORE_DEP=yes
;;
-ds|--disable-script)
DISABLE_SCRIPT=yes
;;
-v|--verbose)
VERBOSE_REMOVE=yes
;;
--no-preremove)
NO_PREREMOVE=yes
;;
--no-postremove)
NO_POSTREMOVE=yes
;;
--no-color)
NO_COLOR=yes
;;
--no-orphan-check)
NO_ORPHAN_CHECK=yes
;;
--root)
if [ ! "$2" ]; then
msg "Option '$1' require an argument (root path)."
exit 1
fi
ROOT="$2"
shift
;;
*)
RMNAME=$1
;;
esac
shift
done
}
main() {
. /usr/share/scratchpkg/functions || exit 1
parse_options "$@"
### DISABLE COLOR ###
if [ "$NO_COLOR" ]; then
nocolor
fi
loadconfigfile
# CHANGE ROOT PATH ###
if [ "$ROOT" ]; then
ROOT_DIR="$ROOT"
INDEX_DIR="$ROOT_DIR/$INDEX_DIR"
BACKUP_DIR="$ROOT_DIR/$BACKUP_DIR"
REJECTED_DIR="$ROOT_DIR/$REJECTED_DIR"
fi
if [ -z $RMNAME ]; then
msgerr "Please state package name for remove."
exit 1
fi
### CHECK FOR ROOT ACCESS ###
if [ "$UID" != "0" ]; then
msgerr "${color_red}Removing package need root access.${color_reset}"
exit 1
fi
check_directory
### 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
### CHECK PACKAGE IN DATABASE ###
if [ ! -d $INDEX_DIR/$RMNAME ]; then
msg "Package ${color_red}$RMNAME${color_reset} not installed."
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
### RUN NECESSARY UPDATE AFTER REMOVE PACKAGE ###
updatesystemdb
### UPDATE INFO PAGES ###
if [ "$UPDATE_INFO_PAGES" ]; then
updateinfopages
fi
exit 0
}
main "$@"