# -*- Shell-script -*- # Copyright (C) 2007 - 2021 Steve Youngs # # A collection of Zsh functions that I use day to day for maintaining # and administering my machines. These come in very handy if you set up # one of your users as a "package manager". There is a corresponding # _zsh-pkgtools file that provides completion for most of what is here. ## Help H-pkg () { cat< -- print the source repo location of PKG with optional 2nd arg non-nil, also print repo type. pkgsu [PKGUSR] -- switch to user PKGUSR. pkg_install [DESCRIPTION] [USER] [GROUP] -- install a new package, DESCRIPTION must be quoted. pkg_ldconfig -- Run ldconfig. xtar [FILE] -- extract tarball FILE. vtar [FILE] -- view the contents of tarball FILE. ctar [FILE] [DIRECTORY] -- create a tarball FILE of DIRECTORY. Compression is automatically chosen from the filename. deadlibs [LIBNAME] -- print processes using deleted library, LIBNAME EOF } ## Keep a list of all packages. # This needs sudo setup to allow the "package manager" to run commands # with no password. I gave the wheel group such access. pkglst () { PKGLST=($(sudo groupmems -lg install)) } ## Find packages matching a regexp fpkg () { if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [REGEXP]" >&2 return 1 else print ${PKGLST[*]}|tr ' ' '\n'|grep -iE --colour ${argv[1]} fi } ## Print a package's .project ppkg () { if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [NAME]" >&2 return 1 else pinky -l $argv[1]|less fi } ## Find package names for commands matching regexp cpkg () { if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [CMD]" >&2 return 1 else find $path -type f -regex "^.*/$argv[1].*$" \ -printf "%f -- (%u:%g)\n"|grep --colour '(.*)' fi } ## List all packages lpkg () { print ${PKGLST[*]}|tr ' ' '\n'|less } ## Show date/time a package was last updated upkg() { if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [PKG]" >&2 return 1 else grep --colour 'Last_Updated: ' ~$argv[1]/.project fi } ## List all packages with last-updated date/time Lpkg () { for ((i=1; i<=${#PKGLST}; i++)); do print "${PKGLST[${i}]}#$(upkg ${PKGLST[${i}]}|cut -d' ' -f3-)" done|column -t -s\#|less } ## Display a package's version vpkg() { if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [PKG]" >&2 return 1 else grep --colour 'Version: ' ~$argv[1]/.project fi } ## Display a package's install notes ipkg() { if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [PKG]" >&2 return 1 else local top=$(grep -n "Install Notes" ~$argv[1]/.project|cut -d: -f1) local bot=$(grep -n "General Notes" ~$argv[1]/.project|cut -d: -f1) sed -n ${top},${bot}p ~$argv[1]/.project|less fi } ## Display a package's general notes gpkg() { if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [PKG]" >&2 return 1 else local top=$(grep -n "General Notes" ~$argv[1]/.project|cut -d: -f1) local bot=$(grep -n "CONTENTS" ~$argv[1]/.project|cut -d: -f1) sed -n ${top},${bot}p ~$argv[1]/.project|less fi } ## Display a package's short description dpkg() { if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [PKG]" >&2 return 1 else grep --colour 'Description: ' ~$argv[1]/.project fi } ## Display a package's long description Dpkg() { if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [PKG]" >&2 return 1 else local top=$(grep -n "Description:" ~$argv[1]/.project|cut -d: -f1) local bot=$(grep -n "Repo_Type:" ~$argv[1]/.project|cut -d: -f1) sed -n ${top},${bot}p ~$argv[1]/.project|less fi } ## Display a package's website wpkg() { if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [PKG]" >&2 return 1 else grep --colour 'Web_Site: ' ~$argv[1]/.project fi } ## Display a package's dependencies pkgdeps() { if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [PKG]" >&2 return 1 else grep --colour 'Deps: ' ~$argv[1]/.project fi } ## Display a package's repo URL pkgrepo() { if [[ $ARGC -lt 1 || $ARGC -gt 2 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [PKG] " >&2 return 1 else grep --colour 'Repo_Location: ' ~$argv[1]/.project [[ -n "$argv[2]" ]] && grep --colour 'Repo_Type: ' ~$argv[1]/.project fi } ## Display all packages that depend on package pkgwant() { if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then echo Invalid or mission argument >&2 echo "Usage: $0 [PKG]" >&2 return 1 fi for p in ${PKGLST[@]}; do pkgdeps ${p} | grep -wq $argv[1] && print ${p} done } ## Convenience: create tarballs ctar() { if [[ $ARGC -ne 2 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [FILE] [DIRECTORY]" >&2 return 1 fi local opts opts=(--create --owner=0 --group=0 --auto-compress --file) tar ${opts} $1 $2 } ## Change to package user pkgsu() { if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [PKGUSR]" >&2 return 1 else ssh -l root localhost -t DISPLAY=${DISPLAY} su - $argv[1] fi } ## Install new package pkg_install() { if [[ $ARGC -lt 3 || $ARGC -gt 3 ]]; then echo Invalid or missing argument >&2 echo "Usage: $0 [DESCRIPTION] [USER] [GROUP]" >&2 return 1 else ssh -l root localhost -t install_package \ ${argv[1]} $argv[2] $argv[3] fi && pkglst } ## See what is currently using now deleted libs deadlibs() { if [[ $ARGC -ne 1 ]]; then echo 1>&2 Invalid or missing argument echo 1>&2 "Usage: $0 [LIBNAME]" return 1 fi ssh root@localhost grep -l -e "${argv[1]}.*deleted" /proc/*/maps | tr -cd 0-9\\n | xargs -r ps --no-headers | awk '{print $5}' } ## Couple handy aliases alias pkg_ldconfig='ssh -l root localhost ldconfig' alias vtar=less alias xtar='tar xf' ## On-Load actions pkglst ### End