#!/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 ${GREEN}$ipackagename${CRESET}..." ### CHECK DEPENDENCY ### if [ ! "$IGNORE_DEP" ]; then msg2 "Checking dependencies..." checkdeps $1 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 for backup in $ibackup; do [ -f ${backup}.spkgnew ] && rm ${backup}.spkgnew done 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 ${RED}$ipackagename${CRESET}." spkglock exit 1 else msg "Successfully remove ${GREEN}$ipackagename${CRESET}." fi case $PREREMOVE_STATUS in OK) msg "preremove : ${GREEN}OK${CRESET}" ;; KO) msg "preremove : ${RED}FAIL${CRESET}" ;; esac case $POSTREMOVE_STATUS in OK) msg "postremove : ${GREEN}OK${CRESET}" ;; KO) msg "postremove : ${RED}FAIL${CRESET}" ;; 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=$(installed_pkg_info name $1) iversion=$(installed_pkg_info version $1) irelease=$(installed_pkg_info release $1) ibackup=$(installed_pkg_info backup $1) idepends=$(installed_pkg_info depends $1) imakedepends=$(installed_pkg_info makedepends $1) ipackagename=$iname-$iversion-$irelease } checkdeps() { for pkg in $(allinstalled); do name=$(installed_pkg_info name $pkg) version=$(installed_pkg_info version $pkg) release=$(installed_pkg_info release $pkg) pkgname="$name-$version-$release" depends=$(installed_pkg_info depends $pkg) for dep in ${depends[@]}; do if [ "$dep" = "$1" ]; then ERRDEP+=($pkgname) fi done done if [ "${#ERRDEP[@]}" -gt 0 ]; then msgwarn "Package ${YELLOW}$iname-$iversion-$irelease${CRESET} 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() { cat << EOF Usage: removepkg package name [ ] Options: -id, --ignore-dependency skip dependency check -v, --verbose verbose install process --no-preremove don't run pre-remove script --no-postremove don't run post-remove script --no-orphan-check skip orphaned package check after install package --no-color disable colour for output -h, --help show this help message Example: removepkg firefox -id -v remove package firefox, skipping dependency check and verbose deleted file EOF } arg() { if echo "" $1 | grep -vq "^ -"; then return 0 else return 1 fi } parse_options() { if [ -z "$1" ]; then SHOWHELP=yes else while [ "$1" ]; do case $1 in -id | --ignore-dependency) IGNORE_DEP=yes ;; -v | --verbose) VERBOSE_REMOVE=yes ;; -h | --help) SHOWHELP=yes ;; --no-preremove) NO_PREREMOVE=yes ;; --no-postremove) NO_POSTREMOVE=yes ;; --no-color) NOCOLOR=yes ;; --no-orphan-check) NO_ORPHAN_CHECK=yes ;; *) arg "$1" && RMNAME+=($1) || { msgerr "Invalid option!"; exit 1; } ;; esac shift done fi } main() { parse_options "$@" # disable colour if [ "$NOCOLOR" ]; then nocolor fi # show help page if [ "$SHOWHELP" ]; then help exit 0 fi ### CHECK FOR ROOT ACCESS ### needroot "Removing 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 ${YELLOW}/tmp/spkg.lock${CRESET} if no install/remove package process running." exit 1 fi for pkg in ${RMNAME[@]}; do if [ ! -d $INDEX_DIR/$pkg ]; then msg "Package ${RED}$pkg${CRESET} not installed." else getoldname $pkg ### GET NAME, VERSION, RELEASE FROM INSTALLED PACKAGE DATABASE ### removepkg $pkg ### REMOVE PACKAGE ### fi done ### 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 "$@"