mirror of
https://github.com/outbackdingo/scratchpkg.git
synced 2026-01-28 18:20:21 +00:00
499 lines
12 KiB
Bash
Executable File
499 lines
12 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
|
|
}
|
|
|
|
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 -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
|
|
|
|
sysusers
|
|
|
|
runhooks
|
|
|
|
msg "Successfully $oprmsg ${GREEN}$name-$version-$release${CRESET}."
|
|
|
|
# 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 -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
|
|
|
|
}
|
|
|
|
sysusers() {
|
|
|
|
if [ "$(ls $SYSUSERS_DIR/*.conf 2>/dev/null)" ]; then
|
|
for file in $(ls $SYSUSERS_DIR/*.conf); do
|
|
while read uid gid mode dir junk; do
|
|
# Ignore comments and blank lines
|
|
case "${uid}" in
|
|
""|\#*) continue ;;
|
|
esac
|
|
if [ -e "$dir" ]; then
|
|
if [ "$uid" != '-' ]; then
|
|
getent passwd $uid >/dev/null
|
|
if [[ "$?" = 0 ]]; then
|
|
chown "$uid" "$dir"
|
|
fi
|
|
fi
|
|
if [ "$gid" != '-' ]; then
|
|
getent group $gid >/dev/null
|
|
if [[ "$?" = 0 ]]; then
|
|
chgrp "$gid" "$dir"
|
|
fi
|
|
fi
|
|
if [ "$mode" != '-' ]; then
|
|
chmod "$mode" "$dir"
|
|
fi
|
|
fi
|
|
done < "$file"
|
|
done
|
|
fi
|
|
|
|
}
|
|
|
|
help() {
|
|
|
|
cat << EOF
|
|
Usage:
|
|
installpkg package.spkg.txz <options>
|
|
|
|
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) ;;
|
|
-*) for (( i=1; i<${#opt}; i++ )); do OPTS+=(-${opt:$i:1}); done ;;
|
|
*) OPTS+=($opt) ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
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() {
|
|
|
|
extract_opt $@
|
|
parse_opts ${OPTS[@]}
|
|
|
|
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 "$@"
|