#!/bin/sh # Copyright 1997, 1998 Patrick Volkerding, Moorhead, MN USA # Copyright 2002 Slackware Linux, Inc., Concord, CA USA # All rights reserved. # # Redistribution and use of this script, with or without modification, is # permitted provided that the following conditions are met: # # 1. Redistributions of this script must retain the above copyright # notice, this list of conditions and the following disclaimer. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # argv0=${0##*/} warn() { echo "${argv0}: warning: $*" 1>&2; } err() { echo "${argv0}: warning: $*" 1>&2; exit 1; } usage=false stdout=false verbose=false strip=false files=false msg="" for opt; do case ${opt} in -h|--help) usage=true;; -O|--stdout) stdout=true;; -v|--verbose) verbose=true;; -S|--strip-path) strip=true;; --) break;; -*) usage=true msg="unknown option '${opt}'";; *) files=true;; esac done if ! ${files} || ${usage} ; then cat <<-EOF ${argv0}: Converts RPM archives to tar archives Usage: ${argv0} [options] Options: -h, --help This help screen (imagine that) -O, --stdout Write tarball to stdout -S, --strip-path Strip package name from tarball -v, --verbose Verbose output EOF if [ -n "${msg}" ] ; then err "${msg}" else exit 0 fi fi # allow for local development if [ "${0#./}" != "${0}" -a -x "./rpmoffset" ] ; then rpmoffset="./rpmoffset" else rpmoffset="rpmoffset" fi compress="cat" case ${argv0#rpm} in unpack) suffix="";; 2tar) suffix=".tar";; 2tarbz2) compress="bzip2" suffix=".tar.bz2";; 2tbz2) compress="bzip2" suffix=".tbz2";; 2tarlzma) compress="lzma" suffix=".tar.lzma";; 2tgz) compress="gzip" suffix=".tgz";; 2tarxz) compress="xz" suffix=".tar.xz";; 2txz) compress="xz" suffix=".txz";; 2tarzst) compress="zstd" suffix=".tar.zst";; 2targz|*) compress="gzip" suffix=".tar.gz";; esac case ${argv0} in rpm2tar*) strip=true;; esac # try to get a temp dir using progressively older/crappier methods WORKDIR="" trap 'rm -rf "${WORKDIR}"' 0 WORKDIR=$(mktemp -d --tmpdir ${argv0}.XXXXXX 2>/dev/null) if [ -z "${WORKDIR}" ] ; then WORKDIR=$(mktemp -d -t ${argv0}.XXXXXX 2>/dev/null) if [ -z "${WORKDIR}" ] ; then [ -z "${TMPDIR}" ] && TMPDIR="/tmp" WORKDIR=$(mcookie 2>/dev/null) if [ -n "${WORKDIR}" ] ; then WORKDIR="${TMPDIR}/${WORKDIR}" else WORKDIR="${TMPDIR}/$$" fi worked=false if rm -rf "${WORKDIR}" ; then if mkdir -m 700 -p "${WORKDIR}" ; then worked=true elif mkdir -p "${WORKDIR}" ; then if chmod 700 "${WORKDIR}" ; then worked=true fi fi fi if ! ${worked} ; then err "${WORKDIR}: unable to create a temp directory" fi fi fi ret=0 dashdash=false for file; do if ! ${dashdash} ; then case ${file} in -v|--verbose) continue;; -O|--stdout) continue;; -S|--strip-path) continue;; --) dashdash=true; continue;; esac fi ${verbose} && printf "Processing file: ${file} ... " outfile=${file##*/} outfile=${outfile%.rpm} ${strip} && base="" || base=${outfile%.src} DEST="${WORKDIR}/${base}" rm -rf "${DEST}" if ! mkdir "${DEST}" ; then rm -rf "${WORKDIR}" & err "${file}: ${DEST}: unable to create working directory" fi # extract the CPIO from the RPM and unpack it ( decompressor="" # Disable rpm2cpio as it might be broken #249769, # or it might be too old #292057 #if command -v rpm2cpio >/dev/null 2>&1 ; then if false ; then decompressor="rpm2cpio" rpm2cpio "${file}" else # do it by hand :/ set -- $(${rpmoffset} -v < "${file}") decompressor=$1 offset=$2 [ -z "${offset}" ] && err "unable to locate cpio offset (broken/unknown compression?)" dd ibs=${offset} skip=1 if="${file}" 2>/dev/null | ${decompressor} -dc fi [ $? -ne 0 ] && echo "${argv0}: ${file}: failed to extract cpio via ${decompressor} (not actually an RPM?)" 1>&2 ) | ( cd "${DEST}" # filter stupid blocks info from cpio cpio -i -m -d 2>/dev/null ) if [ $? -ne 0 ] ; then false elif [ -n "${suffix}" ] ; then # repack the files into the appropriate tar file ( cd "${WORKDIR}" tar cf - "./${base}" ) | ${compress} | ( if ${stdout} ; then cat else cat > "${outfile}${suffix}" fi ) else # just unpacking, so move the files cp -pPR "${DEST}/" ./ fi tret=$? if [ ${tret} -eq 0 ] ; then msg=OK else ret=${tret} msg=FAIL fi ${verbose} && echo ${msg} rm -rf "${DEST}" done # No need for this as the trap will take care of it #rm -rf "${WORKDIR}" exit ${ret}