From 71fcb69028d6e02bc7f24459918e504d261f86cd Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Thu, 19 Apr 2012 12:46:48 -0400 Subject: contrib: use a separate build rule for bash scripts Treat bash scripts separately from the others to allow for a different build rule, which is reused from the scripts/ subdir. Signed-off-by: Dave Reisner --- contrib/Makefile.am | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/contrib/Makefile.am b/contrib/Makefile.am index a3d2d42b..3936e23d 100644 --- a/contrib/Makefile.am +++ b/contrib/Makefile.am @@ -4,16 +4,22 @@ AUTOMAKE_OPTIONS = std-options bin_SCRIPTS = \ $(OURSCRIPTS) -OURSCRIPTS = \ +BASHSCRIPTS = \ bacman \ paccache \ pacdiff \ paclist \ paclog-pkglist \ pacscripts \ - pacsearch \ pacsysclean +OTHERSCRIPTS = \ + pacsearch + +OURSCRIPTS = \ + $(BASHSCRIPTS) \ + $(OTHERSCRIPTS) + OURFILES = \ bash_completion \ zsh_completion @@ -50,12 +56,17 @@ edit = sed \ -e 's|@SIZECMD[@]|$(SIZECMD)|g' \ -e '1s|!/bin/bash|!$(BASH_SHELL)|g' -$(OURSCRIPTS): Makefile +$(OTHERSCRIPTS): Makefile $(AM_V_at)$(RM) $@ $@.tmp $(AM_V_GEN)$(edit) $(srcdir)/$@.in >$@.tmp $(AM_V_at)chmod +x,a-w $@.tmp $(AM_V_at)mv $@.tmp $@ +$(BASHSCRIPTS): Makefile + $(AM_V_at)$(RM) $@ + $(AM_V_GEN)test -f $(srcdir)/$@.in && m4 -P -I $(srcdir) $(srcdir)/$@.in | $(edit) >$@ + $(AM_V_at)chmod +x,a-w $@ + $(OURFILES): Makefile $(AM_V_at)$(RM) $@ $@.tmp $(AM_V_GEN)$(edit) $(srcdir)/$@.in >$@.tmp -- cgit v1.2.3-24-g4f1b From 1b494ab77198a6cbb9c06a13435159641e2dc0c5 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Thu, 19 Apr 2012 12:55:20 -0400 Subject: contrib: rename bash scripts: .in -> .sh.in For consistency with the scripts/ directory, ensure that all bash scripts use the same pre-build suffix. Signed-off-by: Dave Reisner --- contrib/Makefile.am | 30 ++-- contrib/bacman.in | 308 ----------------------------------------- contrib/bacman.sh.in | 307 +++++++++++++++++++++++++++++++++++++++++ contrib/paccache.in | 319 ------------------------------------------- contrib/paccache.sh.in | 319 +++++++++++++++++++++++++++++++++++++++++++ contrib/pacdiff.in | 92 ------------- contrib/pacdiff.sh.in | 92 +++++++++++++ contrib/paclist.in | 64 --------- contrib/paclist.sh.in | 64 +++++++++ contrib/paclog-pkglist.in | 83 ----------- contrib/paclog-pkglist.sh.in | 83 +++++++++++ contrib/pacscripts.in | 138 ------------------- contrib/pacscripts.sh.in | 138 +++++++++++++++++++ contrib/pacsysclean.in | 62 --------- contrib/pacsysclean.sh.in | 62 +++++++++ 15 files changed, 1080 insertions(+), 1081 deletions(-) delete mode 100755 contrib/bacman.in create mode 100755 contrib/bacman.sh.in delete mode 100755 contrib/paccache.in create mode 100755 contrib/paccache.sh.in delete mode 100755 contrib/pacdiff.in create mode 100755 contrib/pacdiff.sh.in delete mode 100755 contrib/paclist.in create mode 100755 contrib/paclist.sh.in delete mode 100755 contrib/paclog-pkglist.in create mode 100755 contrib/paclog-pkglist.sh.in delete mode 100755 contrib/pacscripts.in create mode 100755 contrib/pacscripts.sh.in delete mode 100755 contrib/pacsysclean.in create mode 100755 contrib/pacsysclean.sh.in diff --git a/contrib/Makefile.am b/contrib/Makefile.am index 3936e23d..5139b54d 100644 --- a/contrib/Makefile.am +++ b/contrib/Makefile.am @@ -26,15 +26,15 @@ OURFILES = \ EXTRA_DIST = \ PKGBUILD.vim \ - bacman.in \ + bacman.sh.in \ bash_completion.in \ - paccache.in \ - paclog-pkglist.in \ - pacdiff.in \ - paclist.in \ - pacscripts.in \ + paccache.sh.in \ + paclog-pkglist.sh.in \ + pacdiff.sh.in \ + paclist.sh.in \ + pacscripts.sh.in \ pacsearch.in \ - pacsysclean.in \ + pacsysclean.sh.in \ vimprojects \ zsh_completion.in \ README @@ -64,7 +64,7 @@ $(OTHERSCRIPTS): Makefile $(BASHSCRIPTS): Makefile $(AM_V_at)$(RM) $@ - $(AM_V_GEN)test -f $(srcdir)/$@.in && m4 -P -I $(srcdir) $(srcdir)/$@.in | $(edit) >$@ + $(AM_V_GEN)test -f $(srcdir)/$@.sh.in && m4 -P -I $(srcdir) $(srcdir)/$@.sh.in | $(edit) >$@ $(AM_V_at)chmod +x,a-w $@ $(OURFILES): Makefile @@ -85,15 +85,15 @@ uninstall-local: $(RM) $(DESTDIR)$(sysconfdir)/bash_completion.d/pacman $(RM) $(DESTDIR)$(datarootdir)/zsh/site-functions/_pacman -bacman: $(srcdir)/bacman.in +bacman: $(srcdir)/bacman.sh.in bash_completion: $(srcdir)/bash_completion.in -paccache: $(srcdir)/paccache.in -pacdiff: $(srcdir)/pacdiff.in -paclist: $(srcdir)/paclist.in -paclog-pkglist: $(srcdir)/paclog-pkglist.in -pacscripts: $(srcdir)/pacscripts.in +paccache: $(srcdir)/paccache.sh.in +pacdiff: $(srcdir)/pacdiff.sh.in +paclist: $(srcdir)/paclist.sh.in +paclog-pkglist: $(srcdir)/paclog-pkglist.sh.in +pacscripts: $(srcdir)/pacscripts.sh.in pacsearch: $(srcdir)/pacsearch.in -pacsysclean: $(srcdir)/pacsysclean.in +pacsysclean: $(srcdir)/pacsysclean.sh.in zsh_completion: $(srcdir)/zsh_completion.in # vim:set ts=2 sw=2 noet: diff --git a/contrib/bacman.in b/contrib/bacman.in deleted file mode 100755 index 93623565..00000000 --- a/contrib/bacman.in +++ /dev/null @@ -1,308 +0,0 @@ -#!/bin/bash -# -# bacman: recreate a package from a running system -# This script rebuilds an already installed package using metadata -# stored into the pacman database and system files -# -# (c) 2008 - locci -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -shopt -s extglob -shopt -s nullglob - -declare -r myname='bacman' -declare -r myver='@PACKAGE_VERSION@' - -# -# User Friendliness -# -usage() { - echo "This program recreates a package using pacman's db and system files" - echo "Usage: $myname " - echo "Example: $myname kernel26" -} - -version() { - printf "%s %s\n" "$myname" "$myver" - echo 'Copyright (C) 2008 locci ' -} - -if (( $# != 1 )); then - usage - exit 1 -fi - -if [[ $1 = -@(h|-help) ]]; then - usage - exit 0 -elif [[ $1 = -@(V|-version) ]]; then - version - exit 0 -fi - -# -# Fakeroot support -# -if (( EUID )); then - if [[ -f /usr/bin/fakeroot ]]; then - echo "Entering fakeroot environment" - export INFAKEROOT="1" - /usr/bin/fakeroot -u -- "$0" "$@" - exit $? - else - echo "WARNING: installing fakeroot or running $myname as root is required to" - echo " preserve the ownership permissions of files in some packages" - echo "" - fi -fi - -# -# Setting environmental variables -# -if [[ ! -r @sysconfdir@/pacman.conf ]]; then - echo "ERROR: unable to read @sysconfdir@/pacman.conf" - exit 1 -fi - -eval $(awk '/DBPath/ {print $1$2$3}' @sysconfdir@/pacman.conf) -pac_db="${DBPath:-@localstatedir@/lib/pacman/}/local" - -if [[ ! -r @sysconfdir@/makepkg.conf ]]; then - echo "ERROR: unable to read @sysconfdir@/makepkg.conf" - exit 1 -fi - -source "@sysconfdir@/makepkg.conf" -if [[ -r ~/.makepkg.conf ]]; then - source ~/.makepkg.conf -fi - -pkg_arch=${CARCH:-'unknown'} -pkg_dest="${PKGDEST:-$PWD}" -pkg_pkger=${PACKAGER:-'Unknown Packager'} - -pkg_name="$1" -pkg_dir=("$pac_db/$pkg_name"-+([^-])-+([^-])) -pkg_namver=("${pkg_dir[@]##*/}") - -# -# Checks everything is in place -# -if [[ ! -d $pac_db ]]; then - echo "ERROR: pacman database directory ${pac_db} not found" - exit 1 -fi - -if (( ${#pkg_dir[@]} != 1 )); then - printf "ERROR: %d entries for package %s found in pacman database\n" \ - ${#pkg_dir[@]} "${pkg_name}" - printf "%s\n" "${pkg_dir[@]}" - exit 1 -fi - -if [[ ! -d $pkg_dir ]]; then - printf "ERROR: package %s is found in pacman database,\n" "${pkg_name}" - printf " but \`%s' is not a directory\n" "${pkg_dir}" - exit 1 -fi - -# -# Begin -# -echo "Package: ${pkg_namver}" -work_dir=$(mktemp -d --tmpdir bacman.XXXXXXXXXX) -cd "$work_dir" || exit 1 - -# -# File copying -# -echo "Copying package files..." - -cat "$pkg_dir"/files | -while read i; do - if [[ -z $i ]]; then - continue - fi - - if [[ $i == %+([A-Z])% ]]; then - current=$i - continue - fi - - case "$current" in - %FILES%) - ret=0 - if [[ -e /$i ]]; then - bsdtar -cnf - "/$i" 2> /dev/null | bsdtar -xpf - - - # Workaround to bsdtar not reporting a missing file as an error - if ! [[ -e $work_dir/$i || -L $work_dir/$i ]]; then - echo "" - echo "ERROR: unable to add /$i to the package" - echo " If your user does not have permssion to read this file then" - echo " you will need to run $myname as root" - rm -rf "$work_dir" - exit 1 - fi - else - echo "" - echo "WARNING: package file /$i is missing" - echo "" - fi - ;; - esac -done - -ret=$? -if (( ret )); then - rm -rf "$work_dir" - exit 1 -fi - -pkg_size=$(du -sk | awk '{print $1 * 1024}') - -# -# .PKGINFO stuff -# TODO adopt makepkg's write_pkginfo() into this or scripts/library -# -echo Generating .PKGINFO metadata... -echo "# Generated by $myname $myver" > .PKGINFO -if [[ $INFAKEROOT == "1" ]]; then - echo "# Using $(fakeroot -v)" >> .PKGINFO -fi -echo "# $(LC_ALL=C date)" >> .PKGINFO -echo "#" >> .PKGINFO - -cat "$pkg_dir"/{desc,files} | -while read i; do - if [[ -z $i ]]; then - continue; - fi - - if [[ $i == %+([A-Z])% ]]; then - current=$i - continue - fi - - case "$current" in - # desc - %NAME%) - echo "pkgname = $i" >> .PKGINFO - ;; - %VERSION%) - echo "pkgver = $i" >> .PKGINFO - ;; - %DESC%) - echo "pkgdesc = $i" >> .PKGINFO - ;; - %URL%) - echo "url = $i" >> .PKGINFO - ;; - %LICENSE%) - echo "license = $i" >> .PKGINFO - ;; - %ARCH%) - echo "arch = $i" >> .PKGINFO - ;; - %BUILDDATE%) - echo "builddate = $(date -u "+%s")" >> .PKGINFO - ;; - %PACKAGER%) - echo "packager = $pkg_pkger" >> .PKGINFO - ;; - %SIZE%) - echo "size = $pkg_size" >> .PKGINFO - ;; - %GROUPS%) - echo "group = $i" >> .PKGINFO - ;; - %REPLACES%) - echo "replaces = $i" >> .PKGINFO - ;; - %DEPENDS%) - echo "depend = $i" >> .PKGINFO - ;; - %OPTDEPENDS%) - echo "optdepend = $i" >> .PKGINFO - ;; - %CONFLICTS%) - echo "conflict = $i" >> .PKGINFO - ;; - %PROVIDES%) - echo "provides = $i" >> .PKGINFO - ;; - - # files - %BACKUP%) - # strip the md5sum after the tab - echo "backup = ${i%%$'\t'*}" >> .PKGINFO - ;; - esac -done - -comp_files=".PKGINFO" - -if [[ -f $pkg_dir/install ]]; then - cp "$pkg_dir/install" "$work_dir/.INSTALL" - comp_files+=" .INSTALL" -fi -if [[ -f $pkg_dir/changelog ]]; then - cp "$pkg_dir/changelog" "$work_dir/.CHANGELOG" - comp_files+=" .CHANGELOG" -fi - -# -# Fixes owner:group and permissions for .PKGINFO, .CHANGELOG, .INSTALL -# -chown root:root "$work_dir"/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null -chmod 644 "$work_dir"/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null - -# -# Generate the package -# -echo "Generating the package..." - -pkg_file="$pkg_dest/$pkg_namver-$pkg_arch${PKGEXT}" -ret=0 - -# TODO: Maybe this can be set globally for robustness -shopt -s -o pipefail -bsdtar -cf - $comp_files * | -case "$PKGEXT" in - *tar.gz) gzip -c -f -n ;; - *tar.bz2) bzip2 -c -f ;; - *tar.xz) xz -c -z - ;; - *tar.Z) compress -c -f ;; - *tar) cat ;; - *) echo "WARNING: '%s' is not a valid archive extension." \ - "$PKGEXT" >&2; cat ;; -esac > "${pkg_file}"; ret=$? - -if (( ret )); then - echo "ERROR: unable to write package to $pkg_dest" - echo " Maybe the disk is full or you do not have write access" - rm -rf "$work_dir" - exit 1 -fi - -rm -rf "$work_dir" - -echo Done - -exit 0 - -# vim: set ts=2 sw=2 noet: - diff --git a/contrib/bacman.sh.in b/contrib/bacman.sh.in new file mode 100755 index 00000000..ffb9d6d3 --- /dev/null +++ b/contrib/bacman.sh.in @@ -0,0 +1,307 @@ +#!/bin/bash +# +# bacman: recreate a package from a running system +# This script rebuilds an already installed package using metadata +# stored into the pacman database and system files +# +# (c) 2008 - locci +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +shopt -s extglob +shopt -s nullglob + +declare -r myname='bacman' +declare -r myver='@PACKAGE_VERSION@' + +# +# User Friendliness +# +usage() { + echo "This program recreates a package using pacman's db and system files" + echo "Usage: $myname " + echo "Example: $myname kernel26" +} + +version() { + printf "%s %s\n" "$myname" "$myver" + echo 'Copyright (C) 2008 locci ' +} + +if (( $# != 1 )); then + usage + exit 1 +fi + +if [[ $1 = -@(h|-help) ]]; then + usage + exit 0 +elif [[ $1 = -@(V|-version) ]]; then + version + exit 0 +fi + +# +# Fakeroot support +# +if (( EUID )); then + if [[ -f /usr/bin/fakeroot ]]; then + echo "Entering fakeroot environment" + export INFAKEROOT="1" + /usr/bin/fakeroot -u -- "$0" "$@" + exit $? + else + echo "WARNING: installing fakeroot or running $myname as root is required to" + echo " preserve the ownership permissions of files in some packages" + echo "" + fi +fi + +# +# Setting environmental variables +# +if [[ ! -r @sysconfdir@/pacman.conf ]]; then + echo "ERROR: unable to read @sysconfdir@/pacman.conf" + exit 1 +fi + +eval $(awk '/DBPath/ {print $1$2$3}' @sysconfdir@/pacman.conf) +pac_db="${DBPath:-@localstatedir@/lib/pacman/}/local" + +if [[ ! -r @sysconfdir@/makepkg.conf ]]; then + echo "ERROR: unable to read @sysconfdir@/makepkg.conf" + exit 1 +fi + +source "@sysconfdir@/makepkg.conf" +if [[ -r ~/.makepkg.conf ]]; then + source ~/.makepkg.conf +fi + +pkg_arch=${CARCH:-'unknown'} +pkg_dest="${PKGDEST:-$PWD}" +pkg_pkger=${PACKAGER:-'Unknown Packager'} + +pkg_name="$1" +pkg_dir=("$pac_db/$pkg_name"-+([^-])-+([^-])) +pkg_namver=("${pkg_dir[@]##*/}") + +# +# Checks everything is in place +# +if [[ ! -d $pac_db ]]; then + echo "ERROR: pacman database directory ${pac_db} not found" + exit 1 +fi + +if (( ${#pkg_dir[@]} != 1 )); then + printf "ERROR: %d entries for package %s found in pacman database\n" \ + ${#pkg_dir[@]} "${pkg_name}" + printf "%s\n" "${pkg_dir[@]}" + exit 1 +fi + +if [[ ! -d $pkg_dir ]]; then + printf "ERROR: package %s is found in pacman database,\n" "${pkg_name}" + printf " but \`%s' is not a directory\n" "${pkg_dir}" + exit 1 +fi + +# +# Begin +# +echo "Package: ${pkg_namver}" +work_dir=$(mktemp -d --tmpdir bacman.XXXXXXXXXX) +cd "$work_dir" || exit 1 + +# +# File copying +# +echo "Copying package files..." + +cat "$pkg_dir"/files | +while read i; do + if [[ -z $i ]]; then + continue + fi + + if [[ $i == %+([A-Z])% ]]; then + current=$i + continue + fi + + case "$current" in + %FILES%) + ret=0 + if [[ -e /$i ]]; then + bsdtar -cnf - "/$i" 2> /dev/null | bsdtar -xpf - + + # Workaround to bsdtar not reporting a missing file as an error + if ! [[ -e $work_dir/$i || -L $work_dir/$i ]]; then + echo "" + echo "ERROR: unable to add /$i to the package" + echo " If your user does not have permssion to read this file then" + echo " you will need to run $myname as root" + rm -rf "$work_dir" + exit 1 + fi + else + echo "" + echo "WARNING: package file /$i is missing" + echo "" + fi + ;; + esac +done + +ret=$? +if (( ret )); then + rm -rf "$work_dir" + exit 1 +fi + +pkg_size=$(du -sk | awk '{print $1 * 1024}') + +# +# .PKGINFO stuff +# TODO adopt makepkg's write_pkginfo() into this or scripts/library +# +echo Generating .PKGINFO metadata... +echo "# Generated by $myname $myver" > .PKGINFO +if [[ $INFAKEROOT == "1" ]]; then + echo "# Using $(fakeroot -v)" >> .PKGINFO +fi +echo "# $(LC_ALL=C date)" >> .PKGINFO +echo "#" >> .PKGINFO + +cat "$pkg_dir"/{desc,files} | +while read i; do + if [[ -z $i ]]; then + continue; + fi + + if [[ $i == %+([A-Z])% ]]; then + current=$i + continue + fi + + case "$current" in + # desc + %NAME%) + echo "pkgname = $i" >> .PKGINFO + ;; + %VERSION%) + echo "pkgver = $i" >> .PKGINFO + ;; + %DESC%) + echo "pkgdesc = $i" >> .PKGINFO + ;; + %URL%) + echo "url = $i" >> .PKGINFO + ;; + %LICENSE%) + echo "license = $i" >> .PKGINFO + ;; + %ARCH%) + echo "arch = $i" >> .PKGINFO + ;; + %BUILDDATE%) + echo "builddate = $(date -u "+%s")" >> .PKGINFO + ;; + %PACKAGER%) + echo "packager = $pkg_pkger" >> .PKGINFO + ;; + %SIZE%) + echo "size = $pkg_size" >> .PKGINFO + ;; + %GROUPS%) + echo "group = $i" >> .PKGINFO + ;; + %REPLACES%) + echo "replaces = $i" >> .PKGINFO + ;; + %DEPENDS%) + echo "depend = $i" >> .PKGINFO + ;; + %OPTDEPENDS%) + echo "optdepend = $i" >> .PKGINFO + ;; + %CONFLICTS%) + echo "conflict = $i" >> .PKGINFO + ;; + %PROVIDES%) + echo "provides = $i" >> .PKGINFO + ;; + + # files + %BACKUP%) + # strip the md5sum after the tab + echo "backup = ${i%%$'\t'*}" >> .PKGINFO + ;; + esac +done + +comp_files=".PKGINFO" + +if [[ -f $pkg_dir/install ]]; then + cp "$pkg_dir/install" "$work_dir/.INSTALL" + comp_files+=" .INSTALL" +fi +if [[ -f $pkg_dir/changelog ]]; then + cp "$pkg_dir/changelog" "$work_dir/.CHANGELOG" + comp_files+=" .CHANGELOG" +fi + +# +# Fixes owner:group and permissions for .PKGINFO, .CHANGELOG, .INSTALL +# +chown root:root "$work_dir"/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null +chmod 644 "$work_dir"/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null + +# +# Generate the package +# +echo "Generating the package..." + +pkg_file="$pkg_dest/$pkg_namver-$pkg_arch${PKGEXT}" +ret=0 + +# TODO: Maybe this can be set globally for robustness +shopt -s -o pipefail +bsdtar -cf - $comp_files * | +case "$PKGEXT" in + *tar.gz) gzip -c -f -n ;; + *tar.bz2) bzip2 -c -f ;; + *tar.xz) xz -c -z - ;; + *tar.Z) compress -c -f ;; + *tar) cat ;; + *) echo "WARNING: '%s' is not a valid archive extension." \ + "$PKGEXT" >&2; cat ;; +esac > "${pkg_file}"; ret=$? + +if (( ret )); then + echo "ERROR: unable to write package to $pkg_dest" + echo " Maybe the disk is full or you do not have write access" + rm -rf "$work_dir" + exit 1 +fi + +rm -rf "$work_dir" + +echo Done + +exit 0 + +# vim: set ts=2 sw=2 noet: diff --git a/contrib/paccache.in b/contrib/paccache.in deleted file mode 100755 index da65f476..00000000 --- a/contrib/paccache.in +++ /dev/null @@ -1,319 +0,0 @@ -#!/bin/bash -# -# pacache - flexible pacman cache cleaning -# -# Copyright (C) 2011 Dave Reisner -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - - -shopt -s extglob - -declare -r myname='paccache' -declare -r myver='@PACKAGE_VERSION@' - -declare -a candidates=() cmdopts=() whitelist=() blacklist=() -declare -i delete=0 dryrun=0 filecount=0 move=0 needsroot=0 totalsaved=0 verbose=0 -declare cachedir=@localstatedir@/cache/pacman/pkg delim=$'\n' keep=3 movedir= scanarch= - -msg() { - local mesg=$1; shift - printf "==> $mesg\n" "$@" -} >&2 - -error() { - local mesg=$1; shift - printf "==> ERROR: $mesg\n" "$@" -} >&2 - -die() { - error "$@" - exit 1 -} - -# reads a list of files on stdin and prints out deletion candidates -pkgfilter() { - # there's whitelist and blacklist parameters passed to this - # script after the block of awk. - - awk -v keep="$1" -v scanarch="$2" ' - function parse_filename(filename, parts, count, i, pkgname, arch) { - - count = split(filename, parts, "-") - - i = 1 - pkgname = parts[i++] - while (i <= count - 3) { - pkgname = pkgname "-" parts[i++] - } - - arch = substr(parts[count], 1, index(parts[count], ".") - 1) - - # filter on whitelist or blacklist - if (wlen && !whitelist[pkgname]) return - if (blen && blacklist[pkgname]) return - - if ("" == packages[pkgname,arch]) { - packages[pkgname,arch] = filename - } else { - packages[pkgname,arch] = packages[pkgname,arch] SUBSEP filename - } - } - - BEGIN { - # create whitelist - wlen = ARGV[1]; delete ARGV[1] - for (i = 2; i < 2 + wlen; i++) { - whitelist[ARGV[i]] = 1 - delete ARGV[i] - } - - # create blacklist - blen = ARGV[i]; delete ARGV[i] - while (i++ < ARGC) { - blacklist[ARGV[i]] = 1 - delete ARGV[i] - } - - # read package filenames - while (getline < "/dev/stdin") { - parse_filename($0) - } - - for (pkglist in packages) { - # idx[1,2] = idx[pkgname,arch] - split(pkglist, idx, SUBSEP) - - # enforce architecture match if specified - if (!scanarch || scanarch == idx[2]) { - count = split(packages[idx[1], idx[2]], pkgs, SUBSEP) - for(i = 1; i <= count - keep; i++) { - print pkgs[i] - } - } - } - }' "${@:3}" -} - -size_to_human() { - awk -v size="$1" ' - BEGIN { - suffix[1] = "B" - suffix[2] = "KiB" - suffix[3] = "MiB" - suffix[4] = "GiB" - suffix[5] = "TiB" - count = 1 - - while (size > 1024) { - size /= 1024 - count++ - } - - sizestr = sprintf("%.2f", size) - sub(/\.?0+$/, "", sizestr) - printf("%s %s", sizestr, suffix[count]) - }' -} - -runcmd() { - if (( needsroot )); then - msg "Privilege escalation required" - if sudo -v &>/dev/null && sudo -l &>/dev/null; then - sudo "$@" - else - printf '%s ' 'root' - su -c "$(printf '%q ' "$@")" - fi - else - "$@" - fi -} - -summarize() { - local -i filecount=$1; shift - local seenarch= seen= arch= name= - local -r pkg_re='(.+)-[^-]+-[0-9]+-([^.]+)\.pkg.*' - - if (( delete )); then - printf -v output 'finished: %d packages removed' "$filecount" - elif (( move )); then - printf -v output "finished: %d packages moved to \`%s'" "$filecount" "$movedir" - elif (( dryrun )); then - if (( verbose )); then - msg "Candidate packages:" - while read -r pkg; do - if (( verbose >= 3 )); then - [[ $pkg =~ $pkg_re ]] && name=${BASH_REMATCH[1]} arch=${BASH_REMATCH[2]} - if [[ -z $seen || $seenarch != "$arch" || $seen != "$name" ]]; then - seen=$name seenarch=$arch - printf '%s (%s):\n' "$name" "$arch" - fi - printf ' %s\n' "$pkg" - elif (( verbose >= 2 )); then - printf "$PWD/%s$delim" "$pkg" - else - printf "%s$delim" "$pkg" - fi - done < <(printf '%s\n' "$@" | pacsort) - fi - printf -v output 'finished dry run: %d candidates' "$filecount" - fi - - printf '\n' >&2 - msg "$output (diskspace saved: %s)" "$(size_to_human "$totalsaved")" -} - -usage() { - cat < [options] [targets...] - -$myname is a flexible pacman cache cleaning utility, which has numerous -options to help control how much, and what, is deleted from any directory -containing pacman package tarballs. - - Operations: - -d perform a dry run, only finding candidate packages. - -m move candidate packages to 'movedir'. - -r remove candidate packages. - - Options: - -a scan for 'arch' (default: all architectures). - -c scan 'cachedir' for packages (default: @localstatedir@/cache/pacman/pkg). - -f apply force to mv(1) and rm(1) operations. - -h display this help message. - -i ignore 'pkgs', which is a comma separated. Alternatively, - specify '-' to read package names from stdin, newline delimited. - -k keep 'num' of each package in 'cachedir' (default: 3). - -u target uninstalled packages. - -v increase verbosity. specify up to 3 times. - -z use null delimiters for candidate names (only with -v and -vv) - -EOF -} - -version() { - printf "%s %s\n" "$myname" "$myver" - echo 'Copyright (C) 2011 Dave Reisner ' -} - -if (( ! UID )); then - error "Do not run this script as root. You will be prompted for privilege escalation." - exit 42 -fi - -# TODO: remove this workaround and use a sane command line parser (like the -# parse_options library from scripts/) here -if [[ $1 = -@(h|-help) ]]; then - usage - exit 0 -elif [[ $1 = -@(V|-version) ]]; then - version - exit 0 -fi - -while getopts ':a:c:dfi:k:m:rsuvz' opt; do - case $opt in - a) scanarch=$OPTARG ;; - c) cachedir=$OPTARG ;; - d) dryrun=1 ;; - f) cmdopts=(-f) ;; - i) if [[ $OPTARG = '-' ]]; then - [[ ! -t 0 ]] && IFS=$'\n' read -r -d '' -a ign - else - IFS=',' read -r -a ign <<< "$OPTARG" - fi - blacklist+=("${ign[@]}") - unset i ign ;; - k) keep=$OPTARG - if [[ -z $keep || -n ${keep//[0-9]/} ]]; then - die 'argument to option -k must be a non-negative integer' - else - keep=$(( 10#$keep )) - fi ;; - m) move=1 movedir=$OPTARG ;; - r) delete=1 ;; - u) IFS=$'\n' read -r -d '' -a ign < <(pacman -Qq) - blacklist+=("${ign[@]}") - unset ign ;; - v) (( ++verbose )) ;; - z) delim='\0' ;; - :) die "option '--%s' requires an argument" "$OPTARG" ;; - ?) die "invalid option -- '%s'" "$OPTARG" ;; - esac -done -shift $(( OPTIND - 1 )) - -# remaining args are a whitelist -whitelist=("$@") - -# sanity checks -case $(( dryrun+delete+move )) in - 0) die "no operation specified (use -h for help)" ;; - [^1]) die "only one operation may be used at a time" ;; -esac - -[[ -d $cachedir ]] || - die "cachedir \`%s' does not exist or is not a directory" "$cachedir" - -[[ $movedir && ! -d $movedir ]] && - die "move-to directory \`%s' does not exist or is not a directory" "$movedir" - -if (( move || delete )); then - # make it an absolute path since we're about to chdir - [[ ${movedir:0:1} != '/' ]] && movedir=$PWD/$movedir - [[ ! -w $cachedir || ( $movedir && ! -w $movedir ) ]] && needsroot=1 -fi - -# unlikely that this will fail, but better make sure -cd "$cachedir" >/dev/null || die "failed to chdir to \`%s'" "$cachedir" - -# note that these results are returned in an arbitrary order from awk, but -# they'll be resorted (in summarize) iff we have a verbosity level set. -IFS=$'\n' read -r -d '' -a candidates < \ - <(printf '%s\n' *.pkg.tar?(.+([^.])) | pacsort | - pkgfilter "$keep" "$scanarch" \ - "${#whitelist[*]}" "${whitelist[@]}" \ - "${#blacklist[*]}" "${blacklist[@]}") - -if (( ! ${#candidates[*]} )); then - msg 'no candidate packages found for pruning' - exit 1 -fi - -# grab this prior to signature scavenging -pkgcount=${#candidates[*]} - -# copy the list, merging in any found sigs -for cand in "${candidates[@]}"; do - candtemp+=("$cand") - [[ -f $cand.sig ]] && candtemp+=("$cand.sig") -done -candidates=("${candtemp[@]}") -unset candtemp - -# do this before we destroy anything -totalsaved=$(@SIZECMD@ "${candidates[@]}" | awk '{ sum += $1 } END { print sum }') - -# crush. kill. destroy. -(( verbose )) && cmdopts+=(-v) -if (( delete )); then - runcmd rm "${cmdopts[@]}" "${candidates[@]}" -elif (( move )); then - runcmd mv "${cmdopts[@]}" "${candidates[@]}" "$movedir" -fi - -summarize "$pkgcount" "${candidates[@]}" - -# vim: set ts=2 sw=2 noet: diff --git a/contrib/paccache.sh.in b/contrib/paccache.sh.in new file mode 100755 index 00000000..da65f476 --- /dev/null +++ b/contrib/paccache.sh.in @@ -0,0 +1,319 @@ +#!/bin/bash +# +# pacache - flexible pacman cache cleaning +# +# Copyright (C) 2011 Dave Reisner +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +shopt -s extglob + +declare -r myname='paccache' +declare -r myver='@PACKAGE_VERSION@' + +declare -a candidates=() cmdopts=() whitelist=() blacklist=() +declare -i delete=0 dryrun=0 filecount=0 move=0 needsroot=0 totalsaved=0 verbose=0 +declare cachedir=@localstatedir@/cache/pacman/pkg delim=$'\n' keep=3 movedir= scanarch= + +msg() { + local mesg=$1; shift + printf "==> $mesg\n" "$@" +} >&2 + +error() { + local mesg=$1; shift + printf "==> ERROR: $mesg\n" "$@" +} >&2 + +die() { + error "$@" + exit 1 +} + +# reads a list of files on stdin and prints out deletion candidates +pkgfilter() { + # there's whitelist and blacklist parameters passed to this + # script after the block of awk. + + awk -v keep="$1" -v scanarch="$2" ' + function parse_filename(filename, parts, count, i, pkgname, arch) { + + count = split(filename, parts, "-") + + i = 1 + pkgname = parts[i++] + while (i <= count - 3) { + pkgname = pkgname "-" parts[i++] + } + + arch = substr(parts[count], 1, index(parts[count], ".") - 1) + + # filter on whitelist or blacklist + if (wlen && !whitelist[pkgname]) return + if (blen && blacklist[pkgname]) return + + if ("" == packages[pkgname,arch]) { + packages[pkgname,arch] = filename + } else { + packages[pkgname,arch] = packages[pkgname,arch] SUBSEP filename + } + } + + BEGIN { + # create whitelist + wlen = ARGV[1]; delete ARGV[1] + for (i = 2; i < 2 + wlen; i++) { + whitelist[ARGV[i]] = 1 + delete ARGV[i] + } + + # create blacklist + blen = ARGV[i]; delete ARGV[i] + while (i++ < ARGC) { + blacklist[ARGV[i]] = 1 + delete ARGV[i] + } + + # read package filenames + while (getline < "/dev/stdin") { + parse_filename($0) + } + + for (pkglist in packages) { + # idx[1,2] = idx[pkgname,arch] + split(pkglist, idx, SUBSEP) + + # enforce architecture match if specified + if (!scanarch || scanarch == idx[2]) { + count = split(packages[idx[1], idx[2]], pkgs, SUBSEP) + for(i = 1; i <= count - keep; i++) { + print pkgs[i] + } + } + } + }' "${@:3}" +} + +size_to_human() { + awk -v size="$1" ' + BEGIN { + suffix[1] = "B" + suffix[2] = "KiB" + suffix[3] = "MiB" + suffix[4] = "GiB" + suffix[5] = "TiB" + count = 1 + + while (size > 1024) { + size /= 1024 + count++ + } + + sizestr = sprintf("%.2f", size) + sub(/\.?0+$/, "", sizestr) + printf("%s %s", sizestr, suffix[count]) + }' +} + +runcmd() { + if (( needsroot )); then + msg "Privilege escalation required" + if sudo -v &>/dev/null && sudo -l &>/dev/null; then + sudo "$@" + else + printf '%s ' 'root' + su -c "$(printf '%q ' "$@")" + fi + else + "$@" + fi +} + +summarize() { + local -i filecount=$1; shift + local seenarch= seen= arch= name= + local -r pkg_re='(.+)-[^-]+-[0-9]+-([^.]+)\.pkg.*' + + if (( delete )); then + printf -v output 'finished: %d packages removed' "$filecount" + elif (( move )); then + printf -v output "finished: %d packages moved to \`%s'" "$filecount" "$movedir" + elif (( dryrun )); then + if (( verbose )); then + msg "Candidate packages:" + while read -r pkg; do + if (( verbose >= 3 )); then + [[ $pkg =~ $pkg_re ]] && name=${BASH_REMATCH[1]} arch=${BASH_REMATCH[2]} + if [[ -z $seen || $seenarch != "$arch" || $seen != "$name" ]]; then + seen=$name seenarch=$arch + printf '%s (%s):\n' "$name" "$arch" + fi + printf ' %s\n' "$pkg" + elif (( verbose >= 2 )); then + printf "$PWD/%s$delim" "$pkg" + else + printf "%s$delim" "$pkg" + fi + done < <(printf '%s\n' "$@" | pacsort) + fi + printf -v output 'finished dry run: %d candidates' "$filecount" + fi + + printf '\n' >&2 + msg "$output (diskspace saved: %s)" "$(size_to_human "$totalsaved")" +} + +usage() { + cat < [options] [targets...] + +$myname is a flexible pacman cache cleaning utility, which has numerous +options to help control how much, and what, is deleted from any directory +containing pacman package tarballs. + + Operations: + -d perform a dry run, only finding candidate packages. + -m move candidate packages to 'movedir'. + -r remove candidate packages. + + Options: + -a scan for 'arch' (default: all architectures). + -c scan 'cachedir' for packages (default: @localstatedir@/cache/pacman/pkg). + -f apply force to mv(1) and rm(1) operations. + -h display this help message. + -i ignore 'pkgs', which is a comma separated. Alternatively, + specify '-' to read package names from stdin, newline delimited. + -k keep 'num' of each package in 'cachedir' (default: 3). + -u target uninstalled packages. + -v increase verbosity. specify up to 3 times. + -z use null delimiters for candidate names (only with -v and -vv) + +EOF +} + +version() { + printf "%s %s\n" "$myname" "$myver" + echo 'Copyright (C) 2011 Dave Reisner ' +} + +if (( ! UID )); then + error "Do not run this script as root. You will be prompted for privilege escalation." + exit 42 +fi + +# TODO: remove this workaround and use a sane command line parser (like the +# parse_options library from scripts/) here +if [[ $1 = -@(h|-help) ]]; then + usage + exit 0 +elif [[ $1 = -@(V|-version) ]]; then + version + exit 0 +fi + +while getopts ':a:c:dfi:k:m:rsuvz' opt; do + case $opt in + a) scanarch=$OPTARG ;; + c) cachedir=$OPTARG ;; + d) dryrun=1 ;; + f) cmdopts=(-f) ;; + i) if [[ $OPTARG = '-' ]]; then + [[ ! -t 0 ]] && IFS=$'\n' read -r -d '' -a ign + else + IFS=',' read -r -a ign <<< "$OPTARG" + fi + blacklist+=("${ign[@]}") + unset i ign ;; + k) keep=$OPTARG + if [[ -z $keep || -n ${keep//[0-9]/} ]]; then + die 'argument to option -k must be a non-negative integer' + else + keep=$(( 10#$keep )) + fi ;; + m) move=1 movedir=$OPTARG ;; + r) delete=1 ;; + u) IFS=$'\n' read -r -d '' -a ign < <(pacman -Qq) + blacklist+=("${ign[@]}") + unset ign ;; + v) (( ++verbose )) ;; + z) delim='\0' ;; + :) die "option '--%s' requires an argument" "$OPTARG" ;; + ?) die "invalid option -- '%s'" "$OPTARG" ;; + esac +done +shift $(( OPTIND - 1 )) + +# remaining args are a whitelist +whitelist=("$@") + +# sanity checks +case $(( dryrun+delete+move )) in + 0) die "no operation specified (use -h for help)" ;; + [^1]) die "only one operation may be used at a time" ;; +esac + +[[ -d $cachedir ]] || + die "cachedir \`%s' does not exist or is not a directory" "$cachedir" + +[[ $movedir && ! -d $movedir ]] && + die "move-to directory \`%s' does not exist or is not a directory" "$movedir" + +if (( move || delete )); then + # make it an absolute path since we're about to chdir + [[ ${movedir:0:1} != '/' ]] && movedir=$PWD/$movedir + [[ ! -w $cachedir || ( $movedir && ! -w $movedir ) ]] && needsroot=1 +fi + +# unlikely that this will fail, but better make sure +cd "$cachedir" >/dev/null || die "failed to chdir to \`%s'" "$cachedir" + +# note that these results are returned in an arbitrary order from awk, but +# they'll be resorted (in summarize) iff we have a verbosity level set. +IFS=$'\n' read -r -d '' -a candidates < \ + <(printf '%s\n' *.pkg.tar?(.+([^.])) | pacsort | + pkgfilter "$keep" "$scanarch" \ + "${#whitelist[*]}" "${whitelist[@]}" \ + "${#blacklist[*]}" "${blacklist[@]}") + +if (( ! ${#candidates[*]} )); then + msg 'no candidate packages found for pruning' + exit 1 +fi + +# grab this prior to signature scavenging +pkgcount=${#candidates[*]} + +# copy the list, merging in any found sigs +for cand in "${candidates[@]}"; do + candtemp+=("$cand") + [[ -f $cand.sig ]] && candtemp+=("$cand.sig") +done +candidates=("${candtemp[@]}") +unset candtemp + +# do this before we destroy anything +totalsaved=$(@SIZECMD@ "${candidates[@]}" | awk '{ sum += $1 } END { print sum }') + +# crush. kill. destroy. +(( verbose )) && cmdopts+=(-v) +if (( delete )); then + runcmd rm "${cmdopts[@]}" "${candidates[@]}" +elif (( move )); then + runcmd mv "${cmdopts[@]}" "${candidates[@]}" "$movedir" +fi + +summarize "$pkgcount" "${candidates[@]}" + +# vim: set ts=2 sw=2 noet: diff --git a/contrib/pacdiff.in b/contrib/pacdiff.in deleted file mode 100755 index bfafda26..00000000 --- a/contrib/pacdiff.in +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/bash -# pacdiff : a simple pacnew/pacorig/pacsave updater -# -# Copyright (c) 2007 Aaron Griffin -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -declare -r myname='pacdiff' -declare -r myver='@PACKAGE_VERSION@' - -diffprog=${DIFFPROG:-vimdiff} -diffsearchpath=${DIFFSEARCHPATH:-/etc} -locate=0 - -usage() { - echo "$myname : a simple pacnew/pacorig/pacsave updater" - echo "Usage : $myname [-l]" - echo " -l/--locate makes $myname use locate rather than find" - echo " DIFFPROG variable allows to override the default vimdiff" - echo " DIFFSEARCHPATH allows to override the default /etc path" - echo "Example : DIFFPROG=meld DIFFSEARCHPATH=\"/boot /etc /usr\" $myname" -} - -version() { - printf "%s %s\n" "$myname" "$myver" - echo 'Copyright (C) 2007 Aaron Griffin ' -} - -cmd() { - if [ $locate -eq 1 ]; then - locate -0 -e -b \*.pacnew \*.pacorig \*.pacsave - else - find $diffsearchpath \( -name \*.pacnew -o -name \*.pacorig -o -name \*.pacsave \) -print0 - fi -} - -if [ $# -gt 0 ]; then - case $1 in - -l|--locate) - locate=1;; - -V|--version) - version; exit 0;; - -h|--help) - usage; exit 0;; - *) - usage; exit 1;; - esac -fi - -# see http://mywiki.wooledge.org/BashFAQ/020 -while IFS= read -u 3 -r -d '' pacfile; do - file="${pacfile%.pac*}" - echo "File: $file" - if [ ! -f "$file" ]; then - echo " $file does not exist" - rm -i "$pacfile" - continue - fi - check="$(cmp "$pacfile" "$file")" - if [ -z "${check}" ]; then - echo " Files are identical, removing..." - rm "$pacfile" - else - echo -n " File differences found. (V)iew, (S)kip, (R)emove: [v/s/r] " - while read c; do - case $c in - r|R) rm "$pacfile"; break ;; - v|V) - $diffprog "$pacfile" "$file" - rm -i "$pacfile"; break ;; - s|S) break ;; - *) echo -n " Invalid answer. Try again: [v/s/r] "; continue ;; - esac - done - fi -done 3< <(cmd) - -exit 0 - -# vim: set ts=2 sw=2 noet: diff --git a/contrib/pacdiff.sh.in b/contrib/pacdiff.sh.in new file mode 100755 index 00000000..bfafda26 --- /dev/null +++ b/contrib/pacdiff.sh.in @@ -0,0 +1,92 @@ +#!/bin/bash +# pacdiff : a simple pacnew/pacorig/pacsave updater +# +# Copyright (c) 2007 Aaron Griffin +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +declare -r myname='pacdiff' +declare -r myver='@PACKAGE_VERSION@' + +diffprog=${DIFFPROG:-vimdiff} +diffsearchpath=${DIFFSEARCHPATH:-/etc} +locate=0 + +usage() { + echo "$myname : a simple pacnew/pacorig/pacsave updater" + echo "Usage : $myname [-l]" + echo " -l/--locate makes $myname use locate rather than find" + echo " DIFFPROG variable allows to override the default vimdiff" + echo " DIFFSEARCHPATH allows to override the default /etc path" + echo "Example : DIFFPROG=meld DIFFSEARCHPATH=\"/boot /etc /usr\" $myname" +} + +version() { + printf "%s %s\n" "$myname" "$myver" + echo 'Copyright (C) 2007 Aaron Griffin ' +} + +cmd() { + if [ $locate -eq 1 ]; then + locate -0 -e -b \*.pacnew \*.pacorig \*.pacsave + else + find $diffsearchpath \( -name \*.pacnew -o -name \*.pacorig -o -name \*.pacsave \) -print0 + fi +} + +if [ $# -gt 0 ]; then + case $1 in + -l|--locate) + locate=1;; + -V|--version) + version; exit 0;; + -h|--help) + usage; exit 0;; + *) + usage; exit 1;; + esac +fi + +# see http://mywiki.wooledge.org/BashFAQ/020 +while IFS= read -u 3 -r -d '' pacfile; do + file="${pacfile%.pac*}" + echo "File: $file" + if [ ! -f "$file" ]; then + echo " $file does not exist" + rm -i "$pacfile" + continue + fi + check="$(cmp "$pacfile" "$file")" + if [ -z "${check}" ]; then + echo " Files are identical, removing..." + rm "$pacfile" + else + echo -n " File differences found. (V)iew, (S)kip, (R)emove: [v/s/r] " + while read c; do + case $c in + r|R) rm "$pacfile"; break ;; + v|V) + $diffprog "$pacfile" "$file" + rm -i "$pacfile"; break ;; + s|S) break ;; + *) echo -n " Invalid answer. Try again: [v/s/r] "; continue ;; + esac + done + fi +done 3< <(cmd) + +exit 0 + +# vim: set ts=2 sw=2 noet: diff --git a/contrib/paclist.in b/contrib/paclist.in deleted file mode 100755 index 7883e21b..00000000 --- a/contrib/paclist.in +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -# paclist - List all packages installed from a given repo -# -# Copyright (C) 2008 Dan McGee -# Copyright (C) 2011 Dave Reisner -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -declare -r myname='paclist' -declare -r myver='@PACKAGE_VERSION@' - -export TEXTDOMAIN='pacman' -export TEXTDOMAINDIR='/usr/share/locale' - -# determine whether we have gettext; make it a no-op if we do not -if ! type gettext &>/dev/null; then - gettext() { - echo "$@" - } -fi - -usage() { - printf '%s - List all packages installed from a given repo\n' "$myname" - printf 'Usage: %s \n' "$myname" - printf 'Example: %s testing\n' "$myname" -} - -version() { - printf "%s %s\n" "$myname" "$myver" - echo 'Copyright (C) 2008 Dan McGee ' - echo 'Copyright (C) 2011 Dave Reisner ' -} - -if [[ -z $1 ]]; then - usage - exit 1 -fi - -if [[ $1 = -@(h|-help) ]]; then - usage - exit 0 -elif [[ $1 = -@(V|-version) ]]; then - version - exit 0 -fi - -printf -v installed '[%s]' "$(gettext installed)" -pacman -Sl $1 | awk -v i="$installed" '$NF == i { print $2,$3 }' - -# exit with pacman's return value, not awk's -exit ${PIPESTATUS[0]} - -# vim: set ts=2 sw=2 noet: diff --git a/contrib/paclist.sh.in b/contrib/paclist.sh.in new file mode 100755 index 00000000..7883e21b --- /dev/null +++ b/contrib/paclist.sh.in @@ -0,0 +1,64 @@ +#!/bin/bash +# paclist - List all packages installed from a given repo +# +# Copyright (C) 2008 Dan McGee +# Copyright (C) 2011 Dave Reisner +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +declare -r myname='paclist' +declare -r myver='@PACKAGE_VERSION@' + +export TEXTDOMAIN='pacman' +export TEXTDOMAINDIR='/usr/share/locale' + +# determine whether we have gettext; make it a no-op if we do not +if ! type gettext &>/dev/null; then + gettext() { + echo "$@" + } +fi + +usage() { + printf '%s - List all packages installed from a given repo\n' "$myname" + printf 'Usage: %s \n' "$myname" + printf 'Example: %s testing\n' "$myname" +} + +version() { + printf "%s %s\n" "$myname" "$myver" + echo 'Copyright (C) 2008 Dan McGee ' + echo 'Copyright (C) 2011 Dave Reisner ' +} + +if [[ -z $1 ]]; then + usage + exit 1 +fi + +if [[ $1 = -@(h|-help) ]]; then + usage + exit 0 +elif [[ $1 = -@(V|-version) ]]; then + version + exit 0 +fi + +printf -v installed '[%s]' "$(gettext installed)" +pacman -Sl $1 | awk -v i="$installed" '$NF == i { print $2,$3 }' + +# exit with pacman's return value, not awk's +exit ${PIPESTATUS[0]} + +# vim: set ts=2 sw=2 noet: diff --git a/contrib/paclog-pkglist.in b/contrib/paclog-pkglist.in deleted file mode 100755 index 222bbc4c..00000000 --- a/contrib/paclog-pkglist.in +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/bash -# -# paclog-pkglist - Parse a log file into a list of currently installed packages -# -# Copyright (C) 2011 Dave Reisner -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -declare -r myname='paclog-pkglist' -declare -r myver='@PACKAGE_VERSION@' - -export TEXTDOMAIN='pacman' -export TEXTDOMAINDIR='/usr/share/locale' -declare logfile=${1:-@localstatedir@/log/pacman.log} - -usage() { - printf 'usage: %s [pacman log]\n' "$myname" - printf 'example: %s @localstatedir@/log/pacman.log\n' "$myname" - printf '\ndefaults to: @localstatedir@/log/pacman.log\n' -} - -version() { - printf "%s %s\n" "$myname" "$myver" - echo 'Copyright (C) 2011 Dave Reisner ' -} - -if [[ $1 ]]; then - if [[ $1 = -@(h|-help) ]]; then - usage - exit 0 - elif [[ $1 = -@(V|-version) ]]; then - version - exit 0 - elif [[ ! -e $logfile ]]; then - printf $"target not found: %s\n" "$1" - exit 1 - fi -fi - -<"$logfile" awk ' -{ - action = $3 - pkgname = $4 - pkgver = $5 - upgver = $7 -} - -NF == 5 && action == "installed" { - gsub(/[()]/, "", pkgver) - pkg[pkgname] = pkgver - next -} - -NF == 7 && action == "upgraded" { - sub(/\)/, "", upgver) - pkg[pkgname] = upgver - next -} - -NF == 5 && action == "removed" { - pkg[pkgname] = -1 -} - -END { - for (i in pkg) { - if (pkg[i] != -1) { - printf "%s %s\n",i,pkg[i] - } - } -}' | sort - -# vim: set ts=2 sw=2 noet: diff --git a/contrib/paclog-pkglist.sh.in b/contrib/paclog-pkglist.sh.in new file mode 100755 index 00000000..222bbc4c --- /dev/null +++ b/contrib/paclog-pkglist.sh.in @@ -0,0 +1,83 @@ +#!/bin/bash +# +# paclog-pkglist - Parse a log file into a list of currently installed packages +# +# Copyright (C) 2011 Dave Reisner +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +declare -r myname='paclog-pkglist' +declare -r myver='@PACKAGE_VERSION@' + +export TEXTDOMAIN='pacman' +export TEXTDOMAINDIR='/usr/share/locale' +declare logfile=${1:-@localstatedir@/log/pacman.log} + +usage() { + printf 'usage: %s [pacman log]\n' "$myname" + printf 'example: %s @localstatedir@/log/pacman.log\n' "$myname" + printf '\ndefaults to: @localstatedir@/log/pacman.log\n' +} + +version() { + printf "%s %s\n" "$myname" "$myver" + echo 'Copyright (C) 2011 Dave Reisner ' +} + +if [[ $1 ]]; then + if [[ $1 = -@(h|-help) ]]; then + usage + exit 0 + elif [[ $1 = -@(V|-version) ]]; then + version + exit 0 + elif [[ ! -e $logfile ]]; then + printf $"target not found: %s\n" "$1" + exit 1 + fi +fi + +<"$logfile" awk ' +{ + action = $3 + pkgname = $4 + pkgver = $5 + upgver = $7 +} + +NF == 5 && action == "installed" { + gsub(/[()]/, "", pkgver) + pkg[pkgname] = pkgver + next +} + +NF == 7 && action == "upgraded" { + sub(/\)/, "", upgver) + pkg[pkgname] = upgver + next +} + +NF == 5 && action == "removed" { + pkg[pkgname] = -1 +} + +END { + for (i in pkg) { + if (pkg[i] != -1) { + printf "%s %s\n",i,pkg[i] + } + } +}' | sort + +# vim: set ts=2 sw=2 noet: diff --git a/contrib/pacscripts.in b/contrib/pacscripts.in deleted file mode 100755 index 84687145..00000000 --- a/contrib/pacscripts.in +++ /dev/null @@ -1,138 +0,0 @@ -#!/bin/bash -# -# pacscripts : tries to print out the {pre,post}_{install,remove,upgrade} -# scripts of a given package -# -# Copyright (c) 2009 Giulio "giulivo" Fidente -# Copyright (c) 2009 Xavier Chantry -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -# bash options -set -o nounset -set -o errexit - -declare -r myname='pacscripts' -declare -r myver='@PACKAGE_VERSION@' - -conf="@sysconfdir@/pacman.conf" - -if [ ! -r "$conf" ]; then - echo "ERROR: unable to read $conf" - exit 1 -fi - -eval $(awk '/DBPath/ {print $1$2$3}' "$conf") -eval $(awk '/CacheDir/ {print $1$2$3}' "$conf") -pac_db="${DBPath:-@localstatedir@/lib/pacman}/local" -pac_cache="${CacheDir:-@localstatedir@/cache/pacman/pkg}" - -error() { - local mesg=$1; shift - printf "==> $(gettext "ERROR:") ${mesg}\n" "$@" >&2 -} - -usage() { - echo "This program prints out the {pre,post}_{install,remove,upgrade} scripts" - echo "of a given package." - echo "Usage: $myname pkgname|pkgfile" - echo - echo " OPTIONS:" - echo " -h, --help Print this help message" - echo " -v, --version Print program name and version" - echo - echo "Example: $myname gconf-editor" - echo "Example: $myname gconf-editor-2.24.1-1-x86_64.pkg.tar.gz" -} - -version() { - printf "%s %s\n" "$myname" "$myver" - echo 'Copyright (c) 2009 Giulio "giulivo" Fidente ' - echo 'Copyright (c) 2009 Xavier Chantry ' -} - -spacman() { - if [ $EUID -eq 0 ]; then - pacman "$@" - else - if ! type -p sudo; then - error "Cannot find the sudo binary! Is sudo installed?" - error "Otherwise try to run the program as root" - exit 1 - else - sudo pacman "$@" - fi - fi -} - -print_db() { - pkg=$(pacman -Q "$1") - pkg=${pkg/ /-} - if [ -f $pac_db/$pkg*/install ]; then - cat $pac_db/$pkg*/install - echo - return 0 - else - error "Package $1 does not include any .INSTALL script" - return 1 - fi -} - -print_pkg() { - if ! bsdtar -xOf "$1" .INSTALL 2>/dev/null; then - error "Package $1 does not include any .INSTALL script" - return 1 - fi - echo -} - -print_scriptlet() { - if [ -f "$1" ]; then - if bsdtar tf "$1" .PKGINFO &>/dev/null; then - print_pkg "$1" - return - fi - fi - if pacman -Q "$1" &>/dev/null; then - print_db "$1" - return - fi - if ! pacman -Si $1 &>/dev/null; then - error "Package $1 not found" - return 1 - fi - url=$(spacman -Sdp $1 | tail -n1) - filename=$(basename $url) - if [ ! -f "$pac_cache/$filename" ]; then - if ! spacman -Sdw --noconfirm $1 >&2; then - error "Failed to download $1" - return 1 - fi - echo >&2 - fi - print_pkg "$pac_cache/$filename" - return -} - -if [ $# -ne 1 ] ; then - usage - exit 1 -fi - -case "$1" in - --help|-h) usage; exit 0 ;; - --version|-V) version; exit 0 ;; - *) print_scriptlet $1 ;; -esac diff --git a/contrib/pacscripts.sh.in b/contrib/pacscripts.sh.in new file mode 100755 index 00000000..84687145 --- /dev/null +++ b/contrib/pacscripts.sh.in @@ -0,0 +1,138 @@ +#!/bin/bash +# +# pacscripts : tries to print out the {pre,post}_{install,remove,upgrade} +# scripts of a given package +# +# Copyright (c) 2009 Giulio "giulivo" Fidente +# Copyright (c) 2009 Xavier Chantry +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# bash options +set -o nounset +set -o errexit + +declare -r myname='pacscripts' +declare -r myver='@PACKAGE_VERSION@' + +conf="@sysconfdir@/pacman.conf" + +if [ ! -r "$conf" ]; then + echo "ERROR: unable to read $conf" + exit 1 +fi + +eval $(awk '/DBPath/ {print $1$2$3}' "$conf") +eval $(awk '/CacheDir/ {print $1$2$3}' "$conf") +pac_db="${DBPath:-@localstatedir@/lib/pacman}/local" +pac_cache="${CacheDir:-@localstatedir@/cache/pacman/pkg}" + +error() { + local mesg=$1; shift + printf "==> $(gettext "ERROR:") ${mesg}\n" "$@" >&2 +} + +usage() { + echo "This program prints out the {pre,post}_{install,remove,upgrade} scripts" + echo "of a given package." + echo "Usage: $myname pkgname|pkgfile" + echo + echo " OPTIONS:" + echo " -h, --help Print this help message" + echo " -v, --version Print program name and version" + echo + echo "Example: $myname gconf-editor" + echo "Example: $myname gconf-editor-2.24.1-1-x86_64.pkg.tar.gz" +} + +version() { + printf "%s %s\n" "$myname" "$myver" + echo 'Copyright (c) 2009 Giulio "giulivo" Fidente ' + echo 'Copyright (c) 2009 Xavier Chantry ' +} + +spacman() { + if [ $EUID -eq 0 ]; then + pacman "$@" + else + if ! type -p sudo; then + error "Cannot find the sudo binary! Is sudo installed?" + error "Otherwise try to run the program as root" + exit 1 + else + sudo pacman "$@" + fi + fi +} + +print_db() { + pkg=$(pacman -Q "$1") + pkg=${pkg/ /-} + if [ -f $pac_db/$pkg*/install ]; then + cat $pac_db/$pkg*/install + echo + return 0 + else + error "Package $1 does not include any .INSTALL script" + return 1 + fi +} + +print_pkg() { + if ! bsdtar -xOf "$1" .INSTALL 2>/dev/null; then + error "Package $1 does not include any .INSTALL script" + return 1 + fi + echo +} + +print_scriptlet() { + if [ -f "$1" ]; then + if bsdtar tf "$1" .PKGINFO &>/dev/null; then + print_pkg "$1" + return + fi + fi + if pacman -Q "$1" &>/dev/null; then + print_db "$1" + return + fi + if ! pacman -Si $1 &>/dev/null; then + error "Package $1 not found" + return 1 + fi + url=$(spacman -Sdp $1 | tail -n1) + filename=$(basename $url) + if [ ! -f "$pac_cache/$filename" ]; then + if ! spacman -Sdw --noconfirm $1 >&2; then + error "Failed to download $1" + return 1 + fi + echo >&2 + fi + print_pkg "$pac_cache/$filename" + return +} + +if [ $# -ne 1 ] ; then + usage + exit 1 +fi + +case "$1" in + --help|-h) usage; exit 0 ;; + --version|-V) version; exit 0 ;; + *) print_scriptlet $1 ;; +esac diff --git a/contrib/pacsysclean.in b/contrib/pacsysclean.in deleted file mode 100755 index 162530ef..00000000 --- a/contrib/pacsysclean.in +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash - -# pacsysclean - Sort installed packages by increasing installed size. Useful for system clean-up. - -declare -r myname='pacsysclean' -declare -r myver='@PACKAGE_VERSION@' - -PACMAN_OPTS= - -usage() { - echo "$myname - Sort installed packages by increasing installed size." - echo - echo "Usage: $myname [options]" - echo - echo "Options:" - echo " -o Specify custom pacman query options (e.g., dt)" - echo " -h, --help Show this help message and exit" -} - -version() { - printf "%s %s\n" "$myname" "$myver" - echo 'Copyright (C) 2011 Eric Bélanger ' -} - - -if [ -n "$1" ]; then - case "$1" in - -o) PACMAN_OPTS="${2}" ;; - -h|--help) usage; exit 0 ;; - -V|--version) version; exit 0 ;; - *) usage; exit 1 ;; - esac -fi - -IFS=$'\n' -name="^Name.*: (.*)$" -size="^Installed Size.*: (.*) KiB$" - -[[ $PACMAN_OPTS != -* ]] && PACMAN_OPTS="-$PACMAN_OPTS" - -for line in $(LANG=C pacman -Qi $PACMAN_OPTS); do - if [[ $line =~ $name ]]; then - printf "%s\t" ${BASH_REMATCH[1]} - elif [[ $line =~ $size ]]; then - printf "%s\n" ${BASH_REMATCH[1]} - fi -done | sort -g -k2 | awk ' -BEGIN { - split("KiB MiB GiB TiB PiB EiB ZiB YiB", suffix) -} -function format_size(size) { - count = 1 - while (size + 0 > 1024) { - size /= 1024 - count++ - } - sizestr = sprintf("%.2f %s", size, suffix[count]) - return sizestr -} -{ - printf("%s\t%s\n", format_size($2), $1); -}' diff --git a/contrib/pacsysclean.sh.in b/contrib/pacsysclean.sh.in new file mode 100755 index 00000000..162530ef --- /dev/null +++ b/contrib/pacsysclean.sh.in @@ -0,0 +1,62 @@ +#!/bin/bash + +# pacsysclean - Sort installed packages by increasing installed size. Useful for system clean-up. + +declare -r myname='pacsysclean' +declare -r myver='@PACKAGE_VERSION@' + +PACMAN_OPTS= + +usage() { + echo "$myname - Sort installed packages by increasing installed size." + echo + echo "Usage: $myname [options]" + echo + echo "Options:" + echo " -o Specify custom pacman query options (e.g., dt)" + echo " -h, --help Show this help message and exit" +} + +version() { + printf "%s %s\n" "$myname" "$myver" + echo 'Copyright (C) 2011 Eric Bélanger ' +} + + +if [ -n "$1" ]; then + case "$1" in + -o) PACMAN_OPTS="${2}" ;; + -h|--help) usage; exit 0 ;; + -V|--version) version; exit 0 ;; + *) usage; exit 1 ;; + esac +fi + +IFS=$'\n' +name="^Name.*: (.*)$" +size="^Installed Size.*: (.*) KiB$" + +[[ $PACMAN_OPTS != -* ]] && PACMAN_OPTS="-$PACMAN_OPTS" + +for line in $(LANG=C pacman -Qi $PACMAN_OPTS); do + if [[ $line =~ $name ]]; then + printf "%s\t" ${BASH_REMATCH[1]} + elif [[ $line =~ $size ]]; then + printf "%s\n" ${BASH_REMATCH[1]} + fi +done | sort -g -k2 | awk ' +BEGIN { + split("KiB MiB GiB TiB PiB EiB ZiB YiB", suffix) +} +function format_size(size) { + count = 1 + while (size + 0 > 1024) { + size /= 1024 + count++ + } + sizestr = sprintf("%.2f %s", size, suffix[count]) + return sizestr +} +{ + printf("%s\t%s\n", format_size($2), $1); +}' -- cgit v1.2.3-24-g4f1b From 03acea832ad39fa371781f045c39677a02d1156a Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 17 Apr 2012 21:34:30 -0400 Subject: validate bash scripts with 'bash -n' during build. Use the no-exec mode of $(BASH_SHELL) to check for syntax errors in shell scripts. Since we use the extglob feature in various places, this requires that we pass -O extglob to the shell as well, to ensure that the parser is armed to handle this syntax. Signed-off-by: Dave Reisner --- contrib/Makefile.am | 1 + scripts/Makefile.am | 1 + 2 files changed, 2 insertions(+) diff --git a/contrib/Makefile.am b/contrib/Makefile.am index 5139b54d..3cc1e578 100644 --- a/contrib/Makefile.am +++ b/contrib/Makefile.am @@ -66,6 +66,7 @@ $(BASHSCRIPTS): Makefile $(AM_V_at)$(RM) $@ $(AM_V_GEN)test -f $(srcdir)/$@.sh.in && m4 -P -I $(srcdir) $(srcdir)/$@.sh.in | $(edit) >$@ $(AM_V_at)chmod +x,a-w $@ + @$(BASH_SHELL) -O extglob -n $@ $(OURFILES): Makefile $(AM_V_at)$(RM) $@ $@.tmp diff --git a/scripts/Makefile.am b/scripts/Makefile.am index b8a19900..06e9095e 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -64,6 +64,7 @@ $(OURSCRIPTS): Makefile $(AM_V_at)$(RM) $@ $(AM_V_GEN)test -f $(srcdir)/$@.sh.in && m4 -P -I $(srcdir) $(srcdir)/$@.sh.in | $(edit) >$@ $(AM_V_at)chmod +x,a-w $@ + @$(BASH_SHELL) -O extglob -n $@ makepkg: \ $(srcdir)/makepkg.sh.in \ -- cgit v1.2.3-24-g4f1b From ea4aa6f184909db38bacbbf60f22f1674f2853a6 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Wed, 11 Apr 2012 09:29:07 -0400 Subject: configure: require bash >= 4.1 at compile time We've unofficially agreed to raise our minimum supported bash version to 4.1, and since added features that require it. Additionally, an earlier commit adds a syntax check to the builds of scripts/ and contrib/ which could conceivably fail with an earlier shell. Therefore, make this a hard requirement of the build process. Signed-off-by: Dave Reisner --- configure.ac | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d488bfaf..0e78c238 100644 --- a/configure.ac +++ b/configure.ac @@ -148,7 +148,23 @@ AC_PROG_AWK AC_PROG_CC_C99 AC_PROG_INSTALL AC_CHECK_PROGS([PYTHON], [python2.7 python2.6 python2.5 python2 python], [false]) -AC_PATH_PROGS([BASH_SHELL], [bash bash4 bash3], [false]) +AC_PATH_PROGS([BASH_SHELL], [bash bash4], [false]) + +AS_IF([test "x$BASH_SHELL" = "xfalse"], + AC_MSG_WARN([*** bash >= 4.1.0 is required for pacman scripts]), + [bash_version_major=`$BASH_SHELL -c 'echo "${BASH_VERSINFO[[0]]}"'` + bash_version_minor=`$BASH_SHELL -c 'echo "${BASH_VERSINFO[[1]]}"'` + ok=yes + if test "$bash_version_major" -lt 4; then + ok=no + fi + if test "$bash_version_major" -eq 4 && test "$bash_version_minor" -lt 1; then + ok=no + fi + if test "$ok" = "no"; then + AC_MSG_ERROR([*** bash >= 4.1.0 is required for pacman scripts]) + fi + unset bash_version_major bash_version_minor ok]) # find installed gettext AM_GNU_GETTEXT([external], [need-ngettext]) -- cgit v1.2.3-24-g4f1b From 6d10de881e0ca38d8f20384e20139784589ea2c7 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Thu, 19 Apr 2012 13:33:57 -0400 Subject: paccache: adopt parseopts for options parsing Add longopts and update usage. This removes the TODO item and incorporates --help/--version into the standard option set. Signed-off-by: Dave Reisner --- contrib/Makefile.am | 2 +- contrib/paccache.sh.in | 119 ++++++++++++++++++++++++++++++------------------- 2 files changed, 73 insertions(+), 48 deletions(-) diff --git a/contrib/Makefile.am b/contrib/Makefile.am index 3cc1e578..fe2fa550 100644 --- a/contrib/Makefile.am +++ b/contrib/Makefile.am @@ -88,7 +88,7 @@ uninstall-local: bacman: $(srcdir)/bacman.sh.in bash_completion: $(srcdir)/bash_completion.in -paccache: $(srcdir)/paccache.sh.in +paccache: $(srcdir)/paccache.sh.in $(top_srcdir)/scripts/library/parseopts.sh pacdiff: $(srcdir)/pacdiff.sh.in paclist: $(srcdir)/paclist.sh.in paclog-pkglist: $(srcdir)/paclog-pkglist.sh.in diff --git a/contrib/paccache.sh.in b/contrib/paccache.sh.in index da65f476..e8116721 100755 --- a/contrib/paccache.sh.in +++ b/contrib/paccache.sh.in @@ -42,6 +42,8 @@ die() { exit 1 } +m4_include(../scripts/library/parseopts.sh) + # reads a list of files on stdin and prints out deletion candidates pkgfilter() { # there's whitelist and blacklist parameters passed to this @@ -184,21 +186,21 @@ options to help control how much, and what, is deleted from any directory containing pacman package tarballs. Operations: - -d perform a dry run, only finding candidate packages. - -m move candidate packages to 'movedir'. - -r remove candidate packages. + -d, --dryrun perform a dry run, only finding candidate packages. + -m, --move move candidate packages to 'movedir'. + -r, --remove remove candidate packages. Options: - -a scan for 'arch' (default: all architectures). - -c scan 'cachedir' for packages (default: @localstatedir@/cache/pacman/pkg). - -f apply force to mv(1) and rm(1) operations. - -h display this help message. - -i ignore 'pkgs', which is a comma separated. Alternatively, - specify '-' to read package names from stdin, newline delimited. - -k keep 'num' of each package in 'cachedir' (default: 3). - -u target uninstalled packages. - -v increase verbosity. specify up to 3 times. - -z use null delimiters for candidate names (only with -v and -vv) + -a, --arch scan for 'arch' (default: all architectures). + -c, --cachedir scan 'cachedir' for packages (default: @localstatedir@/cache/pacman/pkg). + -f, --force apply force to mv(1) and rm(1) operations. + -h, --help display this help message and exit. + -i, --ignore ignore 'pkgs', comma separated. Alternatively, specify '-' to + read package names from stdin, newline delimited. + -k, --keep keep 'num' of each package in 'cachedir' (default: 3). + -u, --uninstalled target uninstalled packages. + -v, --verbose increase verbosity. specify up to 3 times. + -z, --null use null delimiters for candidate names (only with -v and -vv) EOF } @@ -213,47 +215,70 @@ if (( ! UID )); then exit 42 fi -# TODO: remove this workaround and use a sane command line parser (like the -# parse_options library from scripts/) here -if [[ $1 = -@(h|-help) ]]; then - usage - exit 0 -elif [[ $1 = -@(V|-version) ]]; then - version - exit 0 -fi +OPT_SHORT=':a:c:dfhi:k:m:rsuVvz' +OPT_LONG=('arch:' 'cachedir:' 'dryrun' 'force' 'help' 'ignore:' 'keep:' 'move' + 'remove' 'uninstalled' 'version' 'verbose' 'null') -while getopts ':a:c:dfi:k:m:rsuvz' opt; do - case $opt in - a) scanarch=$OPTARG ;; - c) cachedir=$OPTARG ;; - d) dryrun=1 ;; - f) cmdopts=(-f) ;; - i) if [[ $OPTARG = '-' ]]; then - [[ ! -t 0 ]] && IFS=$'\n' read -r -d '' -a ign - else - IFS=',' read -r -a ign <<< "$OPTARG" - fi - blacklist+=("${ign[@]}") - unset i ign ;; - k) keep=$OPTARG +if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then + exit 1 +fi +set -- "${OPTRET[@]}" +unset OPT_SHORT OPT_LONG OPTRET + +while :; do + case $1 in + -a|--arch) + scanarch=$2 + shift ;; + -c|--cachedir) + cachedir=$2 + shift ;; + -d|--dryrun) + dryrun=1 ;; + -f|--force) + cmdopts=(-f) ;; + -h|--help) + usage + exit 0 ;; + -i|--ignore) + if [[ $2 = '-' ]]; then + [[ ! -t 0 ]] && IFS=$'\n' read -r -d '' -a ign + else + IFS=',' read -r -a ign <<< "$2" + fi + blacklist+=("${ign[@]}") + unset i ign + shift ;; + -k|--keep) + keep=$2 if [[ -z $keep || -n ${keep//[0-9]/} ]]; then die 'argument to option -k must be a non-negative integer' else keep=$(( 10#$keep )) - fi ;; - m) move=1 movedir=$OPTARG ;; - r) delete=1 ;; - u) IFS=$'\n' read -r -d '' -a ign < <(pacman -Qq) - blacklist+=("${ign[@]}") - unset ign ;; - v) (( ++verbose )) ;; - z) delim='\0' ;; - :) die "option '--%s' requires an argument" "$OPTARG" ;; - ?) die "invalid option -- '%s'" "$OPTARG" ;; + fi + shift ;; + -m|--move) + move=1 movedir=$2 + shift ;; + -r|--remove) + delete=1 ;; + -u|--uninstalled) + IFS=$'\n' read -r -d '' -a ign < <(pacman -Qq) + blacklist+=("${ign[@]}") + unset ign ;; + -V|--version) + version + exit 0 ;; + -v|--verbose) + (( ++verbose )) ;; + -z|--null) + delim='\0' ;; + --) + shift + break 2 ;; esac + shift done -shift $(( OPTIND - 1 )) # remaining args are a whitelist whitelist=("$@") -- cgit v1.2.3-24-g4f1b From 953415c86a17c1db8bebbbaca89e6fd5783386b6 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Sun, 22 Apr 2012 17:38:48 -0400 Subject: rankmirrors: move to contrib/ This script is of questionable value, as it ranks mirrors by an uninteresting attribute: ping. While the script itself is interesting, people should be encouraged to rank mirrors by more useful measures, such as actual speed, locality, or up to date-ness. Signed-off-by: Dave Reisner --- contrib/.gitignore | 1 + contrib/Makefile.am | 5 +- contrib/rankmirrors.sh.in | 212 ++++++++++++++++++++++++++++++++++++++++++++++ scripts/.gitignore | 1 - scripts/Makefile.am | 4 - scripts/rankmirrors.sh.in | 212 ---------------------------------------------- 6 files changed, 217 insertions(+), 218 deletions(-) create mode 100644 contrib/rankmirrors.sh.in delete mode 100644 scripts/rankmirrors.sh.in diff --git a/contrib/.gitignore b/contrib/.gitignore index 70d19093..01bc22bd 100644 --- a/contrib/.gitignore +++ b/contrib/.gitignore @@ -7,4 +7,5 @@ paclog-pkglist pacscripts pacsearch pacsysclean +rankmirrors zsh_completion diff --git a/contrib/Makefile.am b/contrib/Makefile.am index fe2fa550..a325d62a 100644 --- a/contrib/Makefile.am +++ b/contrib/Makefile.am @@ -11,7 +11,8 @@ BASHSCRIPTS = \ paclist \ paclog-pkglist \ pacscripts \ - pacsysclean + pacsysclean \ + rankmirrors OTHERSCRIPTS = \ pacsearch @@ -35,6 +36,7 @@ EXTRA_DIST = \ pacscripts.sh.in \ pacsearch.in \ pacsysclean.sh.in \ + rankmirrors.sh.in vimprojects \ zsh_completion.in \ README @@ -95,6 +97,7 @@ paclog-pkglist: $(srcdir)/paclog-pkglist.sh.in pacscripts: $(srcdir)/pacscripts.sh.in pacsearch: $(srcdir)/pacsearch.in pacsysclean: $(srcdir)/pacsysclean.sh.in +rankmirrors: $(srcdir)/rankmirrors.sh.in zsh_completion: $(srcdir)/zsh_completion.in # vim:set ts=2 sw=2 noet: diff --git a/contrib/rankmirrors.sh.in b/contrib/rankmirrors.sh.in new file mode 100644 index 00000000..875a1439 --- /dev/null +++ b/contrib/rankmirrors.sh.in @@ -0,0 +1,212 @@ +#!/bin/bash +# +# rankmirrors - read a list of mirrors from a file and rank them by speed +# @configure_input@ +# +# Copyright (c) 2009 Matthew Bruenig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# traps interrupt key to spit out pre-interrupt info +trap finaloutput INT + +usage() { + echo "Usage: rankmirrors [options] MIRRORFILE | URL" + echo + echo "Ranks pacman mirrors by their connection and opening speed. Pacman mirror" + echo "files are located in @sysconfdir@/pacman.d/. It can also rank one mirror if the URL is" + echo "provided." + echo + echo "Options:" + echo " --version show program's version number and exit" + echo " -h, --help show this help message and exit" + echo " -n NUM number of servers to output, 0 for all" + echo " -t, --times only output mirrors and their response times" + echo " -u, --url test a specific url" + echo " -v, --verbose be verbose in ouptut" + echo " -r, --repo specify a specific repo name instead of guessing" + exit 0 +} + +version() { + echo "rankmirrors (pacman) @PACKAGE_VERSION@" + echo "Copyright (c) 2009 Matthew Bruenig ." + echo + echo "This is free software; see the source for copying conditions." + echo "There is NO WARRANTY, to the extent permitted by law." + exit 0 +} + +err() { + echo "$1" >&2 + exit 1 +} + +# gettime fetchurl (e.g gettime http://foo.com/core/os/i686/core.db.tar.gz) +# returns the fetching time, or timeout, or unreachable +gettime() { + IFS=' ' output=( $(curl -s -m 10 -w "%{time_total} %{http_code}" "$1" -o/dev/null) ) + (( $? == 28 )) && echo timeout && return + (( ${output[1]} >= 400 || ! ${output[1]} )) && echo unreachable && return + echo "${output[0]}" +} + +# getfetchurl serverurl (e.g. getturl http://foo.com/core/os/i686) +# if $repo is in the line, then assumes core +# if $arch is in the line, then assumes $(uname -m) +# returns a fetchurl (e.g. http://foo.com/core/os/i686/core.db.tar.gz) +ARCH="$(uname -m)" +getfetchurl() { + local strippedurl="${1%/}" + + local replacedurl="${strippedurl//'$arch'/$ARCH}" + if [[ ! $TARGETREPO ]]; then + replacedurl="${replacedurl//'$repo'/core}" + local tmp="${replacedurl%/*}" + tmp="${tmp%/*}" + + local reponame="${tmp##*/}" + else + replacedurl="${replacedurl//'$repo'/$TARGETREPO}" + local reponame="$TARGETREPO" + fi + + if [[ -z $reponame || $reponame = $replacedurl ]]; then + echo "fail" + else + local fetchurl="${replacedurl}/$reponame.db" + echo "$fetchurl" + fi +} + +# This exists to remove the need for a separate interrupt function +finaloutput() { + IFS=$'\n' read -r -d '' -a sortedarray < \ + <(printf '%s\n' "${timesarray[@]}" | LC_COLLATE=C sort) + + # Final output for mirrorfile + numiterator="0" + if [[ $TIMESONLY ]]; then + echo + echo " Servers sorted by time (seconds):" + for line in "${sortedarray[@]}"; do + echo "${line#* } : ${line% *}" + ((numiterator++)) + (( NUM && numiterator >= NUM )) && break + done + else + for line in "${sortedarray[@]}"; do + echo "Server = ${line#* }" + ((numiterator++)) + (( NUM && numiterator >= NUM )) && break + done + fi + exit 0 +} + + +# Argument parsing +[[ $1 ]] || usage +while [[ $1 ]]; do + if [[ ${1:0:2} = -- ]]; then + case "${1:2}" in + help) usage ;; + version) version ;; + times) TIMESONLY=1 ; shift ;; + verbose) VERBOSE=1 ; shift ;; + url) CHECKURL=1; [[ $2 ]] || err "Must specify url."; URL="$2"; shift 2;; + repo) [[ $2 ]] || err "Must specify repo name."; TARGETREPO="$2"; shift 2;; + *) err "\`$1' is an invalid argument." + esac + elif [[ ${1:0:1} = - ]]; then + + if [[ ! ${1:1:1} ]]; then + [[ -t 0 ]] && err "Stdin is empty." + IFS=$'\n' linearray=( $( -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# traps interrupt key to spit out pre-interrupt info -trap finaloutput INT - -usage() { - echo "Usage: rankmirrors [options] MIRRORFILE | URL" - echo - echo "Ranks pacman mirrors by their connection and opening speed. Pacman mirror" - echo "files are located in @sysconfdir@/pacman.d/. It can also rank one mirror if the URL is" - echo "provided." - echo - echo "Options:" - echo " --version show program's version number and exit" - echo " -h, --help show this help message and exit" - echo " -n NUM number of servers to output, 0 for all" - echo " -t, --times only output mirrors and their response times" - echo " -u, --url test a specific url" - echo " -v, --verbose be verbose in ouptut" - echo " -r, --repo specify a specific repo name instead of guessing" - exit 0 -} - -version() { - echo "rankmirrors (pacman) @PACKAGE_VERSION@" - echo "Copyright (c) 2009 Matthew Bruenig ." - echo - echo "This is free software; see the source for copying conditions." - echo "There is NO WARRANTY, to the extent permitted by law." - exit 0 -} - -err() { - echo "$1" >&2 - exit 1 -} - -# gettime fetchurl (e.g gettime http://foo.com/core/os/i686/core.db.tar.gz) -# returns the fetching time, or timeout, or unreachable -gettime() { - IFS=' ' output=( $(curl -s -m 10 -w "%{time_total} %{http_code}" "$1" -o/dev/null) ) - (( $? == 28 )) && echo timeout && return - (( ${output[1]} >= 400 || ! ${output[1]} )) && echo unreachable && return - echo "${output[0]}" -} - -# getfetchurl serverurl (e.g. getturl http://foo.com/core/os/i686) -# if $repo is in the line, then assumes core -# if $arch is in the line, then assumes $(uname -m) -# returns a fetchurl (e.g. http://foo.com/core/os/i686/core.db.tar.gz) -ARCH="$(uname -m)" -getfetchurl() { - local strippedurl="${1%/}" - - local replacedurl="${strippedurl//'$arch'/$ARCH}" - if [[ ! $TARGETREPO ]]; then - replacedurl="${replacedurl//'$repo'/core}" - local tmp="${replacedurl%/*}" - tmp="${tmp%/*}" - - local reponame="${tmp##*/}" - else - replacedurl="${replacedurl//'$repo'/$TARGETREPO}" - local reponame="$TARGETREPO" - fi - - if [[ -z $reponame || $reponame = $replacedurl ]]; then - echo "fail" - else - local fetchurl="${replacedurl}/$reponame.db" - echo "$fetchurl" - fi -} - -# This exists to remove the need for a separate interrupt function -finaloutput() { - IFS=$'\n' read -r -d '' -a sortedarray < \ - <(printf '%s\n' "${timesarray[@]}" | LC_COLLATE=C sort) - - # Final output for mirrorfile - numiterator="0" - if [[ $TIMESONLY ]]; then - echo - echo " Servers sorted by time (seconds):" - for line in "${sortedarray[@]}"; do - echo "${line#* } : ${line% *}" - ((numiterator++)) - (( NUM && numiterator >= NUM )) && break - done - else - for line in "${sortedarray[@]}"; do - echo "Server = ${line#* }" - ((numiterator++)) - (( NUM && numiterator >= NUM )) && break - done - fi - exit 0 -} - - -# Argument parsing -[[ $1 ]] || usage -while [[ $1 ]]; do - if [[ ${1:0:2} = -- ]]; then - case "${1:2}" in - help) usage ;; - version) version ;; - times) TIMESONLY=1 ; shift ;; - verbose) VERBOSE=1 ; shift ;; - url) CHECKURL=1; [[ $2 ]] || err "Must specify url."; URL="$2"; shift 2;; - repo) [[ $2 ]] || err "Must specify repo name."; TARGETREPO="$2"; shift 2;; - *) err "\`$1' is an invalid argument." - esac - elif [[ ${1:0:1} = - ]]; then - - if [[ ! ${1:1:1} ]]; then - [[ -t 0 ]] && err "Stdin is empty." - IFS=$'\n' linearray=( $( Date: Mon, 19 Mar 2012 23:56:59 -0400 Subject: libalpm: add pkg-config file No one seems to do this "correctly", but for the sake of having an easy method of detecting the presence and version of libalpm on a given system, we provide a straightforward .pc file. Signed-off-by: Dave Reisner --- configure.ac | 1 + lib/libalpm/.gitignore | 1 + lib/libalpm/Makefile.am | 3 +++ lib/libalpm/libalpm.pc.in | 12 ++++++++++++ 4 files changed, 17 insertions(+) create mode 100644 lib/libalpm/libalpm.pc.in diff --git a/configure.ac b/configure.ac index 0e78c238..15e93e71 100644 --- a/configure.ac +++ b/configure.ac @@ -449,6 +449,7 @@ AC_DEFINE_UNQUOTED([SCRIPTLET_SHELL], "$SCRIPTLET_SHELL", [The full path of the AC_CONFIG_FILES([ lib/libalpm/Makefile lib/libalpm/po/Makefile.in +lib/libalpm/libalpm.pc src/pacman/Makefile src/pacman/po/Makefile.in src/util/Makefile diff --git a/lib/libalpm/.gitignore b/lib/libalpm/.gitignore index 36d41441..82318d3f 100644 --- a/lib/libalpm/.gitignore +++ b/lib/libalpm/.gitignore @@ -2,3 +2,4 @@ .libs *.lo *.la +libalpm.pc diff --git a/lib/libalpm/Makefile.am b/lib/libalpm/Makefile.am index 0781d5d8..ef448417 100644 --- a/lib/libalpm/Makefile.am +++ b/lib/libalpm/Makefile.am @@ -23,6 +23,9 @@ if ENABLE_GNU89_INLINE_CC AM_CFLAGS += -fgnu89-inline endif +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libalpm.pc + libalpm_la_SOURCES = \ add.h add.c \ alpm.h alpm.c \ diff --git a/lib/libalpm/libalpm.pc.in b/lib/libalpm/libalpm.pc.in new file mode 100644 index 00000000..fe4e2583 --- /dev/null +++ b/lib/libalpm/libalpm.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libalpm +Description: Arch Linux package management library +URL: http://www.archlinux.org/pacman/ +Version: @VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -lalpm +Libs.private: @LIBS@ @LIBARCHIVE_LIBS@ @LIBSSL_LIBS@ @LIBCURL_LIBS@ @GPGME_LIBS@ -- cgit v1.2.3-24-g4f1b