#!/bin/sh warn() { echo $* 1>&2 } die() { echo $* 1>&2 zpm log -i -a 'aborting install' -t "$pkgid" "$*" exit 1 } changeall() { for pkgid in $(zpm list -s $1); do zpm pkg $pkgid status=$2 done } dryrun=0 verbose=0 runscripts=1 runconfigure=1 absorb=0 overwrite=0 syncopts='' installall=0 mergefiles=0 # zpm-install [-SCn] [ -d localdb ] [ -f pkgfile ] [ -R installroot ] pkgstr ... while getopts f:d:R:nSCvAOaF opt; do case $opt in f) pkgfile="$OPTARG" ;; F) mergefiles=1 ;; d) localdb="$OPTARG" ;; R) rootdir="$OPTARG" ;; S) runscripts=0 ;; C) runconfigure=0 ;; A) absorb=1; syncopts="${syncopts} -A" ;; a) installall=1; ;; O) overwrite=1; syncopts="${syncopts} -O" ;; n) dryrun=1 ;; v) verbose=1 ;; *) die "usage ..." ;; esac done shift $(( OPTIND - 1)) if [ -z "$1" ]; then installall=1 fi if [ -z "$pkgfile" ]; then pkgfile=$ZPM_PACKAGE_FILE fi if [ $installall -eq 1 ]; then pkglist="$(zpm list -f $pkgfile)" else pkglist=$(zpm findpkg -f $pkgfile "$1") fi if [ $verbose -gt 0 ]; then echo $pkglist fi if [ -z "$pkglist" ]; then die "$0 no packages specified for install" fi if [ "$idempotent" = 1 ]; then idempotent='or ignore' fi if [ -n "$rootdir" ]; then : rootdir=${rootdir%%/} fi if [ -z "$localdb" ]; then localdb=${rootdir}/var/lib/zpm/local.db fi if [ ! -f "$localdb" ]; then if [ -n "$rootdir" ] && [ ! -d $rootdir ]; then mkdir $rootdir || die "can't create $rootdir: $!" fi for d in /var /var/lib /var/lib/zpm; do test -d $rootdir/$d || mkdir $rootdir/$d || die "can't create $rootdir/$d/: $!" done zpm init "$localdb" if [ $? -ne 0 ]; then die "aborting install" fi fi ZPMDB=$localdb export ZPMDB if [ -z "$ZPMDB" ]; then die "no local db" else #echo "localdb = $ZPMDB" true fi zpm test -v "$ZPMDB" || die "$ZPMDB is not a zpm database" # check if we're installing something already var=$(zpm list -f $localdb -s installing | wc -l) if [ $var -gt 0 ]; then zpm list -v -f $localdb -s installing die "already ($localdb) installing $var package(s)" fi # check if we're removing something already var=$(zpm list -f $localdb -s removing | wc -l) if [ $var -gt 0 ]; then zpm list -v -f $localdb -s removing die "already ($localdb) removing $var package(s)" fi var=$(zpm list -f $localdb -s updating | wc -l) if [ $var -gt 0 ]; then zpm list -v -f $localdb -s updating die "already ($localdb) updating $var package(s)" fi if [ -n "$rootdir" ]; then ZPM_ROOT_DIR="$rootdir" export ZPM_ROOT_DIR fi for pkgid in $pkglist; do curstatus=$(zpm pkg $pkgid status) if [ "$curstatus" = 'installed' ]; then die "$pkgid already installed" fi package=$(zpm parse -n $pkgid) current=$(zpm list -s installed "$package") if [ $runscripts -gt 0 ]; then # TODO run pre-upgrade script if needed # zpm runscript -p pre-upgrade $current $pkgid zpm script -f $pkgfile -p pre-install $pkgid $current if [ $? -ne 0 ]; then die "pre-install script for $pkgid failed" fi else if zpm script -f $pkgfile -Fql -p pre-install $pkgid; then zpm note -e -p $pkgid -m 'pre-install script not run' fi fi # remove the package if it exists. can't be in an installed # state, would have bailed above. So, if it exists, can only # be 'upgraded'. This should be fast, because we won't run # a garbage collect, so any possible duplicate files between # an upgraded or removed files, if they're there, won't need # to be merged. # only merge if localdb and pkgfile are different if [ "$pkgfile" != "$ZPMDB" ]; then zpm rmpackage $pkgid if [ $verbose -gt 0 ]; then echo merging $pkgid fi if [ $mergefiles -eq 1 ]; then zpm merge -u -F -f $pkgfile -s installing $pkgid else zpm merge -u -f $pkgfile -s installing $pkgid fi if [ $? -ne 0 ]; then die "merging $pkgid failed" fi else zpm pkg $pkgid status=installing fi zpm shell "$ZPMDB" "update packages set status='updating' where status='installed' and package in (select package from packages where status = 'installing')" done # do the sync #zpm shell $ZPMDB 'select * from install_status' 1>&2 if [ $dryrun -gt 0 ]; then syncopts="$syncopts -n" fi if [ $verbose -gt 0 ]; then syncopts="$syncopts -v" fi if [ "$pkgfile" != "$ZPMDB" ]; then syncopts="$syncopts -f $pkgfile" fi #zpm shell $ZPMDB 'select * from syncinfo' #zpm list -v zpm syncfs $syncopts syncrv=$? if [ $dryrun -gt 0 ]; then for pkgid in $pkglist; do zpm pkg $pkgid status=dryrun done fi if [ $syncrv -ne 0 ]; then zpm pkg $pkgid status=failed die 'zpm-syncfs failed'; fi if [ $(id -u) -eq 0 ]; then if [ ! -d $rootdir/etc ]; then warn "no etc directory in $rootdir, skipping ldconfig" elif [ -f $rootdir/sbin/ldconfig ]; then $rootdir/sbin/ldconfig -r ${rootdir:-/} elif [ -f /sbin/ldconfig ]; then /sbin/ldconfig -r ${rootdir:-/} else true fi fi for pkgid in $pkglist; do package=$(zpm parse -n $pkgid) current=$(zpm list -s updating "$package") if [ $runscripts -gt 0 ]; then zpm script -p post-install $pkgid $current else if zpm script -Fql -p post-install $pkgid; then zpm note -e -p $pkgid -m 'post-install script not run' fi fi if [ -n "$current" ]; then zpm pkg $pkgid status=installed :$current status=updated else zpm pkg $pkgid status=installed fi # TODO skip configure if not on a terminal, regardless of settings # TODO will need force option if [ $runconfigure -gt 0 ]; then zpm script -p configure $pkgid else if zpm script -Fql -p configure $pkgid; then zpm note -e -p $pkgid -m 'configure script not run' fi fi done changeall updating updated