--- /dev/null
+#!/bin/sh
+
+# control repositories
+
+# repo ...
+# add name <url>
+# del name
+# pri name <n>
+# list [-v ] [ name ... ]
+# note name <note>
+# url name [url]
+# packages [ name ... ] -- like zpm list
+# contents [ name ... ] -- like zpm contents
+# search [ name ] -- packages
+# push name ckagefile ...
+# pull name package ...
+# extract -- extract metadata from repo
+# json - extract metadata as json
+# setpkgurl packageid url
+# update - pull info from remote
+# gc [name] - run zpm gc on repo file
+
+chroot=1
+pkgroot=
+
+while getopts :R:d: opt; do
+ case $opt in
+ R) pkgroot="$OPTARG" ;;
+ d) ZPMDB="$OPTARG" ;;
+ esac
+done
+
+shift $((OPTIND - 1))
+
+for cf in /etc/zpmrc ~/.zpmrc ./.zpmrc; do
+ test -r $cf && . $cf
+done
+
+pkgroot=${pkgroot%/}
+
+: ${ZPMDB:=$pkgroot/var/lib/zpm/local.db}
+
+repodir=/var/lib/zpm/repo
+mkdir -p $repodir
+
+export ZPMDB
+
+warn() {
+ printf '%s:' "$0" 1>&2
+ printf ' %s' $* 1>&2
+ printf '\n' 1>&2
+ exit 1
+}
+
+die() {
+ printf '%s:' "$0" 1>&2
+ printf ' %s' $* 1>&2
+ printf '\n' 1>&2
+ exit 1
+}
+
+set -e
+zpm test -v $ZPMDB
+
+if [ $# -gt 0 ]; then
+ action=$1
+ shift
+else
+ action=list
+fi
+
+select() (
+ name=$(zpm quote "$1")
+ cols=$2
+ if [ -n "$name" ]; then
+ where="where name = '$name'"
+ fi
+ zpm shell -separator ' ' $ZPMDB "select $cols from repository $where order by priority,name"
+)
+
+update() (
+ name=$(zpm quote "$1")
+ col=$2
+ val=$(zpm quote "$3")
+ if [ -n "$name" ]; then
+ where="where name = '$name'"
+ fi
+ zpm shell $ZPMDB "update repository set $col = '$val' $where"
+)
+
+refresh() {
+ zpm shell $ZPMDB "update repository set refreshed = strftime('%s', 'now') where name = '$1'"
+}
+
+update_info() {
+ if [ $# -eq 0 ]; then
+ set $(select '' name)
+ fi
+ for repo in "$@"; do
+ url=$(select "$repo" url)
+ rf="$repodir/$repo.repo"
+ if [ -z "$url" ]; then
+ check_for_repo "$repo" || warn "no url for repo $repo"
+ return 1
+ fi
+ if [ -f "$rf" ]; then
+ # TODO merge in so packages aren't deleted
+ zpm fetchurl -fpn -z "$rf" -o "$rf.tmp" "$url"
+ rv=$?
+ else
+ zpm fetchurl -fpn -o "$rf.tmp" "$url" && refresh "$repo"
+ rv=$?
+ fi
+ if [ $rv -eq 0 ]; then
+ test -f "$rf.tmp" &&
+ zpm test "$rf.tmp" &&
+ mv "$rf.tmp" "$rf"
+ refresh "$repo"
+ fi
+ done
+}
+
+head_response_code() {
+ zpm fetchurl -S -z "$2" "$1"
+}
+
+download() {
+ repo=$1
+ shift
+ url=$(select "$repo" url)
+ base=${url%/*}
+ for package in "$@"; do
+ pkgid=$(zpm findpkg -f $repodir/$repo.repo $package)
+ if [ -z "$pkgid" ]; then
+ warn "no package found for $package"
+ else
+ mkdir -p "$repodir/$repo"
+ dest="$repodir/$repo/$pkgid.zpm"
+ fetch="$base/packages/$pkgid.zpm"
+
+ if [ -f "$dest" ]; then
+ rc=$(head_response_code $fetch $dest)
+ if [ $rc = 304 ]; then
+ echo "have $pkgid"
+ continue
+ fi
+ echo downloading $pkgid
+ zpm fetchurl -f '-#' -z "$dest" -o "$dest.tmp" $fetch
+ mv "$dest.tmp" "$dest"
+ else
+ echo downloading $pkgid
+ zpm fetchurl -f '-#' -o "$dest.tmp" $fetch
+ mv "$dest.tmp" "$dest"
+ fi
+ fi
+ done
+}
+
+purge() {
+ repo=$1
+ shift
+ url=$(select "$repo" url)
+ base=${url%/*}
+ for package in "$@"; do
+ pkgid=$(zpm findpkg -f $repodir/$repo.repo $package)
+ if [ -z "$pkgid" ]; then
+ warn "no package found for $package"
+ else
+ mkdir -p "$repodir/$repo"
+ dest="$repodir/$repo/$pkgid.zpm"
+
+ if [ -f "$dest" ]; then
+ rm $dest
+ fi
+ zpm rmpackage -f $repodir/$repo.repo $pkgid
+ fi
+ done
+}
+
+check_for_repo() {
+ rn=$(select "$1" name)
+ if [ -z "$rn" ]; then
+ warn "no repository $1"
+ return 1
+ fi
+ return 0
+}
+
+case $action in
+ list)
+ select '' priority,name,url,refreshed ;;
+ add)
+ name=$(zpm quote "$1")
+ url=$(zpm quote "$2")
+ zpm shell $ZPMDB "insert into repository (name,url) values ('$name', '$url')"
+ ;;
+ del)
+ name=$(zpm quote "$1")
+ zpm shell $ZPMDB "delete from repository where name = '$name'"
+ rm -f $repodir/$1.repo
+ test -d "$repodir/$repo" && rm -r "$repodir/$repo"
+ ;;
+ url)
+ if [ -n "$2" ]; then
+ update "$1" url "$2"
+ else
+ select "$1" url
+ fi
+ ;;
+ pri*)
+ if [ -n "$2" ]; then
+ update "$1" priority "$2"
+ else
+ select "$1" priority
+ fi
+ ;;
+ fetch|download)
+ download "$@"
+ ;;
+ update|pull)
+ update_info "$@"
+ ;;
+ packages)
+ repo=$1
+ shift
+ zpm list -f $repodir/$repo.repo "$@"
+ ;;
+ contents)
+ repo=$1
+ shift
+ zpm contents -f $repodir/$repo.repo "$@"
+ ;;
+ purge)
+ purge "$@"
+ ;;
+
+ *)
+ echo unknown action
+ exit 1
+ ;;
+esac