# HG changeset patch # User Franz Glasner # Date 1571296153 -7200 # Node ID 3dcae0e917692d4aea4c878b46c9798e5b3d21bb # Parent 37737f225887cf37af56bfb4ee460b982a1bdfbc Move all admin scripts into the "sbin" folder diff -r 37737f225887 -r 3dcae0e91769 Makefile --- a/Makefile Wed Oct 16 08:56:32 2019 +0200 +++ b/Makefile Thu Oct 17 09:09:13 2019 +0200 @@ -31,7 +31,7 @@ do-extract: ${MKDIR} ${WRKSRC}/bin ${MKDIR} ${WRKSRC}/sbin -.for _rp in bin/check-ports bin/fjail bin/fpkg sbin/bsmtp2dma +.for _rp in sbin/check-ports sbin/fjail sbin/fpkg sbin/bsmtp2dma ${CP} -v ${SRC}/${_rp} ${WRKSRC}/${_rp} ${SED} -i "" -E -e "s|\\\$$Date\\\$$|\$$Date: ${HGDATE} \$$|" ${WRKSRC}/${_rp} ${SED} -i "" -E -e "s|\\\$$Revision\\\$$|\$$Revision: ${HGREVISION} \$$|" ${WRKSRC}/${_rp} @@ -54,7 +54,7 @@ .endfor do-install: -.for _rp in bin/check-ports bin/fjail bin/fpkg sbin/bsmtp2dma +.for _rp in sbin/check-ports sbin/fjail sbin/fpkg sbin/bsmtp2dma ${INSTALL_SCRIPT} ${WRKSRC}/${_rp} ${STAGEDIR}${PREFIX}/${_rp} .endfor ${MKDIR} ${STAGEDIR}${ETCDIR} diff -r 37737f225887 -r 3dcae0e91769 bin/check-ports --- a/bin/check-ports Wed Oct 16 08:56:32 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,501 +0,0 @@ -#!/bin/sh -# -*- indent-tabs-mode: nil; -*- -: 'Check the version status of installed ports and compare them to -repository versions. - -:Author: Franz Glasner -:Copyright: (c) 2017-2019 Franz Glasner. - All rights reserved. -:License: BSD 3-Clause "New" or "Revised" License. - See LICENSE for details. - If you cannot find LICENSE see - -:ID: @(#)@@PKGORIGIN@@ $HGid$ - -' - -VERSION="@@VERSION@@" - -# -# Configuration directory -# -: ${CONFIGDIR:=@@ETCDIR@@} - -test -r "${CONFIGDIR}/tools.conf" && . "${CONFIGDIR}/tools.conf" - -# -# Mapping configuration: installed package name -> original package name -# Note: This is independent of any repo -# -: ${PACKAGE_MAPPING:=${CONFIGDIR}/package-mapping.conf} - -# -# Local repository with non-public packages and/or ports with changed -# OPTIONS (i.e. not using the defaults) or forks of official packages with -# other package names -# -: ${LOCAL_REPO:=LocalRepo} - -# -# Local repository with ports with default OPTIONS (i.e. unchanged) -# but newer than the packages in the "FreeBSD" repository. -# Some sort of a fast-track repository. -# -: ${LOCALBSDPORTS_REPO:=LocalBSDPorts} - -# -# The official FreeBSD binary repository -# -: ${FREEBSD_REPO:=FreeBSD} - -# -# Directly installed from ports -# -: ${PORTS_DIRECT_INSTALLED_REPO:=unknown-repository} - -# -# For the workaround of the bug in pkg rquery -I -# -: ${PORTSDIR:=/usr/ports} -: ${INDEXDIR:=${PORTSDIR}} -: ${INDEXFILE:=@@INDEXFILE@@} - - -get_remote_repo_versions() { - : 'Determine the remote repository versions of all packages in - repository `_repo`. - - Args: - _repo: the name of the repote repository - - Returns: - status 0 on success, 1 on errors - - Output (Globals): - remote_versions_${_repo}: the versions of all packages in `_repo` and - their extended version status with respect to - locally installed packages - - ' - local _repo _data _rv - - _repo=$1 - - _data=$(pkg version -U -R -r ${_repo} -v) - _rv=$? - eval remote_versions_${_repo}=\"\${_data}\" - return ${_rv} -} - -get_remote_repo_data() { - : 'Get the extended package version information from the remote repository - `_repo` for package `_name`. - - Args: - _repo: the name of the remote repository - _name: the package name - - Input (Globals): - remote_versions_${_repo}: the extended version info for *all* packages - in repo `_repo`. - - Returns: - status 0 on success, 1 on errors or if the package is not found - in the remote repository - - Output (Globals): - remote_label_${_repo}: - remote_descr_${_repo}: - - ' - local _repo _name _rversions _rfqp _rl _rdescr - - _repo=$1 - _name=$2 - - eval _rversions=\"\${remote_versions_${_repo}}\" - while read _rfqp _rl _rdescr ; do - if [ ${_rfqp%-*} = ${_name} ] ; then - eval remote_label_${_repo}=\"\${_rl}\" - eval remote_descr_${_repo}=\"\${_rdescr}\" - return 0 - fi - done <&2 - exit 2 - ;; - esac -done - -if [ -n "${short_flag}" -a -n "${alldata_flag}" ]; then - echo "the -s option cannot be combined with -A or -a" >&2 - exit 2 -fi - -installed_packages=$(pkg query '%n') -installed_data="$(pkg query '%n %v %R' $installed_packages)" - -get_remote_repo_versions ${LOCAL_REPO} -get_remote_repo_versions ${LOCALBSDPORTS_REPO} -get_remote_repo_versions ${FREEBSD_REPO} -get_local_index_versions - -while read lfqp llabel ldescr ; do - _installed_name=${lfqp%-*} - _installed_version=${lfqp##*-} - title_printed="" - get_repo_for_installed_package ${_installed_name} - get_mapping ${_installed_name} - if [ -n "${verbose_flag}" ] ; then - print_title "${lfqp}" "${repository}" - fi - if ! assert_local_version ${_installed_name} ${_installed_version} ; then - echo "Assertion failed: $lfqp ${_installed_name} ${_installed_version} ${llabel}" >&2 - exit 1 - fi - get_remote_repo_data ${LOCAL_REPO} ${_installed_name} - get_remote_repo_data ${LOCALBSDPORTS_REPO} ${_installed_name} - get_remote_repo_data ${FREEBSD_REPO} ${_installed_name} - _print_detail="" - if [ -n "${mapped_package_name}" ] ; then - _print_detail=1 - fi - if [ \( -n "${alldata_flag}" \) ]; then - _print_detail=1 - else - if [ -n "${short_flag}" ]; then - # - # NOTE: -s and -A/-a are incompatible: so "alldata_XXX" needs not - # to be checked! - # - case "${repository}" in - "${FREEBSD_REPO}") - if [ \( "${llabel}" != '<' -a "${llabel}" != '=' \) -o "${remote_label_FreeBSD}" != '=' -o "${remote_label_LocalRepo}" != '?' -o "${remote_label_LocalBSDPorts}" != '?' ]; then - _print_detail=1 - fi - ;; - "${LOCAL_REPO}") - _print_detail=1 - ;; - "${LOCALBSDPORTS_REPO}") - if [ "${llabel}" != '=' -o "${remote_label_FreeBSD}" != '>' -o "${remote_label_LocalRepo}" != '?' -o "${remote_label_LocalBSDPorts}" = '?' -o "${remote_label_LocalBSDPorts}" = '<' ]; then - _print_detail=1 - fi - ;; - "${PORTS_DIRECT_INSTALLED_REPO}") - _print_detail=1 - ;; - *) - echo "ERROR: unhandled repository: ${repository}" >&2 - exit 1 - ;; - esac - else - if [ \( \( "${llabel}" != '?' -a "${llabel}" != '=' \) -o \( "${remote_label_FreeBSD}" != '?' -a "${remote_label_FreeBSD}" != '=' \) -o \( "${remote_label_LocalBSDPorts}" != '?' -a "${remote_label_LocalBSDPorts}" != '=' \) -o \( "${remote_label_LocalRepo}" != '?' -a "${remote_label_LocalRepo}" != '=' \) \) -o \( "${repository}" = "${PORTS_DIRECT_INSTALLED_REPO}" \) ]; then - _print_detail=1 - fi - fi - fi - if [ -n "${_print_detail}" ]; then - print_title "${lfqp}" "${repository}" - echo " INDEX : ${llabel} ${ldescr}" - echo " FreeBSD : ${remote_label_FreeBSD} ${remote_descr_FreeBSD}" - if [ \( -n "${alldata_flag_LocalBSDPorts}" \) -o \( "${remote_label_LocalBSDPorts}" != '?' \) ] ; then - echo " LocalBSDPorts: ${remote_label_LocalBSDPorts} ${remote_descr_LocalBSDPorts}" - fi - if [ \( -n "${alldata_flag_LocalRepo}" \) -o \( "${remote_label_LocalRepo}" != '?' \) ] ; then - echo " LocalRepo : ${remote_label_LocalRepo} ${remote_descr_LocalRepo}" - fi - if [ -n "${mapped_package_name}" ] ; then - echo " ---> ${mapped_package_name}" - get_immediate_index_version "${mapped_package_name}" - get_immediate_remote_repo_version ${LOCAL_REPO} ${mapped_package_name} - get_immediate_remote_repo_version ${LOCALBSDPORTS_REPO} ${mapped_package_name} - get_immediate_remote_repo_version ${FREEBSD_REPO} ${mapped_package_name} - echo " INDEX : ${immediate_index_version}" - echo " FreeBSD : ${immediate_remote_repo_version_FreeBSD}" - echo " LocalBSDPorts: ${immediate_remote_repo_version_LocalBSDPorts}" - echo " LocalRepo : ${immediate_remote_repo_version_LocalRepo}" - fi - fi -done < -:ID: @(#)@@PKGORIGIN@@ $HGid$ - -' - -set -eu - -VERSION="@@VERSION@@" - -USAGE=' -USAGE: fjail [ OPTIONS ] COMMAND [ COMMAND OPTIONS ] [ ARG ... ] - -OPTIONS: - - -V Print the program name and version number to stdout and exit - - -h Print this help message to stdout and exit - -COMMANDS: - - datasets [-u] PARENT CHILD - - Create ZFS datasets to be used within a jail - - PARENT must exist already and CHILD must not exist. - - -u Do not automatically mount newly created datasets - - privs MOUNTPOINT - - Adjust some Unix privileges to mounted jail datasets - - populate MOUNTPOINT BASETXZ - - Populate the jail directory in MOUNTPOINT with the base system in BASETXZ - - copy SOURCE-DATASET DEST-DATASET - - Copy a tree of ZFS datasets with "zfs send -R" and "zfs receive". - Note that the destination dataset must not exist already. - - -u Do not automatically mount received datasets - -ENVIRONMENT: - - All environment variables that affect "zfs" are effective also. - -DESCRIPTION: - - All commands with the exception of "populate" require ZFS as - filesystem. -' - - -# Reset to standard umask -umask 0022 - - -# -# "datasets" -- create the ZFS dataset tree -# -# command_datasets [ -u ] parent-dataset child-dataset -# -# -u do not automatically mount newly created datasets -# -command_datasets() { - # parent ZFS dataset -- child ZFS dataset name - local _pds _cds - # and its mount point - local _pmp _get _dummy - # full name of the dataset - local _ds - # dynamic ZFS options - local _zfsopts - - _zfsopts="" - while getopts "u" _opt ; do - case ${_opt} in - u) - # do not mount newly created datasets - _zfsopts="${_zfsopts} -u" - ;; - \?|:) - return 2; - ;; - esac - done - shift $((OPTIND-1)) - OPTIND=1 - - _pds="$1" - if [ -z "${_pds}" ]; then - echo "ERROR: no parent dataset given" >&2 - return 2 - fi - _get=$(zfs get -H mountpoint "${_pds}" 2>/dev/null) || { echo "ERROR: dataset \`${_pds}' does not exist" >&2; return 1; } - IFS=$'\t' read _dummy _dummy _pmp _dummy <&2 - return 1 - ;; - legacy) - echo "ERROR: dataset \`${_pds}' has a \`${_mp}' mountpoint" >&2 - return 1 - ;; - *) - # VOID - ;; - esac - _cds="$2" - if [ -z "${_cds}" ]; then - echo "ERROR: no child dataset given" >&2 - return 2 - fi - _ds="${_pds}/${_cds}" - echo "Resulting new root dataset is \`${_ds}' at mountpoint \`${_pmp}/${_cds}'" - if zfs get -H mountpoint "${_ds}" >/dev/null 2>/dev/null; then - echo "ERROR: dataset \`${_ds}' does already exist" >&2 - return 1 - fi - zfs create ${_zfsopts} -o atime=off "${_ds}" - zfs create ${_zfsopts} -o sync=disabled -o setuid=off "${_ds}/tmp" - zfs create ${_zfsopts} "${_ds}/usr" - zfs create ${_zfsopts} "${_ds}/var" - zfs create ${_zfsopts} -o exec=off -o setuid=off "${_ds}/var/audit" - zfs create ${_zfsopts} -o exec=off -o setuid=off "${_ds}/var/cache" - zfs create ${_zfsopts} -o exec=off -o setuid=off -o compression=off "${_ds}/var/cache/pkg" - zfs create ${_zfsopts} -o exec=off -o setuid=off -o compression=off "${_ds}/var/crash" - zfs create ${_zfsopts} -o exec=off -o setuid=off "${_ds}/var/db" - zfs create ${_zfsopts} -o exec=on -o setuid=off "${_ds}/var/db/pkg" - zfs create ${_zfsopts} -o readonly=on -o exec=off -o setuid=off "${_ds}/var/empty" - zfs create ${_zfsopts} -o exec=off -o setuid=off -o primarycache=metadata "${_ds}/var/log" - zfs create ${_zfsopts} -o exec=off -o setuid=off -o atime=on "${_ds}/var/mail" - zfs create ${_zfsopts} -o sync=disabled -o exec=off -o setuid=off -o compression=off -o primarycache=all "${_ds}/var/run" - zfs create ${_zfsopts} -o sync=disabled -o setuid=off "${_ds}/var/tmp" -} - - -# -# "populate" -- populate the datasets with content from a FreeBSD base.txz -# -# command_populate mountpoint basetxz -# -command_populate() { - # MOUNTPOINT -- base.txz - local _mp _basetxz - - _mp="$1" - _basetxz="$2" - - if [ -z "${_mp}" ]; then - echo "ERROR: no mountpoint given" >&2 - return 2 - fi - if [ -z "${_basetxz}" ]; then - echo "ERROR: no base.txz given" >&2 - return 2 - fi - if [ ! -d "${_mp}" ]; then - echo "ERROR: mountpoint \`${_mp}' does not exist" >&2 - return 1 - fi - if [ ! -r "${_basetxz}" ]; then - echo "ERROR: file \`${_basetxz}' is not readable" >&2 - return 1 - fi - - tar -C "${_mp}" --exclude=./var/empty -xJp -f "${_basetxz}" || { echo "ERROR: tar encountered errors" >&2; return 1; } -} - - -# -# "copy" -- ZFS copy of datasets -# -# command_copy source-dataset destination-dataset -# -command_copy() { - # source dataset -- destination dataset - local _source _dest - # dynamic ZFS options - local _zfsopts - - _zfsopts="" - while getopts "u" _opt ; do - case ${_opt} in - u) - # do not mount newly created datasets - _zfsopts="${_zfsopts} -u" - ;; - \?|:) - return 2; - ;; - esac - done - shift $((OPTIND-1)) - OPTIND=1 - - _source="$1" - if [ -z "${_source}" ]; then - echo "ERROR: no source dataset given" >&2 - return 2 - fi - _dest="$2" - if [ -z "${_dest}" ]; then - echo "ERROR: no source dataset given" >&2 - return 2 - fi - zfs send -R -n -v ${_source} || { echo "ERROR: ZFS operation failed in no-op mode" >&2; return 1; } - zfs send -R "${_source}" | zfs receive ${_zfsopts} "${_dest}" || { echo "ERROR: ZFS operation failed" >&2; return 1; } -} - - -# -# "privs" -- adjust privileges -# -# To be used when all ZFS datasets are mounted. -# -command_privs() { - # mountpoint - local _mp _d - - _mp="$1" - if [ -z "${_mp}" ]; then - echo "ERROR: no mountpoint given" >&2 - return 2 - fi - if [ ! -d "${_mp}" ]; then - echo "ERROR: directory \`${_mp}' does not exist" >&2 - return 1 - fi - for _d in tmp var/tmp ; do - chmod 01777 "${_mp}/${_d}" - done - chown root:mail "${_mp}/var/mail" - chmod 0775 "${_mp}/var/mail" -} - - -# -# Global option handling -# -while getopts "Vh" _opt ; do - case ${_opt} in - V) - echo "fjail v${VERSION} (rv:@@HGREVISION@@)" - exit 0 - ;; - h) - echo "${USAGE}" - exit 0 - ;; - \?) - exit 2; - ;; - *) - echo "ERROR: option handling failed" >&2 - exit 2 - ;; - esac -done - -# -# Reset the Shell's option handling system to prepare for handling -# command-local options. -# -shift $((OPTIND-1)) -OPTIND=1 - -test $# -gt 0 || { echo "ERROR: no command given" >&2; exit 2; } - -command="$1" -shift - -case "${command}" in - datasets) - command_datasets "$@" - ;; - privs) - command_privs "$@" - ;; - populate) - command_populate "$@" - ;; - copy) - command_copy "$@" - ;; - *) - echo "ERROR: unknown command \`${command}'" >&2 - exit 2 - ;; -esac diff -r 37737f225887 -r 3dcae0e91769 bin/fpkg --- a/bin/fpkg Wed Oct 16 08:56:32 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,293 +0,0 @@ -#!/bin/sh -# -*- indent-tabs-mode: nil; -*- -: 'A pkg frontend for common operations that also operates in all -running jails. - -:Author: Franz Glasner -:Copyright: (c) 2019 Franz Glasner. - All rights reserved. -:License: BSD 3-Clause "New" or "Revised" License. - See LICENSE for details. - If you cannot find LICENSE see - -:ID: @(#)@@PKGORIGIN@@ $HGid$ - -' - -VERSION="@@VERSION@@" - -USAGE=' -USAGE: fpkg [ OPTIONS] COMMAND [ COMMAND-OPTIONS ] - -OPTIONS: - - -V Print the program name and version number to stdout and exit - - -h Print this help message to stdout and exit - -COMMANDS: - - audit - - `pkg audit` on the local host and all running visible jails - - update - - `pkg update` on the local host and all running visible jails - - upgrade - - `pkg upgrade` on the local host and all running visible jails - - upgrade-check - - `pkg upgrade -n` on the local host and all running visible jails - - check-fast-track - Check packages installed from the LocalBSDPorts repository against - the repositories `FreeBSD` and `LocalBSDPorts` on the local host - and all visible jails - - -ENVIRONMENT: - - FPKG_AUDIT_FLAGS - Additional flags given to `pkg audit` - (Default: -Fr) - - FPKG_UPDATE_FLAGS - Additional flags given to `pkg update` - (Default: empty) - - FPKG_UPGRADE_FLAGS - Additional flags given to `pkg upgrade` and `pkg upgrade -n` - (Default: empty) - - FPKG_SIGN - Marker for the begin of an output group (local host or jail) - (Default: "===> ") - - FPKG_SKIPSIGN - Marker for the begin of a skipped output group - (Default: "----> ") - - All other environment variables that affect `pkg` are effective also. -' - -# -# Configuration directory -# -: ${CONFIGDIR:=@@ETCDIR@@} - -test -r "${CONFIGDIR}/tools.conf" && . "${CONFIGDIR}/tools.conf" - -: ${FPKG_AUDIT_FLAGS:=-Fr} -: ${FPKG_UPDATE_FLAGS:=} -: ${FPKG_UPGRADE_FLAGS:=} -: ${FPKG_SIGN:='===> '} -: ${FPKG_SKIPSIGN:='----> '} - -# -# The official FreeBSD binary repository -# -: ${FREEBSD_REPO:=FreeBSD} - -# -# Local repository with ports with default OPTIONS (i.e. unchanged) -# but newer than the packages in the "FreeBSD" repository. -# Some sort of a fast-track repository. -# -: ${LOCALBSDPORTS_REPO:=LocalBSDPorts} - - -has_same_userland_version() { - : 'Check whether the jail `_jail` has the same FreeBSD userland version - as the host the the current process runs. - - Args: - _jail: the running jail to check for - - Returns: - 0 if the userland versions match, 1 otherwise - - ' - local _jail _host_version _jail_version - - _jail="$1" - - _host_version=$(/bin/freebsd-version -u) || exit 1 - _jail_version=$(jexec -l "${_jail}" /bin/freebsd-version -u) || exit 1 - if [ "${_host_version%%-*}" = "${_jail_version%%-*}" ]; then - return 0 - fi - return 1 -} - - -command_audit() { - : 'Do a local `pkg audit -Fr` and also for all running jails - - ' - echo "${FPKG_SIGN}LOCALHOST" - pkg audit ${FPKG_AUDIT_FLAGS} - for _j in $(jls -N | awk '{if(NR>1)print $1}' | sort); do - echo "" - echo "${FPKG_SIGN}JAIL: ${_j}" - if has_same_userland_version "${_j}"; then - pkg -j "${_j}" audit ${FPKG_AUDIT_FLAGS} - else - echo "${FPKG_SKIPSIGN}SKIPPED because of different userland" - fi - done -} - - -command_update() { - : 'Do a local `pkg update` and also for all running jails - - ' - echo "${FPKG_SIGN}LOCALHOST" - pkg update ${FPKG_UPDATE_FLAGS} - for _j in $(jls -N | awk '{if(NR>1)print $1}' | sort); do - echo "" - echo "${FPKG_SIGN}JAIL: ${_j}" - if has_same_userland_version "${_j}"; then - pkg -j "${_j}" update ${FPKG_UPDATE_FLAGS} - else - echo "${FPKG_SKIPSIGN}SKIPPED because of different userland" - fi - done -} - - -command_upgrade() { - : 'Do a local `pkg upgrade` and also for all running jails - - ' - echo "${FPKG_SIGN}LOCALHOST" - pkg upgrade ${FPKG_UPGRADE_FLAGS} - for _j in $(jls -N | awk '{if(NR>1)print $1}' | sort); do - echo "" - echo "${FPKG_SIGN}JAIL: ${_j}" - if has_same_userland_version "${_j}"; then - pkg -j "${_j}" upgrade ${FPKG_UPGRADE_FLAGS} - else - echo "${FPKG_SKIPSIGN}SKIPPED because of different userland" - fi - done -} - - -command_upgrade_check() { - : 'Do a local `pkg upgrade -n` and also for all running jails - - ' - echo "${FPKG_SIGN}LOCALHOST" - pkg upgrade -n ${FPKG_UPGRADE_FLAGS} - for _j in $(jls -N | awk '{if(NR>1)print $1}' | sort); do - echo "" - echo "${FPKG_SIGN}JAIL: ${_j}" - if has_same_userland_version "${_j}"; then - pkg -j "${_j}" upgrade -n ${FPKG_UPGRADE_FLAGS} - else - echo "${FPKG_SKIPSIGN}SKIPPED because of different userland" - fi - done -} - - -command_check_fasttrack() { - : 'Check the fast-track repository versions against the canonical - FreeBSD repository versions. - - Input (Globals): - FREEBSD_REPO: the (canonical) FreeBSD repository name - LOCALBSDPORTS_REPO: the fast-track repository name - - ' - local _name local _repo _j - - echo "${FPKG_SIGN}LOCALHOST" - pkg query '%n %R' | - while read _name _repo; do - if [ "${_repo}" = "${LOCALBSDPORTS_REPO}" ]; then - echo " ${_name}" - printf " %-15s : %s\n" "${LOCALBSDPORTS_REPO}" "$(pkg version -U -r ${LOCALBSDPORTS_REPO} -n ${_name} -v)" - printf " %-15s : %s\n" "${FREEBSD_REPO}" "$(pkg version -U -r ${FREEBSD_REPO} -n ${_name} -v)" - fi - done - for _j in $(jls -N | awk '{if(NR>1)print $1}' | sort); do - echo "" - echo "${FPKG_SIGN}JAIL: ${_j}" - if has_same_userland_version "${_j}"; then - pkg -j "${_j}" query '%n %R' | - while read _name _repo; do - if [ "${_repo}" = "${LOCALBSDPORTS_REPO}" ]; then - echo " ${_name}" - printf " %s-15s : %s\n" "${LOCALBSDPORTS_REPO}" "$(pkg -j ${_j} version -U -r ${LOCALBSDPORTS_REPO} -n ${_name} -v)" - printf " %-15s : %s\n" "${FREEBSD_REPO}" "$(pkg -j ${_j} version -U -r ${FREEBSD_REPO} -n ${_name} -v)" - fi - done - else - echo "${FPKG_SKIPSIGN}SKIPPED because of different userland" - fi - done -} - - -# -# Global option handling -# -while getopts "Vh" _opt ; do - case ${_opt} in - V) - echo "fpkg v${VERSION} (rv:@@HGREVISION@@)" - exit 0 - ;; - h) - echo "${USAGE}" - exit 0 - ;; - \?) - exit 2; - ;; - *) - echo "ERROR: option handling failed" >&2 - exit 2 - ;; - esac -done - -# -# Reset the Shell's option handling system to prepare for handling -# command-local options. -# -shift $((OPTIND-1)) -OPTIND=1 - -command="$1" -shift - -test -n "$command" || { echo "ERROR: no command given" >&2; exit 2; } - -case "${command}" in - audit) - command_audit "$@" - ;; - update) - command_update "$@" - ;; - upgrade) - command_upgrade "$@" - ;; - upgrade-check|upgrade_check) - command_upgrade_check "$@" - ;; - check-fast-track|check-fasttrack|check_fast_track|check_fasttrack) - command_check_fasttrack "$@" - ;; - *) - echo "ERROR: unknown command \`${command}'" >&2 - exit 2; - ;; -esac diff -r 37737f225887 -r 3dcae0e91769 pkg-plist --- a/pkg-plist Wed Oct 16 08:56:32 2019 +0200 +++ b/pkg-plist Thu Oct 17 09:09:13 2019 +0200 @@ -1,10 +1,10 @@ @comment DIRECTORIES @dir %%ETCDIR%% @comment FILES -bin/check-ports -bin/fjail -bin/fpkg sbin/bsmtp2dma +sbin/check-ports +sbin/fjail +sbin/fpkg @sample %%ETCDIR%%/tools.conf.sample @sample %%ETCDIR%%/package-mapping.conf.sample @sample %%ETCDIR%%/bsmtp2dma.conf.sample diff -r 37737f225887 -r 3dcae0e91769 sbin/check-ports --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sbin/check-ports Thu Oct 17 09:09:13 2019 +0200 @@ -0,0 +1,501 @@ +#!/bin/sh +# -*- indent-tabs-mode: nil; -*- +: 'Check the version status of installed ports and compare them to +repository versions. + +:Author: Franz Glasner +:Copyright: (c) 2017-2019 Franz Glasner. + All rights reserved. +:License: BSD 3-Clause "New" or "Revised" License. + See LICENSE for details. + If you cannot find LICENSE see + +:ID: @(#)@@PKGORIGIN@@ $HGid$ + +' + +VERSION="@@VERSION@@" + +# +# Configuration directory +# +: ${CONFIGDIR:=@@ETCDIR@@} + +test -r "${CONFIGDIR}/tools.conf" && . "${CONFIGDIR}/tools.conf" + +# +# Mapping configuration: installed package name -> original package name +# Note: This is independent of any repo +# +: ${PACKAGE_MAPPING:=${CONFIGDIR}/package-mapping.conf} + +# +# Local repository with non-public packages and/or ports with changed +# OPTIONS (i.e. not using the defaults) or forks of official packages with +# other package names +# +: ${LOCAL_REPO:=LocalRepo} + +# +# Local repository with ports with default OPTIONS (i.e. unchanged) +# but newer than the packages in the "FreeBSD" repository. +# Some sort of a fast-track repository. +# +: ${LOCALBSDPORTS_REPO:=LocalBSDPorts} + +# +# The official FreeBSD binary repository +# +: ${FREEBSD_REPO:=FreeBSD} + +# +# Directly installed from ports +# +: ${PORTS_DIRECT_INSTALLED_REPO:=unknown-repository} + +# +# For the workaround of the bug in pkg rquery -I +# +: ${PORTSDIR:=/usr/ports} +: ${INDEXDIR:=${PORTSDIR}} +: ${INDEXFILE:=@@INDEXFILE@@} + + +get_remote_repo_versions() { + : 'Determine the remote repository versions of all packages in + repository `_repo`. + + Args: + _repo: the name of the repote repository + + Returns: + status 0 on success, 1 on errors + + Output (Globals): + remote_versions_${_repo}: the versions of all packages in `_repo` and + their extended version status with respect to + locally installed packages + + ' + local _repo _data _rv + + _repo=$1 + + _data=$(pkg version -U -R -r ${_repo} -v) + _rv=$? + eval remote_versions_${_repo}=\"\${_data}\" + return ${_rv} +} + +get_remote_repo_data() { + : 'Get the extended package version information from the remote repository + `_repo` for package `_name`. + + Args: + _repo: the name of the remote repository + _name: the package name + + Input (Globals): + remote_versions_${_repo}: the extended version info for *all* packages + in repo `_repo`. + + Returns: + status 0 on success, 1 on errors or if the package is not found + in the remote repository + + Output (Globals): + remote_label_${_repo}: + remote_descr_${_repo}: + + ' + local _repo _name _rversions _rfqp _rl _rdescr + + _repo=$1 + _name=$2 + + eval _rversions=\"\${remote_versions_${_repo}}\" + while read _rfqp _rl _rdescr ; do + if [ ${_rfqp%-*} = ${_name} ] ; then + eval remote_label_${_repo}=\"\${_rl}\" + eval remote_descr_${_repo}=\"\${_rdescr}\" + return 0 + fi + done <&2 + exit 2 + ;; + esac +done + +if [ -n "${short_flag}" -a -n "${alldata_flag}" ]; then + echo "the -s option cannot be combined with -A or -a" >&2 + exit 2 +fi + +installed_packages=$(pkg query '%n') +installed_data="$(pkg query '%n %v %R' $installed_packages)" + +get_remote_repo_versions ${LOCAL_REPO} +get_remote_repo_versions ${LOCALBSDPORTS_REPO} +get_remote_repo_versions ${FREEBSD_REPO} +get_local_index_versions + +while read lfqp llabel ldescr ; do + _installed_name=${lfqp%-*} + _installed_version=${lfqp##*-} + title_printed="" + get_repo_for_installed_package ${_installed_name} + get_mapping ${_installed_name} + if [ -n "${verbose_flag}" ] ; then + print_title "${lfqp}" "${repository}" + fi + if ! assert_local_version ${_installed_name} ${_installed_version} ; then + echo "Assertion failed: $lfqp ${_installed_name} ${_installed_version} ${llabel}" >&2 + exit 1 + fi + get_remote_repo_data ${LOCAL_REPO} ${_installed_name} + get_remote_repo_data ${LOCALBSDPORTS_REPO} ${_installed_name} + get_remote_repo_data ${FREEBSD_REPO} ${_installed_name} + _print_detail="" + if [ -n "${mapped_package_name}" ] ; then + _print_detail=1 + fi + if [ \( -n "${alldata_flag}" \) ]; then + _print_detail=1 + else + if [ -n "${short_flag}" ]; then + # + # NOTE: -s and -A/-a are incompatible: so "alldata_XXX" needs not + # to be checked! + # + case "${repository}" in + "${FREEBSD_REPO}") + if [ \( "${llabel}" != '<' -a "${llabel}" != '=' \) -o "${remote_label_FreeBSD}" != '=' -o "${remote_label_LocalRepo}" != '?' -o "${remote_label_LocalBSDPorts}" != '?' ]; then + _print_detail=1 + fi + ;; + "${LOCAL_REPO}") + _print_detail=1 + ;; + "${LOCALBSDPORTS_REPO}") + if [ "${llabel}" != '=' -o "${remote_label_FreeBSD}" != '>' -o "${remote_label_LocalRepo}" != '?' -o "${remote_label_LocalBSDPorts}" = '?' -o "${remote_label_LocalBSDPorts}" = '<' ]; then + _print_detail=1 + fi + ;; + "${PORTS_DIRECT_INSTALLED_REPO}") + _print_detail=1 + ;; + *) + echo "ERROR: unhandled repository: ${repository}" >&2 + exit 1 + ;; + esac + else + if [ \( \( "${llabel}" != '?' -a "${llabel}" != '=' \) -o \( "${remote_label_FreeBSD}" != '?' -a "${remote_label_FreeBSD}" != '=' \) -o \( "${remote_label_LocalBSDPorts}" != '?' -a "${remote_label_LocalBSDPorts}" != '=' \) -o \( "${remote_label_LocalRepo}" != '?' -a "${remote_label_LocalRepo}" != '=' \) \) -o \( "${repository}" = "${PORTS_DIRECT_INSTALLED_REPO}" \) ]; then + _print_detail=1 + fi + fi + fi + if [ -n "${_print_detail}" ]; then + print_title "${lfqp}" "${repository}" + echo " INDEX : ${llabel} ${ldescr}" + echo " FreeBSD : ${remote_label_FreeBSD} ${remote_descr_FreeBSD}" + if [ \( -n "${alldata_flag_LocalBSDPorts}" \) -o \( "${remote_label_LocalBSDPorts}" != '?' \) ] ; then + echo " LocalBSDPorts: ${remote_label_LocalBSDPorts} ${remote_descr_LocalBSDPorts}" + fi + if [ \( -n "${alldata_flag_LocalRepo}" \) -o \( "${remote_label_LocalRepo}" != '?' \) ] ; then + echo " LocalRepo : ${remote_label_LocalRepo} ${remote_descr_LocalRepo}" + fi + if [ -n "${mapped_package_name}" ] ; then + echo " ---> ${mapped_package_name}" + get_immediate_index_version "${mapped_package_name}" + get_immediate_remote_repo_version ${LOCAL_REPO} ${mapped_package_name} + get_immediate_remote_repo_version ${LOCALBSDPORTS_REPO} ${mapped_package_name} + get_immediate_remote_repo_version ${FREEBSD_REPO} ${mapped_package_name} + echo " INDEX : ${immediate_index_version}" + echo " FreeBSD : ${immediate_remote_repo_version_FreeBSD}" + echo " LocalBSDPorts: ${immediate_remote_repo_version_LocalBSDPorts}" + echo " LocalRepo : ${immediate_remote_repo_version_LocalRepo}" + fi + fi +done < +:ID: @(#)@@PKGORIGIN@@ $HGid$ + +' + +set -eu + +VERSION="@@VERSION@@" + +USAGE=' +USAGE: fjail [ OPTIONS ] COMMAND [ COMMAND OPTIONS ] [ ARG ... ] + +OPTIONS: + + -V Print the program name and version number to stdout and exit + + -h Print this help message to stdout and exit + +COMMANDS: + + datasets [-u] PARENT CHILD + + Create ZFS datasets to be used within a jail + + PARENT must exist already and CHILD must not exist. + + -u Do not automatically mount newly created datasets + + privs MOUNTPOINT + + Adjust some Unix privileges to mounted jail datasets + + populate MOUNTPOINT BASETXZ + + Populate the jail directory in MOUNTPOINT with the base system in BASETXZ + + copy SOURCE-DATASET DEST-DATASET + + Copy a tree of ZFS datasets with "zfs send -R" and "zfs receive". + Note that the destination dataset must not exist already. + + -u Do not automatically mount received datasets + +ENVIRONMENT: + + All environment variables that affect "zfs" are effective also. + +DESCRIPTION: + + All commands with the exception of "populate" require ZFS as + filesystem. +' + + +# Reset to standard umask +umask 0022 + + +# +# "datasets" -- create the ZFS dataset tree +# +# command_datasets [ -u ] parent-dataset child-dataset +# +# -u do not automatically mount newly created datasets +# +command_datasets() { + # parent ZFS dataset -- child ZFS dataset name + local _pds _cds + # and its mount point + local _pmp _get _dummy + # full name of the dataset + local _ds + # dynamic ZFS options + local _zfsopts + + _zfsopts="" + while getopts "u" _opt ; do + case ${_opt} in + u) + # do not mount newly created datasets + _zfsopts="${_zfsopts} -u" + ;; + \?|:) + return 2; + ;; + esac + done + shift $((OPTIND-1)) + OPTIND=1 + + _pds="$1" + if [ -z "${_pds}" ]; then + echo "ERROR: no parent dataset given" >&2 + return 2 + fi + _get=$(zfs get -H mountpoint "${_pds}" 2>/dev/null) || { echo "ERROR: dataset \`${_pds}' does not exist" >&2; return 1; } + IFS=$'\t' read _dummy _dummy _pmp _dummy <&2 + return 1 + ;; + legacy) + echo "ERROR: dataset \`${_pds}' has a \`${_mp}' mountpoint" >&2 + return 1 + ;; + *) + # VOID + ;; + esac + _cds="$2" + if [ -z "${_cds}" ]; then + echo "ERROR: no child dataset given" >&2 + return 2 + fi + _ds="${_pds}/${_cds}" + echo "Resulting new root dataset is \`${_ds}' at mountpoint \`${_pmp}/${_cds}'" + if zfs get -H mountpoint "${_ds}" >/dev/null 2>/dev/null; then + echo "ERROR: dataset \`${_ds}' does already exist" >&2 + return 1 + fi + zfs create ${_zfsopts} -o atime=off "${_ds}" + zfs create ${_zfsopts} -o sync=disabled -o setuid=off "${_ds}/tmp" + zfs create ${_zfsopts} "${_ds}/usr" + zfs create ${_zfsopts} "${_ds}/var" + zfs create ${_zfsopts} -o exec=off -o setuid=off "${_ds}/var/audit" + zfs create ${_zfsopts} -o exec=off -o setuid=off "${_ds}/var/cache" + zfs create ${_zfsopts} -o exec=off -o setuid=off -o compression=off "${_ds}/var/cache/pkg" + zfs create ${_zfsopts} -o exec=off -o setuid=off -o compression=off "${_ds}/var/crash" + zfs create ${_zfsopts} -o exec=off -o setuid=off "${_ds}/var/db" + zfs create ${_zfsopts} -o exec=on -o setuid=off "${_ds}/var/db/pkg" + zfs create ${_zfsopts} -o readonly=on -o exec=off -o setuid=off "${_ds}/var/empty" + zfs create ${_zfsopts} -o exec=off -o setuid=off -o primarycache=metadata "${_ds}/var/log" + zfs create ${_zfsopts} -o exec=off -o setuid=off -o atime=on "${_ds}/var/mail" + zfs create ${_zfsopts} -o sync=disabled -o exec=off -o setuid=off -o compression=off -o primarycache=all "${_ds}/var/run" + zfs create ${_zfsopts} -o sync=disabled -o setuid=off "${_ds}/var/tmp" +} + + +# +# "populate" -- populate the datasets with content from a FreeBSD base.txz +# +# command_populate mountpoint basetxz +# +command_populate() { + # MOUNTPOINT -- base.txz + local _mp _basetxz + + _mp="$1" + _basetxz="$2" + + if [ -z "${_mp}" ]; then + echo "ERROR: no mountpoint given" >&2 + return 2 + fi + if [ -z "${_basetxz}" ]; then + echo "ERROR: no base.txz given" >&2 + return 2 + fi + if [ ! -d "${_mp}" ]; then + echo "ERROR: mountpoint \`${_mp}' does not exist" >&2 + return 1 + fi + if [ ! -r "${_basetxz}" ]; then + echo "ERROR: file \`${_basetxz}' is not readable" >&2 + return 1 + fi + + tar -C "${_mp}" --exclude=./var/empty -xJp -f "${_basetxz}" || { echo "ERROR: tar encountered errors" >&2; return 1; } +} + + +# +# "copy" -- ZFS copy of datasets +# +# command_copy source-dataset destination-dataset +# +command_copy() { + # source dataset -- destination dataset + local _source _dest + # dynamic ZFS options + local _zfsopts + + _zfsopts="" + while getopts "u" _opt ; do + case ${_opt} in + u) + # do not mount newly created datasets + _zfsopts="${_zfsopts} -u" + ;; + \?|:) + return 2; + ;; + esac + done + shift $((OPTIND-1)) + OPTIND=1 + + _source="$1" + if [ -z "${_source}" ]; then + echo "ERROR: no source dataset given" >&2 + return 2 + fi + _dest="$2" + if [ -z "${_dest}" ]; then + echo "ERROR: no source dataset given" >&2 + return 2 + fi + zfs send -R -n -v ${_source} || { echo "ERROR: ZFS operation failed in no-op mode" >&2; return 1; } + zfs send -R "${_source}" | zfs receive ${_zfsopts} "${_dest}" || { echo "ERROR: ZFS operation failed" >&2; return 1; } +} + + +# +# "privs" -- adjust privileges +# +# To be used when all ZFS datasets are mounted. +# +command_privs() { + # mountpoint + local _mp _d + + _mp="$1" + if [ -z "${_mp}" ]; then + echo "ERROR: no mountpoint given" >&2 + return 2 + fi + if [ ! -d "${_mp}" ]; then + echo "ERROR: directory \`${_mp}' does not exist" >&2 + return 1 + fi + for _d in tmp var/tmp ; do + chmod 01777 "${_mp}/${_d}" + done + chown root:mail "${_mp}/var/mail" + chmod 0775 "${_mp}/var/mail" +} + + +# +# Global option handling +# +while getopts "Vh" _opt ; do + case ${_opt} in + V) + echo "fjail v${VERSION} (rv:@@HGREVISION@@)" + exit 0 + ;; + h) + echo "${USAGE}" + exit 0 + ;; + \?) + exit 2; + ;; + *) + echo "ERROR: option handling failed" >&2 + exit 2 + ;; + esac +done + +# +# Reset the Shell's option handling system to prepare for handling +# command-local options. +# +shift $((OPTIND-1)) +OPTIND=1 + +test $# -gt 0 || { echo "ERROR: no command given" >&2; exit 2; } + +command="$1" +shift + +case "${command}" in + datasets) + command_datasets "$@" + ;; + privs) + command_privs "$@" + ;; + populate) + command_populate "$@" + ;; + copy) + command_copy "$@" + ;; + *) + echo "ERROR: unknown command \`${command}'" >&2 + exit 2 + ;; +esac diff -r 37737f225887 -r 3dcae0e91769 sbin/fpkg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sbin/fpkg Thu Oct 17 09:09:13 2019 +0200 @@ -0,0 +1,293 @@ +#!/bin/sh +# -*- indent-tabs-mode: nil; -*- +: 'A pkg frontend for common operations that also operates in all +running jails. + +:Author: Franz Glasner +:Copyright: (c) 2019 Franz Glasner. + All rights reserved. +:License: BSD 3-Clause "New" or "Revised" License. + See LICENSE for details. + If you cannot find LICENSE see + +:ID: @(#)@@PKGORIGIN@@ $HGid$ + +' + +VERSION="@@VERSION@@" + +USAGE=' +USAGE: fpkg [ OPTIONS] COMMAND [ COMMAND-OPTIONS ] + +OPTIONS: + + -V Print the program name and version number to stdout and exit + + -h Print this help message to stdout and exit + +COMMANDS: + + audit + + `pkg audit` on the local host and all running visible jails + + update + + `pkg update` on the local host and all running visible jails + + upgrade + + `pkg upgrade` on the local host and all running visible jails + + upgrade-check + + `pkg upgrade -n` on the local host and all running visible jails + + check-fast-track + Check packages installed from the LocalBSDPorts repository against + the repositories `FreeBSD` and `LocalBSDPorts` on the local host + and all visible jails + + +ENVIRONMENT: + + FPKG_AUDIT_FLAGS + Additional flags given to `pkg audit` + (Default: -Fr) + + FPKG_UPDATE_FLAGS + Additional flags given to `pkg update` + (Default: empty) + + FPKG_UPGRADE_FLAGS + Additional flags given to `pkg upgrade` and `pkg upgrade -n` + (Default: empty) + + FPKG_SIGN + Marker for the begin of an output group (local host or jail) + (Default: "===> ") + + FPKG_SKIPSIGN + Marker for the begin of a skipped output group + (Default: "----> ") + + All other environment variables that affect `pkg` are effective also. +' + +# +# Configuration directory +# +: ${CONFIGDIR:=@@ETCDIR@@} + +test -r "${CONFIGDIR}/tools.conf" && . "${CONFIGDIR}/tools.conf" + +: ${FPKG_AUDIT_FLAGS:=-Fr} +: ${FPKG_UPDATE_FLAGS:=} +: ${FPKG_UPGRADE_FLAGS:=} +: ${FPKG_SIGN:='===> '} +: ${FPKG_SKIPSIGN:='----> '} + +# +# The official FreeBSD binary repository +# +: ${FREEBSD_REPO:=FreeBSD} + +# +# Local repository with ports with default OPTIONS (i.e. unchanged) +# but newer than the packages in the "FreeBSD" repository. +# Some sort of a fast-track repository. +# +: ${LOCALBSDPORTS_REPO:=LocalBSDPorts} + + +has_same_userland_version() { + : 'Check whether the jail `_jail` has the same FreeBSD userland version + as the host the the current process runs. + + Args: + _jail: the running jail to check for + + Returns: + 0 if the userland versions match, 1 otherwise + + ' + local _jail _host_version _jail_version + + _jail="$1" + + _host_version=$(/bin/freebsd-version -u) || exit 1 + _jail_version=$(jexec -l "${_jail}" /bin/freebsd-version -u) || exit 1 + if [ "${_host_version%%-*}" = "${_jail_version%%-*}" ]; then + return 0 + fi + return 1 +} + + +command_audit() { + : 'Do a local `pkg audit -Fr` and also for all running jails + + ' + echo "${FPKG_SIGN}LOCALHOST" + pkg audit ${FPKG_AUDIT_FLAGS} + for _j in $(jls -N | awk '{if(NR>1)print $1}' | sort); do + echo "" + echo "${FPKG_SIGN}JAIL: ${_j}" + if has_same_userland_version "${_j}"; then + pkg -j "${_j}" audit ${FPKG_AUDIT_FLAGS} + else + echo "${FPKG_SKIPSIGN}SKIPPED because of different userland" + fi + done +} + + +command_update() { + : 'Do a local `pkg update` and also for all running jails + + ' + echo "${FPKG_SIGN}LOCALHOST" + pkg update ${FPKG_UPDATE_FLAGS} + for _j in $(jls -N | awk '{if(NR>1)print $1}' | sort); do + echo "" + echo "${FPKG_SIGN}JAIL: ${_j}" + if has_same_userland_version "${_j}"; then + pkg -j "${_j}" update ${FPKG_UPDATE_FLAGS} + else + echo "${FPKG_SKIPSIGN}SKIPPED because of different userland" + fi + done +} + + +command_upgrade() { + : 'Do a local `pkg upgrade` and also for all running jails + + ' + echo "${FPKG_SIGN}LOCALHOST" + pkg upgrade ${FPKG_UPGRADE_FLAGS} + for _j in $(jls -N | awk '{if(NR>1)print $1}' | sort); do + echo "" + echo "${FPKG_SIGN}JAIL: ${_j}" + if has_same_userland_version "${_j}"; then + pkg -j "${_j}" upgrade ${FPKG_UPGRADE_FLAGS} + else + echo "${FPKG_SKIPSIGN}SKIPPED because of different userland" + fi + done +} + + +command_upgrade_check() { + : 'Do a local `pkg upgrade -n` and also for all running jails + + ' + echo "${FPKG_SIGN}LOCALHOST" + pkg upgrade -n ${FPKG_UPGRADE_FLAGS} + for _j in $(jls -N | awk '{if(NR>1)print $1}' | sort); do + echo "" + echo "${FPKG_SIGN}JAIL: ${_j}" + if has_same_userland_version "${_j}"; then + pkg -j "${_j}" upgrade -n ${FPKG_UPGRADE_FLAGS} + else + echo "${FPKG_SKIPSIGN}SKIPPED because of different userland" + fi + done +} + + +command_check_fasttrack() { + : 'Check the fast-track repository versions against the canonical + FreeBSD repository versions. + + Input (Globals): + FREEBSD_REPO: the (canonical) FreeBSD repository name + LOCALBSDPORTS_REPO: the fast-track repository name + + ' + local _name local _repo _j + + echo "${FPKG_SIGN}LOCALHOST" + pkg query '%n %R' | + while read _name _repo; do + if [ "${_repo}" = "${LOCALBSDPORTS_REPO}" ]; then + echo " ${_name}" + printf " %-15s : %s\n" "${LOCALBSDPORTS_REPO}" "$(pkg version -U -r ${LOCALBSDPORTS_REPO} -n ${_name} -v)" + printf " %-15s : %s\n" "${FREEBSD_REPO}" "$(pkg version -U -r ${FREEBSD_REPO} -n ${_name} -v)" + fi + done + for _j in $(jls -N | awk '{if(NR>1)print $1}' | sort); do + echo "" + echo "${FPKG_SIGN}JAIL: ${_j}" + if has_same_userland_version "${_j}"; then + pkg -j "${_j}" query '%n %R' | + while read _name _repo; do + if [ "${_repo}" = "${LOCALBSDPORTS_REPO}" ]; then + echo " ${_name}" + printf " %s-15s : %s\n" "${LOCALBSDPORTS_REPO}" "$(pkg -j ${_j} version -U -r ${LOCALBSDPORTS_REPO} -n ${_name} -v)" + printf " %-15s : %s\n" "${FREEBSD_REPO}" "$(pkg -j ${_j} version -U -r ${FREEBSD_REPO} -n ${_name} -v)" + fi + done + else + echo "${FPKG_SKIPSIGN}SKIPPED because of different userland" + fi + done +} + + +# +# Global option handling +# +while getopts "Vh" _opt ; do + case ${_opt} in + V) + echo "fpkg v${VERSION} (rv:@@HGREVISION@@)" + exit 0 + ;; + h) + echo "${USAGE}" + exit 0 + ;; + \?) + exit 2; + ;; + *) + echo "ERROR: option handling failed" >&2 + exit 2 + ;; + esac +done + +# +# Reset the Shell's option handling system to prepare for handling +# command-local options. +# +shift $((OPTIND-1)) +OPTIND=1 + +command="$1" +shift + +test -n "$command" || { echo "ERROR: no command given" >&2; exit 2; } + +case "${command}" in + audit) + command_audit "$@" + ;; + update) + command_update "$@" + ;; + upgrade) + command_upgrade "$@" + ;; + upgrade-check|upgrade_check) + command_upgrade_check "$@" + ;; + check-fast-track|check-fasttrack|check_fast_track|check_fasttrack) + command_check_fasttrack "$@" + ;; + *) + echo "ERROR: unknown command \`${command}'" >&2 + exit 2; + ;; +esac