#!/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() { if [ "$UPGRADE_PKG" ]; then oprmsg=upgrade oprmsg2=Upgrading elif [ "$REINSTALL_PKG" ]; then oprmsg=reinstall oprmsg2=Reinstalling else oprmsg=install oprmsg2=Installing fi msg "$oprmsg2 ${GREEN}$name-$version-$release${CRESET}..." # noextract file into system for noextr in ${NO_EXTRACT[@]}; do excludefile+=(--exclude=$noextr) done #ignore conflict if [ ! "$IGNORE_CONFLICT" ]; then msg2 "Checking file conflict..." if [ "$UPGRADE_PKG" ] || [ "$REINSTALL_PKG" ]; then upcheckconflict else checkconflict fi fi # create lock file prevent simultaneous install package spkglock # source .install file inside package if [ ! "$REINSTALL_PKG" ]; then if [ $(tar -tf "$PKGNAME" | grep -x ".pkginstall") ]; then source <(tar -xf "$PKGNAME" .pkginstall -O) fi 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 msg2 "Extracting package..." installcmd() { tar --keep-directory-symlink --no-overwrite-dir -p -x -v -f $1 -C $ROOT_DIR --exclude=.pkginfo --exclude=.pkginstall --exclude=.pkgreadme ${excludefile[@]} } rm -f /tmp/spkginstall.$name LC_ALL= installcmd $PKGNAME | while IFS=' ' read line; do if [ "$line" = "${line%.*}.spkgnew" ]; then line=${line%.*} if [ "$UPGRADE_PKG" ] || [ "$REINSTALL_PKG" ]; then if [ ! -e ${ROOT_DIR}${line} ]; then mv ${ROOT_DIR}${line}.spkgnew ${ROOT_DIR}${line} fi else mv ${ROOT_DIR}${line}.spkgnew ${ROOT_DIR}${line} fi fi echo "$line" >> /tmp/spkginstall.$name done #if [ $? != 0 ]; then #msgerr "Failed install ${RED}$name-$version-$release${CRESET}." #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 msg2 "Removing old files..." removeoldfiles fi registerpkg if [ ! "$NO_POSTINSTALL" ] && [ ! "$UPGRADE_PKG" ]; then run_postinstall fi if [ "$UPGRADE_PKG" ] && [ ! "$NO_POSTUPGRADE" ]; then run_postupgrade fi case $PREINSTALL_STATUS in OK) msg2 "preinstall : ${GREEN}OK${CRESET}" ;; KO) msg2 "preinstall : ${RED}FAIL${CRESET}" ;; esac case $PREUPGRADE_STATUS in OK) msg2 "preupgrade : ${GREEN}OK${CRESET}" ;; KO) msg2 "preupgrade : ${RED}FAIL${CRESET}" ;; esac case $POSTINSTALL_STATUS in OK) msg2 "postinstall : ${GREEN}OK${CRESET}" ;; KO) msg2 "postinstall : ${RED}FAIL${CRESET}" ;; esac case $POSTUPGRADE_STATUS in OK) msg2 "postupgrade : ${GREEN}OK${CRESET}" ;; KO) msg2 "postupgrade : ${RED}FAIL${CRESET}" ;; esac if [ -f $INDEX_DIR/$name/.pkgreadme ]; then msg2 "This package has ${GREEN}readme${CRESET}" fi runhooks msg "Successfully $oprmsg." # remove lock file spkglock } removeoldfiles() { TMP_TARLIST="/tmp/spkginstall.$name" grep -v '/$' $INDEX_DIR/$name/.files | while IFS=' ' 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 '/$') } registerpkg() { rm -fr $INDEX_DIR/$name mkdir $INDEX_DIR/$name tar -x -f $PKGNAME -C $INDEX_DIR/$name .pkginfo cat /tmp/spkginstall.$name > $INDEX_DIR/$name/.files rm -f /tmp/spkginstall.$name #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 } checkconflict() { while IFS=' ' read -r line; do pushd $ROOT_DIR if [ "$line" = "${line%.*}.spkgnew" ]; then line=${line%.*} fi 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 [ "$line" = "${line%.*}.spkgnew" ]; then line=${line%.*} fi 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 } checkoutdate() { if [ "$version-$release" = "$iversion-$irelease" ]; then msg "Package ${GREEN}$name${CRESET} is up-to-date." exit 0 fi } run_preinstall() { if [ "`type -t pre_install`" = "function" ]; then msg2 "Running preinstall script..." pre_install "$version" && PREINSTALL_STATUS=OK || PREINSTALL_STATUS=KO fi } run_postinstall() { if [ "`type -t post_install`" = "function" ]; then msg2 "Running postinstall script..." post_install "$version" && POSTINSTALL_STATUS=OK || POSTINSTALL_STATUS=KO fi } run_preupgrade() { if [ "`type -t pre_upgrade`" = "function" ]; then msg2 "Running preupgrade script..." pre_upgrade "$version" "$iversion" && PREUPGRADE_STATUS=OK || PREUPGRADE_STATUS=KO fi } run_postupgrade() { if [ "`type -t post_upgrade`" = "function" ]; then msg2 "Running postupgrade script..." post_upgrade "$version" "$iversion" && POSTUPGRADE_STATUS=OK || POSTUPGRADE_STATUS=KO 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 echo -e " ${BLUE}*${CRESET} $description" . $hook if [ "`type -t exechook`" = "function" ]; then exechook fi fi fi fi unset description operation target done fi } help() { cat << EOF Usage: installpkg package.spkg.txz Options: -u, --upgrade upgrade package -r, --reinstall reinstall package -d, --no-dep skip dependency check -c, --ignore-conflict ignore conflict when installing package -v, --verbose print files installed -h, --help show this help message --no-preinstall skip preinstall script before build/install package --no-postinstall skip postinstall script after install package --no-preupgrade skip preupgrade script before upgrade package --no-postupgrade skip postupgrade script after upgrade package --no-backup skip backup when upgrading package --no-orphan-check skip orphaned package check after install package --no-color disable colour for output Example: installpkg foobar-1.0-1.spkg.txz -uc --no-backup upgrade package foobar-1.0-1 without backup its old configuration files and skip conflict check EOF } extract_opt() { for opt in $@; do case $opt in --*=*) OPTS+=($opt) ;; --*) OPTS+=($opt) ;; -*) for (( i=1; i<${#opt}; i++ )); do OPTS+=(-${opt:$i:1}); done ;; *) OPTS+=($opt) ;; esac done echo "${OPTS[@]}" } parse_opts() { if [ -z "$1" ]; then SHOWHELP=yes else while [ "$1" ]; do case $1 in -u | --upgrade) UPGRADE_PKG=yes ;; -r | --reinstall) REINSTALL_PKG=yes ;; -d | --no-dep) IGNORE_DEP=yes ;; -c | --ignore-conflict) IGNORE_CONFLICT=yes ;; -v | --verbose) VERBOSE_INSTALL=yes ;; -h | --help) SHOWHELP=yes ;; --no-preinstall) NO_PREINSTALL=yes ;; --no-postinstall) NO_POSTINSTALL=yes ;; --no-preupgrade) NO_PREUPGRADE=yes ;; --no-postupgrade) NO_POSTUPGRADE=yes ;; --no-backup) NO_BACKUP=yes ;; --no-color) NOCOLOR=yes ;; *.spkg.txz) PKGNAME="$1" ;; *) msg "Invalid option! ($1)"; exit 1 ;; esac shift done fi } main() { parse_opts $(extract_opt $@) if [ -n "$PKGNAME" ]; then BASEPKGNAME=$(basename $PKGNAME) fi # disable colour if [ "$NOCOLOR" ]; then nocolor fi # show help page if [ "$SHOWHELP" ] || [ -z "$PKGNAME" ]; then help exit 0 fi # check existence of package file if [ ! -f $PKGNAME ]; then msgerr "Package ${RED}$1${CRESET} not exist!" exit 1 fi echo -ne "Loading $BASEPKGNAME...\033[0K\r" # check integrity of package if ! tar -tf $PKGNAME &>/dev/null; then msgerr "Package ${RED}$1${CRESET} is corrupted!" exit 1 fi echo -ne "\033[0K" # 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 ${YELLOW}/tmp/spkg.lock${CRESET} if no install/remove package process running." exit 1 fi name=$(echo $BASEPKGNAME | sed 's/.spkg.txz//' | rev | cut -d - -f 3- | rev) version=$(echo $BASEPKGNAME | sed 's/.spkg.txz//' | rev | cut -d - -f 2 | rev) release=$(echo $BASEPKGNAME | sed 's/.spkg.txz//' | rev | cut -d - -f 1 | rev) # get package information if installed if [ -e $INDEX_DIR/$name/.pkginfo ]; then iname=$(installed_pkg_info name $name) iversion=$(installed_pkg_info version $name) irelease=$(installed_pkg_info release $name) ALREADYINSTALLED=yes fi if [ "$ALREADYINSTALLED" = "yes" ] && [ ! "$UPGRADE_PKG" ] && [ ! "$REINSTALL_PKG" ]; then msg "Package '$name' already installed. (${GREEN}$iversion-$irelease${CRESET})" exit 0 fi ### IF UPGRADE OR REINSTALL PACKAGE ### if [ "$UPGRADE_PKG" ] || [ "$REINSTALL_PKG" ]; then if [ "$ALREADYINSTALLED" != "yes" ]; then msgerr "Package ${RED}$name${CRESET} not installed." exit 1 fi # UPGRADE PACKAGE if [ "$UPGRADE_PKG" ]; then checkoutdate fi fi ### INSTALL PACKAGE INTO SYSTEM ### installpkg # running ldconfig if [ -x /sbin/ldconfig ]; then /sbin/ldconfig fi exit 0 } main "$@"