mirror of
https://github.com/outbackdingo/scratchpkg.git
synced 2026-02-05 08:28:00 +00:00
526 lines
11 KiB
Bash
Executable File
526 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
spkglock() {
|
|
|
|
if [ ! -f /tmp/spkg.lock ]; then
|
|
touch /tmp/spkg.lock
|
|
else
|
|
rm /tmp/spkg.lock
|
|
fi
|
|
}
|
|
|
|
installpkg() {
|
|
|
|
msg "Installing ${color_green}$packagename${color_reset}..."
|
|
|
|
# noextract file into system
|
|
for noextr in ${NO_EXTRACT[@]}; do
|
|
excludefile+=(--exclude=$noextr)
|
|
done
|
|
|
|
#ignore dependency check
|
|
if [ ! "$IGNORE_DEP" ]; then
|
|
msg2 "Checking package dependencies..."
|
|
checkdeps
|
|
fi
|
|
|
|
#ignore conflict
|
|
if [ ! "$IGNORE_CONFLICT" ]; then
|
|
msg2 "Checking package/file conflict..."
|
|
checkconflict
|
|
checkpkgconflict
|
|
fi
|
|
|
|
# create lock file prevent simultaneous install package
|
|
spkglock
|
|
|
|
# source .install file inside package
|
|
if [ $(tar -tf "$PKGNAME" | grep -w ^".pkginstall") ]; then
|
|
source <(tar -xf "$PKGNAME" .pkginstall -O)
|
|
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..."
|
|
if [ "$VERBOSE_INSTALL" ]; then
|
|
tar --keep-directory-symlink --no-overwrite-dir -p -x -v -f $PKGNAME -C $ROOT_DIR --exclude=.pkginfo --exclude=.pkginstall --exclude=.pkgreadme ${excludefile[@]}
|
|
else
|
|
tar --keep-directory-symlink --no-overwrite-dir -p -x -f $PKGNAME -C $ROOT_DIR --exclude=.pkginfo --exclude=.pkginstall --exclude=.pkgreadme ${excludefile[@]}
|
|
fi
|
|
|
|
if [ $? != 0 ]; then
|
|
msgerr "Failed install ${color_red}$packagename${color_reset}."
|
|
pushd $ROOT_DIR
|
|
while IFS=' ' read -r line; do
|
|
rm_silent "$line" || rmdir_silent --ignore-fail-on-non-empty "$line"
|
|
done < <(tar -tf "$PKGNAME" --exclude=.pkginfo --exclude=.pkginstall --exclude=.pkgreadme ${excludefile[@]} | tac)
|
|
popd
|
|
spkglock
|
|
exit 1
|
|
fi
|
|
|
|
mkdir $INDEX_DIR/$name
|
|
tar -x -f $PKGNAME -C $INDEX_DIR/$name .pkginfo
|
|
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
|
|
|
|
msg "Successfully install ${color_green}$packagename${color_reset}."
|
|
|
|
if [ ! "$NO_POSTINSTALL" ] && [ ! "$UPGRADE_PKG" ]; then
|
|
run_postinstall
|
|
fi
|
|
|
|
if [ "$UPGRADE_PKG" ] && [ ! "$NO_POSTUPGRADE" ]; then
|
|
run_postupgrade
|
|
fi
|
|
|
|
restoreconf
|
|
|
|
case $PREINSTALL_STATUS in
|
|
OK) msg "preinstall : ${color_green}OK${color_reset}" ;;
|
|
KO) msg "preinstall : ${color_red}FAIL${color_reset}" ;;
|
|
esac
|
|
|
|
case $PREUPGRADE_STATUS in
|
|
OK) msg "preupgrade : ${color_green}OK${color_reset}" ;;
|
|
KO) msg "preupgrade : ${color_red}FAIL${color_reset}" ;;
|
|
esac
|
|
|
|
case $POSTINSTALL_STATUS in
|
|
OK) msg "postinstall : ${color_green}OK${color_reset}" ;;
|
|
KO) msg "postinstall : ${color_red}FAIL${color_reset}" ;;
|
|
esac
|
|
|
|
case $POSTUPGRADE_STATUS in
|
|
OK) msg "postupgrade : ${color_green}OK${color_reset}" ;;
|
|
KO) msg "postupgrade : ${color_red}FAIL${color_reset}" ;;
|
|
esac
|
|
|
|
if [ -f $INDEX_DIR/$name/readme ]; then
|
|
msg "This package has ${color_green}readme${color_reset}"
|
|
fi
|
|
|
|
# remove lock file
|
|
spkglock
|
|
}
|
|
|
|
checkdeps() {
|
|
|
|
for dep in ${depends[@]}; do
|
|
if [ ! -d $INDEX_DIR/$dep ]; then
|
|
MSGDEP+=($dep)
|
|
fi
|
|
done
|
|
|
|
if [ "${#MSGDEP[@]}" -gt 0 ]; then
|
|
msg "Missing dependencies:"
|
|
for msdp in ${MSGDEP[@]}; do
|
|
msg2 "$msdp"
|
|
done
|
|
exit 1
|
|
fi
|
|
|
|
}
|
|
|
|
checkpkgconflict() {
|
|
|
|
for pkg in ${conflict[@]}; do
|
|
if [ -d $INDEX_DIR/$pkg ]; then
|
|
msg "Conflict package!: ${color_yellow}$pkg${color_reset}"
|
|
PKG_CONFLICT=yes
|
|
fi
|
|
done
|
|
|
|
if [ "$PKG_CONFLICT" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
}
|
|
|
|
checkconflict() {
|
|
|
|
while IFS=' ' read -r line; do
|
|
pushd $ROOT_DIR
|
|
if [ -f "$line" ] || [ -L "$line" ]; then
|
|
fileconflict+=(${line})
|
|
fi
|
|
popd
|
|
done < <(tar -tf "$PKGNAME" --exclude=.pkginfo --exclude=.pkginstall --exclude=.pkgreadme ${excludefile[@]})
|
|
|
|
if [ "${#fileconflict[@]}" -gt 0 ]; then
|
|
msgerr "File conflict found:"
|
|
for fc in ${fileconflict[@]}; do
|
|
msg2 "$fc"
|
|
done
|
|
exit 1
|
|
fi
|
|
|
|
}
|
|
|
|
getname() {
|
|
|
|
name=$(tar xf $PKGNAME .pkginfo -O | grep ^name | cut -d " " -f3)
|
|
version=$(tar xf $PKGNAME .pkginfo -O | grep ^version | cut -d " " -f3)
|
|
release=$(tar xf $PKGNAME .pkginfo -O | grep ^release | cut -d " " -f3)
|
|
depends=$(tar xf $PKGNAME .pkginfo -O | grep ^depends | cut -d " " -f3-)
|
|
makedepends=$(tar xf $PKGNAME .pkginfo -O | grep ^makedepends | cut -d " " -f3-)
|
|
conflict=$(tar xf $PKGNAME .pkginfo -O | grep ^conflict | cut -d " " -f3-)
|
|
|
|
packagename=$name-$version-$release
|
|
|
|
}
|
|
|
|
getoldname() {
|
|
|
|
iname=$(cat $INDEX_DIR/$name/.pkginfo | grep ^name | cut -d " " -f3)
|
|
iversion=$(cat $INDEX_DIR/$name/.pkginfo | grep ^version | cut -d " " -f3)
|
|
irelease=$(cat $INDEX_DIR/$name/.pkginfo | grep ^release | cut -d " " -f3)
|
|
backup=$(cat $INDEX_DIR/$name/.pkginfo | grep ^backup | cut -d " " -f3-)
|
|
|
|
ipackagename=$iname-$iversion-$irelease
|
|
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
upgradepkg() {
|
|
|
|
if [ ! "$NO_BACKUP" ]; then
|
|
backupconf
|
|
fi
|
|
removepkg $name -id --no-preremove --no-postremove --no-orphan-check
|
|
NO_PREINSTALL=yes
|
|
NO_POSTINSTALL=yes
|
|
|
|
}
|
|
|
|
backupconf() {
|
|
|
|
pushd $ROOT_DIR
|
|
|
|
for bkp in ${backup[@]}; do
|
|
if [ -e $bkp ]; then
|
|
msg2 "Backup ${color_purple}$bkp${color_reset}"
|
|
cp $bkp $BACKUP_DIR
|
|
DONE_BACKUP=yes
|
|
fi
|
|
done
|
|
|
|
popd
|
|
}
|
|
|
|
restoreconf() {
|
|
|
|
if [ "$DONE_BACKUP" ]; then
|
|
|
|
pushd $ROOT_DIR
|
|
|
|
for b in ${backup[@]}; do
|
|
if [ -e $b ]; then
|
|
mkdir -p $REJECTED_DIR/${b%/*}
|
|
mv $b $REJECTED_DIR/$b
|
|
msg2 "Restore ${color_purple}$b${color_reset}"
|
|
mv $BACKUP_DIR/$(basename ${b}) $b
|
|
fi
|
|
done
|
|
|
|
popd
|
|
|
|
fi
|
|
}
|
|
|
|
checkoutdate() {
|
|
|
|
if [ $packagename = $ipackagename ]; then
|
|
msg "Package ${color_green}$packagename${color_reset} is up-to-date."
|
|
exit 1
|
|
fi
|
|
|
|
}
|
|
|
|
check_directory() {
|
|
|
|
for dir in $INDEX_DIR $BACKUP_DIR $REJECTED_DIR; do
|
|
if [ ! -d $dir ]; then
|
|
msgwarn "Directory ${color_yellow}$dir${color_reset} not exist."
|
|
DIR_ERROR=yes
|
|
elif [ ! -w $dir ]; then
|
|
msgwarn "Directory ${color_yellow}$dir${color_reset} not writable."
|
|
DIR_ERROR=yes
|
|
elif [ ! -x $dir ] || [ ! -r $1 ]; then
|
|
msgwarn "Directory ${color_yellow}$dir${color_reset} not readable."
|
|
DIR_ERROR=yes
|
|
fi
|
|
done
|
|
|
|
[ "$DIR_ERROR" ] && exit 1
|
|
|
|
}
|
|
|
|
run_preinstall() {
|
|
|
|
if [ "`type -t pre_install`" = "function" ]; then
|
|
msg "Running preinstall script..."
|
|
pre_install "$version" && PREINSTALL_STATUS=OK || PREINSTALL_STATUS=KO
|
|
fi
|
|
|
|
}
|
|
|
|
run_postinstall() {
|
|
|
|
if [ "`type -t post_install`" = "function" ]; then
|
|
msg "Running postinstall script..."
|
|
post_install "$version" && POSTINSTALL_STATUS=OK || POSTINSTALL_STATUS=KO
|
|
fi
|
|
}
|
|
|
|
run_preupgrade() {
|
|
|
|
if [ "`type -t pre_upgrade`" = "function" ]; then
|
|
msg "Running preupgrade script..."
|
|
pre_upgrade "$version" "$iversion" && PREUPGRADE_STATUS=OK || PREUPGRADE_STATUS=KO
|
|
fi
|
|
|
|
}
|
|
|
|
run_postupgrade() {
|
|
|
|
if [ "`type -t post_upgrade`" = "function" ]; then
|
|
msg "Running postupgrade script..."
|
|
post_upgrade "$version" "$iversion" && POSTUPGRADE_STATUS=OK || POSTUPGRADE_STATUS=KO
|
|
fi
|
|
|
|
}
|
|
|
|
checkneworphan() {
|
|
|
|
for md in ${makedepends[@]}; do
|
|
removemakedepends $md
|
|
done
|
|
if [ "${#saferemove[@]}" -gt 0 ]; then
|
|
msg "Package safe for remove:"
|
|
for saferem in ${saferemove[@]}; do
|
|
msg2 "$saferem"
|
|
done
|
|
fi
|
|
|
|
}
|
|
|
|
removemakedepends() {
|
|
|
|
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 ] && saferemove+=($1)
|
|
}
|
|
|
|
help() {
|
|
|
|
echo -e "Usage:"
|
|
echo -e "\t`basename $0` packagefile < options >"
|
|
echo -e ""
|
|
echo -e "Example:"
|
|
echo -e "\t`basename $0` foobar-1.0-1.spkg.txz -u --no-backup this will upgrade package foobar-1.0-1 without \n\t\t\t\t\t\t\t\tbackup its old configuration file"
|
|
echo -e ""
|
|
echo -e "Options:"
|
|
echo -e "\t-u,\t--upgrade update package"
|
|
echo -e "\t-r,\t--reinstall reinstall package"
|
|
echo -e "\t-id,\t--ignore-dependency ignore dependency"
|
|
echo -e "\t-ic,\t--ignore-conflict ignore conflict when installing package"
|
|
echo -e "\t-v,\t--verbose verbose install process"
|
|
echo -e "\t\t--no-preinstall skip preinstall script when build/install package"
|
|
echo -e "\t\t--no-postinstall skip postinstall script after install package"
|
|
|
|
}
|
|
|
|
parse_options() {
|
|
|
|
while [ "$1" ]; do
|
|
case $1 in
|
|
-u|--upgrade)
|
|
UPGRADE_PKG=yes
|
|
;;
|
|
-r|--reinstall)
|
|
REINSTALL_PKG=yes
|
|
;;
|
|
-id|--ignore-dependency)
|
|
IGNORE_DEP=yes
|
|
;;
|
|
-ic|--ignore-conflict)
|
|
IGNORE_CONFLICT=yes
|
|
;;
|
|
-v|--verbose)
|
|
VERBOSE_INSTALL=yes
|
|
;;
|
|
--no-preinstall)
|
|
NO_PREINSTALL=yes
|
|
;;
|
|
--no-postinstall)
|
|
NO_POSTINSTALL=yes
|
|
;;
|
|
--no-preupgrade)
|
|
NO_PREUPGRADE=yes
|
|
;;
|
|
--no-preupgrade)
|
|
NO_POSTUPGRADE=yes
|
|
;;
|
|
--no-backup)
|
|
NO_BACKUP=yes
|
|
;;
|
|
--no-color)
|
|
NO_COLOR=yes
|
|
;;
|
|
--no-orphan-check)
|
|
NO_ORPHAN_CHECK=yes
|
|
;;
|
|
*.spkg.txz)
|
|
[ -f $1 ] && PKGNAME=$1 || msg "${color_red}$1${color_reset} not exist."
|
|
;;
|
|
--root)
|
|
if [ ! "$2" ]; then
|
|
msg "Option '$1' require an argument (root path)."
|
|
exit 1
|
|
fi
|
|
ROOT="$2"
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
SHOW_HELP=yes
|
|
;;
|
|
*)
|
|
msg "Invalid option!"
|
|
exit 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
|
|
|
|
### SHOW HELP ###
|
|
if [ "$SHOW_HELP" ]; then
|
|
help
|
|
exit 0
|
|
fi
|
|
|
|
### CHECK FOR ROOT ACCESS ###
|
|
if [ "$UID" != "0" ]; then
|
|
msg "${color_red}Installing package need root access!${color_reset}"
|
|
exit 1
|
|
fi
|
|
|
|
check_directory
|
|
|
|
### CHECK FOR LOCK FILE ###
|
|
if [ -f /tmp/spkg.lock ]; then
|
|
msg "Cant install/remove package simultaneously."
|
|
msg "remove /tmp/spkg.lock if no install/remove package process running."
|
|
exit 1
|
|
fi
|
|
|
|
### NOT STATED PACKAGE ###
|
|
if [ -z $PKGNAME ]; then
|
|
msg "${color_red}Please state the package to install.${color_reset}"
|
|
exit 1
|
|
fi
|
|
|
|
### GET NAME, VERSION, RELEASE FROM PACKAGE ###
|
|
getname # get info from package
|
|
|
|
### IF INSTALLED & NO UPGRADE & NO REINSTALL ###
|
|
if [ -d $INDEX_DIR/$name ] && [ ! "$UPGRADE_PKG" ] && [ ! "$REINSTALL_PKG" ]; then
|
|
getoldname # get info from package index
|
|
msg "Package ${color_green}$ipackagename${color_reset} already installed."
|
|
exit 0
|
|
fi
|
|
|
|
### IF UPGRADE OR REINSTALL PACKAGE ###
|
|
if [ "$UPGRADE_PKG" ] || [ "$REINSTALL_PKG" ]; then
|
|
if [ ! -d $INDEX_DIR/$name ]; then
|
|
msg "Package ${color_red}$name${color_reset} is not installed."
|
|
exit 1
|
|
fi
|
|
getoldname
|
|
# UPGRADE PACKAGE
|
|
if [ "$UPGRADE_PKG" ]; then
|
|
checkoutdate
|
|
msg "Upgrading package: ${color_yellow}$ipackagename${color_reset} -> ${color_green}$packagename${color_reset}"
|
|
# REINSTALL PACKAGE
|
|
elif [ "$REINSTALL_PKG" ]; then
|
|
msg "Reinstall package ${color_green}$packagename${color_reset}."
|
|
fi
|
|
upgradepkg
|
|
fi
|
|
|
|
### INSTALL PACKAGE INTO SYSTEM ###
|
|
installpkg
|
|
|
|
# check orphan package (usually makedepends package)
|
|
if [ ! "$NO_ORPHAN_CHECK" ]; then
|
|
checkneworphan
|
|
fi
|
|
|
|
### RUN THINGS THAT NEED UPDATE AFTER INSTALL PACKAGE ###
|
|
updatesystemdb
|
|
|
|
### UPDATE INFO PAGES ###
|
|
for file in $(cat $INDEX_DIR/$name/.files); do
|
|
if [ $file = usr/share/info/ ]; then
|
|
updateinfopages
|
|
break
|
|
fi
|
|
done
|
|
|
|
exit 0
|
|
}
|
|
|
|
main "$@"
|