#!/bin/sh # # scratchpkg # # Copyright (c) 2018 by Emmett1 (emmett1.2miligrams@gmail.com) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # trap "interrupted" 1 2 3 15 export LC_ALL=C interrupted() { echo ret 1 } msg() { echo "==> $1" } msg2() { echo " -> $1" } msgerr() { echo "==> ERROR: $1" >&2 } msgwarn() { echo "==> WARNING: $1" >&2 } help() { cat << EOF Usage: $(basename $0) [ ] Options: -h, --help show this help message -v, --verbose print removed files --root= remove package from custom root directory EOF } extract_opts() { while [ "$1" ]; do case $1 in --*) opts="$opts $1";; -*) char=${#1}; count=1 while [ "$count" != "$char" ]; do count=$((count+1)) opts="$opts -$(echo $1 | cut -c $count)" done;; *) opts="$opts $1" esac shift done echo $opts } parse_opts() { if [ -z "$1" ]; then SHOWHELP=yes else while [ "$1" ]; do case $1 in -h | --help) SHOWHELP=yes ;; -v | --verbose) VERBOSE_REMOVE="-v" ;; --root=*) ROOT_DIR="${1#*=}" ;; -*) msg "Invalid option: ($1)"; exit 1 ;; *) RMNAME=$1 ;; esac shift done fi } ret() { # remove lock file on exit rm -f "$ROOT_DIR/$LOCK_FILE" exit $1 } isinstalled() { if [ -s "$ROOT_DIR/$PKGDB_DIR/$1" ]; then return 0 else return 1 fi } command -v pkgadd >/dev/null 2>&1 || { msgerr "'pkgadd' not found in \$PATH!" exit 1 } parse_opts $(extract_opts "$@") PKGDB_DIR="$(pkgadd --print-dbdir)" PKGDB_DIR="${PKGDB_DIR##/}" # remove leading / PKGDBPERMS_DIR="$PKGDB_DIR.perms" LOCK_FILE="var/lib/scratchpkg/spkg.lock" # show help page [ "$SHOWHELP" ] || [ -z "$RMNAME" ] && { help exit 0 } # check for root access [ "$(id -u)" = "0" ] || { echo "Removing package need root access!" exit 1 } # check for lock file [ -f "$ROOT_DIR/$LOCK_FILE" ] && { msgerr "Cannot install/remove package simultaneously." msgerr "remove '$ROOT_DIR/$LOCK_FILE' if no install/remove package process running." exit 1 } touch "$ROOT_DIR/$LOCK_FILE" 2>/dev/null || { msgerr "Cannot create lock file in '$ROOT_DIR/$LOCK_FILE'" exit 1 } if ! isinstalled "$RMNAME"; then msgerr "Package '$RMNAME' not installed." ret 1 fi name=$RMNAME version=$(head -n1 $ROOT_DIR/$PKGDB_DIR/$name | awk '{print $1}') release=$(head -n1 $ROOT_DIR/$PKGDB_DIR/$name | awk '{print $2}') if [ -z "$version" ] && [ -z "$release" ]; then msgerr "Package '$RMNAME' is not installed but exists in database." ret 1 fi tail -n+2 "$ROOT_DIR/$PKGDB_DIR"/$name | tac | while read -r line; do case $line in */) grep "^$line$" "$ROOT_DIR/$PKGDB_DIR"/* 2>/dev/null | grep -qv "$ROOT_DIR/$PKGDB_DIR"/$name: || rmdir $([ "$VERBOSE_REMOVE" ] && echo -v) "$ROOT_DIR/$line";; *) rm $([ "$VERBOSE_REMOVE" ] && echo -v) "$ROOT_DIR/$line";; esac done # remove from database rm -f "$ROOT_DIR/$PKGDB_DIR/$name" rm -f "$ROOT_DIR/$PKGDBPERMS_DIR/$name" # running ldconfig if [ -x "$ROOT_DIR"/sbin/ldconfig ]; then "$ROOT_DIR"/sbin/ldconfig -r "$ROOT_DIR"/ fi ret 0