diff options
Diffstat (limited to 'contrib')
-rwxr-xr-x | contrib/cpt-chroot | 92 | ||||
-rwxr-xr-x | contrib/cpt-size | 65 |
2 files changed, 113 insertions, 44 deletions
diff --git a/contrib/cpt-chroot b/contrib/cpt-chroot index 2f7eee7..a2ea151 100755 --- a/contrib/cpt-chroot +++ b/contrib/cpt-chroot @@ -1,22 +1,88 @@ #!/bin/sh -e # Enter a chroot +# shellcheck disable=2004 ## SYNOPSIS: ## .Nm cpt-chroot +## .Op Fl m ## .Op Ar dir ## DESCRIPTION: ## .Nm ## is a wrapper script to chroot inside other root filesystems. It automatically ## mounts important filesystems in to the chroot directory, and unmounts them -## when the user exits the chroot and cleans up leftover host files. +## when the user exits the chroot and cleans up leftover host files. If the flag +## .Fl m +## is given, +## .Nm +## does not try to mount or unmount any filesystems. + +# We generate the parser into the script, because we don't want this script to +# depend on cpt-lib. +nomount='' +REST='' +parse() { + OPTIND=$(($#+1)) + while OPTARG= && [ $# -gt 0 ]; do + case $1 in + --?*=*) OPTARG=$1; shift + eval 'set -- "${OPTARG%%\=*}" "${OPTARG#*\=}"' ${1+'"$@"'} + ;; + --no-*) unset OPTARG ;; + -[mh]?*) OPTARG=$1; shift + eval 'set -- "${OPTARG%"${OPTARG#??}"}" -"${OPTARG#??}"' ${1+'"$@"'} + OPTARG= ;; + esac + case $1 in + '-m') + [ "${OPTARG:-}" ] && OPTARG=${OPTARG#*\=} && set "noarg" "$1" && break + eval '[ ${OPTARG+x} ] &&:' && OPTARG='1' || OPTARG='' + nomount="$OPTARG" + ;; + '-h'|'--help') + usage + exit 0 ;; + --) + shift + while [ $# -gt 0 ]; do + REST="${REST} \"\${$(($OPTIND-$#))}\"" + shift + done + break ;; + [-]?*) + set "unknown" "$1"; break ;; + *) + REST="${REST} \"\${$(($OPTIND-$#))}\"" + esac + shift + done + [ $# -eq 0 ] && { OPTIND=1; unset OPTARG; return 0; } + case $1 in + unknown) set "Unrecognized option: $2" "$@" ;; + noarg) set "Does not allow an argument: $2" "$@" ;; + required) set "Requires an argument: $2" "$@" ;; + pattern:*) set "Does not match the pattern (${1#*:}): $2" "$@" ;; + notcmd) set "Not a command: $2" "$@" ;; + *) set "Validation error ($1): $2" "$@" + esac + echo "$1" >&2 + exit 1 +} +usage() { printf '%s\n' "usage: ${0##*/} [-m] [dir]" "" "Options:" \ + " -m Don't mount or unmount directories" +} + +parser_definition() { + setup REST help:usage -- "usage: ${0##*/} [-m] [dir]" + msg -- '' 'Options:' + flag nomount -m -- "Don't mount or unmount directories" + disp :usage -h --help hidden:1 +} log() { printf '\033[32m->\033[m %s.\n' "$*" } -usage() { printf '%s [dir]\n' "${0##*/}"; exit 0;} - die() { log "$*" >&2 exit 1 @@ -35,7 +101,7 @@ clean() { } main() { - case "$1" in ''|--help|-h) usage; esac + parse "$@" && eval set -- "$REST" [ -d "$1" ] || die Given path does not exist [ "$(id -u)" = 0 ] || die Script needs to be run as root @@ -48,17 +114,19 @@ main() { esac } - trap 'clean "$1"' EXIT INT + [ -z "$nomount" ] && { + trap 'clean "$1"' EXIT INT - log Mounting /dev, /proc and /sys from host; { - mountpoint -q "$1/dev" || mount -o bind /dev "$1/dev" - mountpoint -q "$1/proc" || mount -t proc proc "$1/proc" - mountpoint -q "$1/sys" || mount -t sysfs sys "$1/sys" + log Mounting /dev, /proc and /sys from host; { + mountpoint -q "$1/dev" || mount -o bind /dev "$1/dev" + mountpoint -q "$1/proc" || mount -t proc proc "$1/proc" + mountpoint -q "$1/sys" || mount -t sysfs sys "$1/sys" - } + } - log Copying /etc/resolv.conf from host; { - [ -f "$1/etc/resolv.conf" ] || cp /etc/resolv.conf "$1/etc" + log Copying /etc/resolv.conf from host; { + [ -f "$1/etc/resolv.conf" ] || cp /etc/resolv.conf "$1/etc" + } } log Entering chroot; { diff --git a/contrib/cpt-size b/contrib/cpt-size index 2812d56..4b983a1 100755 --- a/contrib/cpt-size +++ b/contrib/cpt-size @@ -11,40 +11,41 @@ ## .Ar packages ## using the files from the package manifest and outputs a total size of the ## packages along with all the files associated with them. +parser_definition() { + setup REST help:usage -- "usage: ${0##*/} [pkg...]" + disp :usage -h --help hidden:1 +} -## CAVEATS: -## .Nm -## uses the non-POSIX -## .Fl h -## and -## .Fl c -## flags for -## .Xr du 1 , -## which will not work with -## .Em sbase , -## but it is a major performance improvement compared to calculating -## total and human-readable sizes by hand. +# shellcheck source=../src/cpt-lib +# shellcheck disable=1091 +. cpt-lib -case "$1" in - --help|-h) - printf '%s\n' "usage: ${0##*/} [pkg...]" - exit 0 - ;; - '') set -- "${PWD##*/}" -esac +# Ensure that all the packages given as arguments are installed. +pkg_list "$@" >/dev/null -for pkg; do cpt-list "$pkg" >/dev/null; done +mkdir -p "$tmp_dir" -files= -for pkg; do - while read -r file; do - # Filter directories from manifest and leave only files. - # Directories in the manifest end in a trailing '/'. - case $file in */) continue; esac - files="$files '$file'" - done < "$CPT_ROOT/var/db/cpt/installed/$pkg/manifest" -done -eval "set -- $files" +# We don't immediately pipe into awk as we want to exit in an error. +for pkg; do sed '/\/$/d;s/./\\&/g' "$sys_db/$pkg/manifest"; done | + xargs du -k > "$tmp_dir/size" -# Send the file list to 'du'. -du -shc -- "$@" 2>/dev/null +# This awk function formats the `du` output similar to the '-hc' flags. We +# could have used a shell `while read` loop to do the exact same thing, but that +# would be much much slower. +awk 'function fmtsize(s) { + if (s==0) f="" + else if (s<1024) f="K" + else if (s<(1048576)){f="M";s=s/1024;} + else if (s<(1073741824)){f="G";s=s/1048576;} + else f="" + return int(s) f + } + { + sc = $1 + size += $1 + sub(sprintf("^%s\s*", $1), "") + printf("%-6s %s\n", fmtsize(sc), $0) + } + END { + printf("%-6s total\n", fmtsize(size)) + }' "$tmp_dir/size" |