--- /dev/null
+#!/bin/sh
+
+warn() {
+ echo $* 1>&2
+}
+
+run_ldconfig() {
+ if [ $(id -u) -eq 0 ]; then
+ if [ ! -d $1/etc ]; then
+ warn "no etc directory in $1, skipping ldconfig"
+ elif [ -f $1/sbin/ldconfig ]; then
+ $1/sbin/ldconfig -r ${1:-/}
+ elif [ -f /sbin/ldconfig ]; then
+ /sbin/ldconfig -r ${1:-/}
+ else
+ true
+ fi
+ fi
+}
+
+changeall() {
+ for pkgid in $(zpm list -s $1); do
+ zpm pkg $pkgid status=$2
+ done
+}
+
+die() {
+ if [ $# -gt 0 ]; then
+ echo $* 1>&2
+ fi
+ zpm log -i -a 'aborted install' -t "$pkgid" "$*"
+ changeall installing
+ changeall removing installed
+ exit 1
+}
+
+current_version() (
+ zpm list -s installed $(zpm parse -n $1)
+)
+
+maybe_run() (
+ phase=$1
+ pkgid=$2
+ run=${3:-0}
+ current=$4
+
+ if [ $run -gt 0 ]; then
+ zpm script -p $phase $pkgid $current
+ rv=$?
+ if [ $rv -ne 0 ]; then
+ warn "$phase script for $pkgid failed"
+ exit $rv
+ fi
+ else
+ if zpm script -Fql -p $phase $pkgid; then
+ zpm note -e -p $pkgid -m "$phase script not run"
+ fi
+ fi
+)
+
+validity_check() {
+ rv=0
+ # check if we're installing something already
+ var=$(zpm list -s installing | wc -l)
+ if [ $var -gt 0 ]; then
+ zpm list -v -f $localdb -s installing
+ warn "already ($localdb) installing $var package(s)"
+ rv=1
+ fi
+ var=$(zpm list -s removing | wc -l)
+ if [ $var -gt 0 ]; then
+ zpm list -v -f $localdb -s removing
+ warn "already ($localdb) removing $var package(s)"
+ rv=1
+ fi
+ var=$(zpm list -s updating | wc -l)
+ if [ $var -gt 0 ]; then
+ zpm list -v -f $localdb -s updating
+ warn "already ($localdb) updating $var package(s)"
+ rv=1
+ fi
+ if [ $rv -ne 0 ]; then
+ die "aborting update"
+ fi
+}
+
+dryrun=0
+verbose=0
+runscripts=1
+runconfigure=1
+absorb=0
+overwrite=0
+syncopts=''
+
+packagepath="/var/lib/zpm/packages"
+to_install=
+to_remove=
+to_update=
+install_for_libs=''
+
+backup=0
+ignorelibdeps=0
+justlist=0
+
+# TODO option to attempt to resume an ongoing install
+# zpm-install [-SCn] [ -d localdb ] [ -f pkgfile ] [ -R installroot ] pkgstr ...
+while getopts f:d:R:nSCvAObBL opt; do
+ case $opt in
+ f) pkgfile="$OPTARG" ;;
+ d) localdb="$OPTARG" ;;
+ P) packagepath="$OPTARG" ;;
+ D) packagepath="$OPTARG:$packagepath" ;;
+ R) rootdir="$OPTARG" ;;
+ S) runscripts=0 ;;
+ C) runconfigure=0 ;;
+ A) absorb=1; syncopts="${syncopts} -A" ;;
+ O) overwrite=1; syncopts="${syncopts} -O" ;;
+ n) dryrun=1 ;;
+ v) verbose=1 ;;
+ b) backup=1 ;;
+ B) backup=0 ;;
+ L) ignorelibdeps=1 ;;
+ l) justlist=1 ;;
+ *) die "usage ..." ;;
+ esac
+done
+shift $(( OPTIND - 1))
+
+ZPMDB=${localdb:-${ZPMDB:-/var/lib/zpm/local.db}}
+export ZPMDB
+# create the localdb if needed
+zpm init $ZPMDB
+
+zpm test -v "$ZPMDB" || die "$ZPMDB is not a zpm database"
+
+validity_check
+
+for op in "$@"; do
+ case "$op" in
+ -*) pkgid=$(zpm findpkg -I "${op#-}")
+ if [ -n "$pkgid" ]; then
+ to_remove="$to_remove $pkgid"
+ fi
+ # else warn not installed
+ ;;
+ +*) pkg=${op#+}
+ search="$search $pkg"
+ ;;
+ *:*) pkg=${op%:*}
+ file=${op#*:}
+ pkgid=$(zpm findpkg -f $file $pkg)
+ if [ -n $pkgid ]; then
+ merge="$merge $pkgid:$file"
+ else
+ die "can't find $pkg in $file"
+ fi
+ ;;
+ *) search="$search $op"
+ ;;
+ esac
+done
+
+search=$(echo $search)
+
+ebail=0
+
+if [ $ignorelibdeps -eq 1 ]; then
+ merge=$(zpm search -iIO $search)
+else
+ merge=$(zpm search -iIO -l $search)
+fi
+
+if [ $? -ne 0 ]; then
+ warn "unmet packages or dependencies, or errors"
+ exit 1
+fi
+
+installset=
+for mergepkg in $merge; do
+ pkgid=${mergepkg%%:*}
+ installset="$installset $pkgid"
+done
+installset=$(printf "%s\n" $installset | sort -u)
+
+# TODO check for downgrade
+
+# fixup package
+nlist=
+nfound=
+baddl=
+for mergepkg in $merge; do
+ pkgid=${mergepkg%:*}
+ repofile=${mergepkg#*:}
+ if [ ${repofile##*.} = 'repo' ]; then
+ status=$(zpm pkg -f $repofile $pkgid status)
+ reponame=$(basename $repofile .repo)
+ if [ "$status" != 'merged' ]; then
+ repodir=$(dirname $repofile)
+ zpmfile=$repodir/$reponame/$pkgid.zpm
+ if [ -f "$zpmfile" ]; then
+ nlist="$nlist $pkgid:$zpmfile"
+ continue
+ else
+ echo downloading $zpmfile
+ zpm repo fetch $reponame $pkgid
+ if [ -f "$zpmfile" ]; then
+ nlist="$nlist $pkgid:$zpmfile"
+ else
+ baddl="$baddl $reponame:$pkgid"
+ fi
+ fi
+ fi
+ else
+ nlist="$nlist $mergepkg"
+ fi
+done
+merge=${nlist#' '}
+baddl=${baddl#' '}
+
+if [ -n "$baddl" ]; then
+ printf 'unable to download: %s\n' $baddl
+ die
+fi
+
+if [ $justlist -eq 1 ]; then
+ for package in $merge; do
+ pkgid=${package%:*}
+ printf 'install %s\n' $pkgid
+ done
+ for pkgid in $to_remove; do
+ printf 'remove %s\n' $pkgid
+ done
+fi
+
+if [ -z "$merge" ] && [ -z "$to_remove" ]; then
+ echo nothing to do
+ exit 0
+fi
+
+echo "merge: $merge"
+
+# finally, merge everything
+for mergepkg in $merge; do
+ pkgid=${mergepkg%:*}
+ pkgfile=${mergepkg#*:}
+
+ # we could have found the package already in the localdb
+ # in which case, we don't need to merge it
+ # TODO check for symlinks?
+ if [ $pkgfile != $ZPMDB ]; then
+ echo merging $pkgfile $pkgid
+ zpm merge -Fuv -f "$pkgfile" $pkgid
+ fi
+ to_install="$to_install $pkgid"
+done
+
+to_install=${to_install#' '}
+
+echo "installing: $to_install"
+
+# absorb anything we're updating or removing, if absorb flag set
+
+if [ -n "$to_install" ]; then
+ for pkgid in $to_install; do
+ current=$(current_version $pkgid)
+ maybe_run pre-install $pkgid $runscripts $current || die
+ done
+fi
+
+if [ -n "$to_remove" ]; then
+ for pkgid in $to_remove; do
+ maybe_run pre-remove $pkgid $runscripts || die
+ done
+fi
+
+if [ -n "$to_install" ]; then
+ for pkgid in $to_install; do
+ zpm pkg $pkgid status=installing
+ done
+fi
+
+if [ -n "$to_remove" ]; then
+ for pkgid in $to_remove; do
+ zpm pkg $pkgid status=removing
+ done
+fi
+
+if [ -n "$rootdir" ]; then
+ ZPM_ROOT_DIR=$rootdir
+ export ZPM_ROOT_DIR
+ : rootdir=${rootdir%%/}
+fi
+
+if [ $dryrun -gt 0 ]; then
+ runscripts=0 # we don't want to run post scripts on a dry-run
+ syncopts="$syncopts -n"
+fi
+
+if [ $verbose -gt 0 ]; then
+ syncopts="${syncopts} -v"
+else
+ # force -v during development
+ syncopts="${syncopts} -v"
+fi
+
+if [ $dryrun -eq 0 ] && [ $backup -eq 1 ]; then
+ true
+ #zpm absorb -s updating
+ #zpm absorb -s removing
+fi
+
+zpm syncfs $syncopts || die 'zpm-syncfs failed';
+
+if [ -n "$to_remove" ]; then
+ for pkgid in $to_remove; do
+ maybe_run post-remove $pkgid $runscripts
+ done
+fi
+
+changeall removing removed
+
+echo running ldconfig
+run_ldconfig $rootdir
+
+if [ -n "$to_install" ]; then
+ for pkgid in $to_install; do
+ package=$(zpm parse -n $pkgid)
+ current=$(zpm list -s installed "$package")
+
+ maybe_run post-install $pkgid $runscripts $current
+
+ if [ -n "$current" ]; then
+ zpm pkg $pkgid status=installed :$current status=updated
+ else
+ zpm pkg $pkgid status=installed
+ fi
+
+ maybe_run configure $pkgid $runconfigure
+ done
+fi
+echo install complete