diff --git a/INSTALL.sh b/INSTALL.sh
index 59c90c3..92d273e 100755
--- a/INSTALL.sh
+++ b/INSTALL.sh
@@ -16,7 +16,8 @@ install -dm777 ${DESTDIR}${CACHE_DIR}/packages
install -dm777 ${DESTDIR}${CACHE_DIR}/sources
install -dm777 ${DESTDIR}${CACHE_DIR}/work
-install -m755 xchroot revdep pkgadd pkgdel pkgbuild pkgquery scratch updateconf ${DESTDIR}${BINDIR}
+install -m755 xchroot revdep pkgadd pkgdel pkgbuild pkgquery scratch updateconf \
+ pkgbase pkgdepends pkgrebuild pkgfix portcreate ${DESTDIR}${BINDIR}
install -m644 scratchpkg.conf scratchpkg.repo scratchpkg.alias ${DESTDIR}${CONFDIR}
install -m644 revdep.conf ${DESTDIR}${REVDEPCONF}
diff --git a/pkgbase b/pkgbase
new file mode 100755
index 0000000..d217ed8
--- /dev/null
+++ b/pkgbase
@@ -0,0 +1,54 @@
+#!/bin/sh
+#
+# script to remove all packages other than base and any user input
+#
+
+parseopt() {
+ while [ "$1" ]; do
+ case $1 in
+ -n) dryrun=1;;
+ -y) yes=$1;;
+ -h) printhelp; exit 0;;
+ *) pkg="$pkg $1"
+ esac
+ shift
+ done
+}
+
+printhelp() {
+ cat << EOF
+Usage:
+ $(basename $0) [options] [packages]
+
+Options:
+ -n dry-run
+ -y dont ask user confirmation
+ -h print this help msg
+
+EOF
+}
+
+parseopt "$@"
+
+echo "Calculate packages to keep..."
+keep=$(scratch deplist base $pkg | awk '{print $2}')
+
+echo "Calculate selected packages to remove..."
+for pkg in $(scratch installed | awk '{print $1}'); do
+ echo $keep | tr ' ' '\n' | grep -qx $pkg || {
+ remove="$remove $pkg"
+ }
+done
+
+[ "$remove" ] && {
+ [ "$dryrun" = 1 ] && {
+ for i in $remove; do
+ echo "remove: $i..."
+ done
+ echo "This is dry-run, no real action is run!"
+ } || {
+ scratch remove $yes $remove
+ }
+}
+
+exit $?
diff --git a/pkgdepends b/pkgdepends
new file mode 100755
index 0000000..b422e2d
--- /dev/null
+++ b/pkgdepends
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+#
+# script to check dependencies
+#
+
+get_libpath() {
+ ldd $1 2>/dev/null | grep $2 | awk '{print $3}'
+}
+
+scratch files $1 | while read -r line; do
+ case $line in
+ usr/share/gir-1.0/*.gir) extra_dep="$extra_dep gobject-introspection";;
+ usr/share/vala/vapi/*.vapi) extra_dep="$extra_dep vala";;
+ esac
+ case $line in
+ */) continue;;
+ esac
+ case "$(file -bi /$line)" in
+ *application/x-sharedlib* | *application/x-executable* | *application/x-pie-executable*)
+ for NEEDED in $(objdump -x /$line | grep NEEDED | awk '{print $2}'); do
+ case $NEEDED in
+ libc.so|libc.so.6) continue;;
+ esac
+ [ "$NEEDED" ] || continue
+ [ -f /"$line" ] || continue
+ libs=$(get_libpath /$line $NEEDED)
+ [ "$libs" ] || continue
+ if ! echo $all_libs | grep -qw $libs; then
+ pkg=$(scratch provide $libs$ | awk '{print $1}' | head -n1)
+ case $pkg in
+ $1|gcc|glibc|musl) continue;;
+ esac
+ [ "$pkg" ] || continue
+ if ! echo $all_pkgs | grep -qw $pkg; then
+ echo $pkg
+ all_pkgs="$all_pkgs $pkg"
+ unset pkg
+ fi
+ all_libs="$all_libs $libs"
+ unset libs
+ fi
+ done ;;
+ esac
+ [ "$extra_dep" ] && {
+ for e in $extra_dep; do
+ if ! echo $all_pkgs | grep -qw $e; then
+ echo $e
+ all_pkgs="$all_pkgs $e"
+ fi
+ done
+ }
+done
+
+exit 0
diff --git a/pkgfix b/pkgfix
new file mode 100755
index 0000000..2e0f37c
--- /dev/null
+++ b/pkgfix
@@ -0,0 +1,140 @@
+#!/bin/sh
+#
+# Copyright (c) 2019 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 .
+#
+#
+# script to detect broken kernel modules after kernel update
+# need to use with 'scratchpkg'
+#
+
+export LANG=C
+
+get_perlmodules() {
+ command -v perl >/dev/null || return
+ perlpath=$(dirname $(perl -V:sitearch | grep -o "'.*'" | sed "s/'//g"))
+ for i in $(dirname $perlpath)/*; do
+ [ "$perlpath" = "$i" ] && continue
+ brokenpkg="$brokenpkg $(scratch provide $i/$ | awk '{print $1}')"
+ done
+}
+
+get_modules() {
+ [ -f /lib/modules/KERNELVERSION ] || return
+ KERVER=$(cat /lib/modules/KERNELVERSION)
+ for i in /lib/modules/*; do
+ case $i in
+ /lib/modules/KERNELVERSION|/lib/modules/$KERVER) continue ;;
+ esac
+ brokenpkg="$brokenpkg $(scratch provide $i/$ | awk '{print $1}')"
+ done
+}
+
+get_rubygem() {
+ command -v gem >/dev/null || return
+ gempath=$(gem env gemdir)
+ for i in $(dirname $gempath)/*; do
+ [ "$gempath" = "$i" ] && continue
+ brokenpkg="$brokenpkg $(scratch provide $i/$ | awk '{print $1}')"
+ done
+}
+
+sort_modules() {
+ for all in $(scratch deplist $brokenpkg | cut -d ' ' -f2); do
+ for r in $brokenpkg; do
+ if [ $r = $all ]; then
+ if [ -z "$order" ]; then
+ order="$all"
+ else
+ order="$order $all"
+ fi
+ break
+ fi
+ done
+ done
+}
+
+confirm() {
+ printf "$1 (Y/n) "
+ read -r response
+ case "$response" in
+ [Nn][Oo]|[Nn]) echo "$2"; return 2 ;;
+ *) : ;;
+ esac
+ return 0
+}
+
+usage() {
+ cat << EOF
+Usage:
+ $(basename $0) [options]
+
+Options:
+ -r rebuild & reinstall broken package
+ -y dont ask user confirmation to rebuild package (use with -r)
+ -h print this help message
+
+EOF
+}
+
+parse_opt() {
+ while [ "$1" ]; do
+ case $1 in
+ -r) REBUILD=1 ;;
+ -y) YES=1 ;;
+ -h) usage; exit 0 ;;
+ *) echo "Invalid option ($1)"; exit 1 ;;
+ esac
+ shift
+ done
+}
+
+parse_opt $@
+
+if [ "$REBUILD" ] && [ "$(id -u)" != 0 ]; then
+ echo "Rebuild broken packages required root!"
+ exit 1
+fi
+
+get_modules
+get_perlmodules
+get_rubygem
+
+if [ "$brokenpkg" ]; then
+ sort_modules
+else
+ echo "No broken packages found."
+ exit 0
+fi
+
+if [ "$REBUILD" = 1 ]; then
+ [ "$YES" ] || {
+ echo
+ echo "Package will be rebuild & reinstall by this order:"
+ echo " $order"
+ echo
+ confirm "Continue rebuild & reinstall broken packages?" "Operation cancelled."
+ }
+ for p in $order; do
+ scratch build -f $p && scratch install -r $p || exit 1
+ done
+else
+ echo "Broken packages:"
+ for p in $order; do
+ echo " $p"
+ done
+fi
+
+exit 0
diff --git a/pkgrebuild b/pkgrebuild
new file mode 100755
index 0000000..30f778d
--- /dev/null
+++ b/pkgrebuild
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# script to rebuild base packages in right toolchain order
+#
+
+LIST="/tmp/$(basename $0)-list"
+touch $LIST
+
+TOOLCHAIN="linux-api-headers glibc-pass1 binutils-pass1 gcc binutils glibc"
+
+#scratch sync || exit 1
+
+for tc in $TOOLCHAIN; do
+ if [ ! $(grep -x $tc $LIST) ]; then
+ pkgname="$(echo $tc | sed 's/-pass1//')"
+ scratch build -f $pkgname || exit 1
+ echo $tc >> $LIST
+ scratch install -r $pkgname --no-backup || exit 1
+ fi
+done
+
+for pkg in $(scratch deplist base | awk '{print $2}'); do
+ case $pkg in
+ linux-api-headers|musl|gcc|binutils|glibc) continue;;
+ esac
+ if [ ! $(grep -x $pkg $LIST) ]; then
+ scratch build -f $pkg || exit 1
+ echo $pkg >> $LIST
+ scratch install -r $pkg --no-backup || exit 1
+ fi
+done
+
+exit 0
diff --git a/portcreate b/portcreate
new file mode 100755
index 0000000..a1b6068
--- /dev/null
+++ b/portcreate
@@ -0,0 +1,48 @@
+#!/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 .
+#
+
+if [ -d "$1" ]; then
+ echo "ERROR: Directory '$1' already exist!"
+ exit 1
+else
+ mkdir "$1"
+ echo "# description :
+# homepage :
+# maintainer :
+# depends :
+
+name=$1
+version=
+release=1
+options=\"\"
+noextract=\"\"
+backup=\"\"
+source=\"\"
+
+build() {
+ cd \$name-\$version
+ ./configure --prefix=/usr
+ make
+ make DESTDIR=\$PKG install
+}" > "$1"/spkgbuild
+ echo "Template port have created for '$1'."
+fi
+
+exit 0
diff --git a/xchroot b/xchroot
index 52cdaca..dd9d958 100755
--- a/xchroot
+++ b/xchroot
@@ -1,4 +1,7 @@
#!/bin/sh
+#
+# script to enter chroot
+#
printhelp() {
cat << EOF
@@ -14,6 +17,13 @@ EOF
msgerr() {
echo "ERROR: $*"
}
+
+unmount() {
+ while true; do
+ mountpoint -q $1 || break
+ umount $1 2>/dev/null
+ done
+}
[ "$(id -u)" = "0" ] || {
msgerr "$(basename $0) need root access!"
@@ -78,13 +88,13 @@ retval=$?
mv $TARGET/etc/resolv.conf.tmp $TARGET/etc/resolv.conf
}
-umount -l $TARGET/dev/pts
-umount -l $TARGET/dev
-umount -l $TARGET/run
-umount -l $TARGET/proc
+unmount $TARGET/dev/pts
+unmount $TARGET/dev
+unmount $TARGET/run
+unmount $TARGET/proc
if [ -n "$EFI_SYSTEM" ]; then
- umount -l $TARGET/sys/firmware/efi/efivars
+ unmount $TARGET/sys/firmware/efi/efivars
fi
-umount -l $TARGET/sys
+unmount $TARGET/sys
exit $retval