#!/bin/bash # Useful functions UMASK="" set_umask () { [ "$UMASK" == "" ] && UMASK="$(umask)" export UMASK umask 002 } restore_umask () { umask $UMASK >/dev/null } # set up general environment WORKDIR=$(mktemp -d /tmp/$(basename $0).XXXXXXXXXX) LOCKS=() # check if messages are to be printed using color unset ALL_OFF BOLD BLUE GREEN RED YELLOW if [[ -t 2 ]]; then ALL_OFF="$(tput sgr0)" BOLD="$(tput bold)" BLUE="${BOLD}$(tput setaf 4)" GREEN="${BOLD}$(tput setaf 2)" RED="${BOLD}$(tput setaf 1)" YELLOW="${BOLD}$(tput setaf 3)" fi readonly ALL_OFF BOLD BLUE GREEN RED YELLOW plain() { local mesg=$1; shift printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" } msg() { local mesg=$1; shift printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" } msg2() { local mesg=$1; shift printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" } warning() { local mesg=$1; shift printf "${YELLOW}==> WARNING:${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 } error() { local mesg=$1; shift printf "${RED}==> ERROR${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 } script_lock() { local LOCKDIR="$TMPDIR/.scriptlock.$(basename $0)" if ! mkdir "$LOCKDIR" >/dev/null 2>&1 ; then local _owner="$(/usr/bin/stat -c %U $LOCKDIR)" error "Script $(basename $0) is already locked by $_owner." exit 1 else set_umask return 0 fi } script_unlock() { local LOCKDIR="$TMPDIR/.scriptlock.$(basename $0)" if [ ! -d "$LOCKDIR" ]; then warning "Script $(basename $0) was not locked!" restore_umask return 1 else rmdir "$LOCKDIR" restore_umask return 0 fi } cleanup() { local l local repo local arch trap - EXIT INT QUIT TERM for l in ${LOCKS[@]}; do repo=${l%.*} arch=${l#*.} if [ -d "$TMPDIR/.repolock.$repo.$arch" ]; then msg "Removing left over lock from $repo/$arch" repo_unlock $repo $arch fi done if [ -d "$TMPDIR/.scriptlock.$(basename $0)" ]; then msg "Removing left over lock from $(basename $0)" script_unlock fi rm -rf "$WORKDIR" [ "$1" ] && exit $1 } abort() { msg 'Aborting...' cleanup 0 } die() { error "$*" cleanup 1 } trap abort INT QUIT TERM HUP trap cleanup EXIT #repo_lock [timeout] repo_lock () { local LOCKDIR="$TMPDIR/.repolock.$1.$2" local _count local _trial local _timeout local _lockblock local _owner if [ $# -eq 2 ]; then _lockblock=true _trial=0 elif [ $# -eq 3 ]; then _lockblock=false _timeout=$3 let _trial=$_timeout/$LOCK_DELAY fi _count=0 while [ $_count -le $_trial ] || $_lockblock ; do if ! mkdir "$LOCKDIR" >/dev/null 2>&1 ; then _owner="$(/usr/bin/stat -c %U $LOCKDIR)" warning "Repo $1-$2 is already locked by $_owner. " \ "Retrying in $LOCK_DELAY seconds..." else LOCKS[${#LOCKS[*]}]="$1.$2" set_umask return 0 fi sleep $LOCK_DELAY let _count=$_count+1 done error "Repo $1-$2 is already locked by $_owner. Giving up!" return 1 } repo_unlock () { #repo_unlock local LOCKDIR="$TMPDIR/.repolock.$1.$2" if [ ! -d "$LOCKDIR" ]; then warning "Repo lock $1-$2 was not locked!" restore_umask return 1 else rmdir "$LOCKDIR" restore_umask return 0 fi } # usage: _grep_pkginfo pkgfile pattern _grep_pkginfo() { local _ret _ret="$(/usr/bin/bsdtar -xOqf "$1" .PKGINFO | /bin/grep -m 1 -E "$2" | /bin/sed 's|\w*\s*=\s*\(.*\)|\1|')" echo "$_ret" } # Get the package base or name as fallback getpkgbase() { local _base _base="$(_grep_pkginfo "$1" "^pkgbase")" if [ -z "$_base" ]; then getpkgname "$1" fi echo "$_base" } # Get the package name getpkgname() { local _name _name="$(_grep_pkginfo "$1" "^pkgname")" if [ -z "$_name" ]; then error "Package '$1' has no pkgname in the PKGINFO. Fail!" exit 1 fi echo "$_name" } # Get the pkgver-pkgrel of this package getpkgver() { local _ver _ver="$(_grep_pkginfo "$1" "^pkgver")" if [ -z "$_ver" ]; then error "Package '$1' has no pkgver in the PKGINFO. Fail!" exit 1 fi echo "$_ver" } getpkgfile() { if [[ ${#} -ne 1 ]]; then error 'No canonical package found!' exit 1 elif [ ! -f "${1}" ]; then error "Package ${1} not found!" exit 1 fi echo ${1} } getpkgfiles() { local f if [ ! -z "$(echo ${@%\.*} | sed "s/ /\n/g" | sort | uniq -D)" ]; then error 'Duplicate packages found!' exit 1 fi for f in ${@}; do if [ ! -f "${f}" ]; then error "Package ${f} not found!" exit 1 fi done echo ${@} } #check_pkg_arch pkgfile arch check_pkg_arch () { local _arch _arch="$(_grep_pkginfo "$1" "^arch")" if [ -z "$_arch" ]; then error "Package '$1' has no arch in the PKGINFO. Fail!" return 1 fi if [ "$_arch" = "$2" ]; then return 0 else return 1 fi } get_repos_for_host() { if [ "$(hostname)" = "sigurd" ]; then echo "community community-testing" else echo "core extra testing" fi } get_pkgpool_for_host() { if [ "$(hostname)" = "sigurd" ]; then echo "pool/community" else echo "pool/packages" fi } #usage: chk_license ${license[@]}" chk_license() { local l local allowed for l in "$@"; do l="$(echo $l | tr '[:upper:]' '[:lower:]')" for allowed in ${ALLOWED_LICENSES[@]}; do allowed="$(echo $allowed | tr '[:upper:]' '[:lower:]')" if [ "$l" = "$allowed" ]; then return 0 fi done done return 1 } pkgname_from_src() { local tmp local a tmp=${1##*/} tmp=${tmp%$SRCEXT} for a in ${ARCHES[@]}; do tmp=${tmp%-$a} done tmp=${tmp%-any} echo ${tmp%-*-*} } pkgver_from_src() { local tmp local a tmp=${1##*/} tmp=${tmp%$SRCEXT} for a in ${ARCHES[@]}; do tmp=${tmp%-$a} done tmp=${tmp%-any} echo $tmp | sed 's|.*-\(.*-.*\)$|\1|g' } check_repo_permission() { local repo=$1 local repos="$(get_repos_for_host)" local found=false local r for r in $repos; do if [ "$r" = "$repo" ]; then found=true fi done [ $found ] || return 1 [ -w "$FTP_BASE/$(get_pkgpool_for_host)" ] || return 1 local arch for arch in ${ARCHES} any; do local w local ws=("${FTP_BASE}/${repo}/os/${arch}/"{,${repo}${DBEXT}}) for w in ws; do [ -w ] || return 1 done done return 0 }