aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2008-05-31 17:02:21 -0400
committerMike Frysinger <vapier@gentoo.org>2008-05-31 17:10:39 -0400
commit6ef605f0d52f06d2146f88872f23f425323f754c (patch)
tree280c80ccd37fc9e81138a4360497dd28ad53074c
parentrpm2targz: fixup bashisms that leaked in (diff)
downloadrpm2targz-6ef605f0d52f06d2146f88872f23f425323f754c.tar.gz
rpm2targz-6ef605f0d52f06d2146f88872f23f425323f754c.tar.bz2
rpm2targz-6ef605f0d52f06d2146f88872f23f425323f754c.zip
rewrite and cleanup
This rewrites the rpm2targz script so that it is easier to extend with custom invocation names (rpm2targz/rpm2tgz/rpm2tar/etc...), with a variety of directory creation tools (mktemp/mcookie/whatever), and with command line options. It also cleans up after itself and includes a lot of error checking. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rwxr-xr-xrpm2targz250
1 files changed, 150 insertions, 100 deletions
diff --git a/rpm2targz b/rpm2targz
index fb9cb47..dcfdc27 100755
--- a/rpm2targz
+++ b/rpm2targz
@@ -21,107 +21,157 @@
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
-# debug switch to allow to bypass use of rpm2cpio provided by the rpm package
-USERPM2CPIO=true
-[ "$TMPDIR" = "" ] && TMPDIR=/tmp
-if [ ! -d "$TMPDIR" ]; then
- echo "TMPDIR=$TMPDIR is not a dir" > /dev/stderr
- exit 1
-fi
-WORKDIR=`mktemp -d $TMPDIR/$$XXXXXX`
-if [ $? != 0 ]; then
- echo "Failed to make tmp workdir for file i/o conversion" > /dev/stderr
- exit 1
+argv0=${0##*/}
+
+usage=false
+stdout=false
+verbose=false
+files=false
+msg=""
+for opt; do
+ case ${opt} in
+ -h|--help) usage=true;;
+ -O|--stdout) stdout=true;;
+ -v|--verbose) verbose=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] <rpms>
+
+ Options:
+ -h, --help This help screen (imagine that)
+ -O, --stdout Write tarball to stdout
+ -v, --verbose Verbose output
+ EOF
+
+ if [ -n "${msg}" ] ; then
+ echo "Error: ${msg}" 1>&2
+ exit 1
+ else
+ exit 0
+ fi
fi
-if [ "$1" = "" ]; then
- echo "$0: Converts RPM format to standard GNU tar + GNU zip format."
- if [ -e /etc/slackware-version ]; then
- echo " (view converted packages with \"less\", install and remove"
- echo " with \"installpkg\", \"removepkg\", \"pkgtool\", or manually"
- echo " with \"tar\")"
- fi
- echo
- echo "Usage: $0 <file.rpm>"
- if [ "`basename $0`" = "rpm2tgz" ]; then
- echo " (Outputs \"file.tgz\")"
- else
- echo " (Outputs \"file.tar.gz\")"
- fi
- exit 1;
+compress="cat"
+case ${argv0} in
+ rpm2tar) suffix=".tar";;
+ rpm2tarbz2) compress="bzip2" suffix=".tar.bz2";;
+ rpm2tbz2) compress="bzip2" suffix=".tbz2";;
+ rpm2tarlzma) compress="lzma" suffix=".tarlzma";;
+ rpm2tgz) compress="gzip" suffix=".tgz";;
+ rpm2targz|*) compress="gzip" suffix=".tar.gz";;
+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
+ echo "${argv0}: ${WORKDIR}: unable to create a temp directory"
+ exit 1
+ fi
+ fi
fi
-for i in $* ; do
- if [ ! "$1" = "$*" ]; then
- echo "Processing file: $i"
- fi
- rm -rf ${WORKDIR}/* || exit 1 ; # clear the way, just in case of mischief
-
- # Determine if this is a source or binary RPM.
- # If we have getrpmtype, use that. Otherwise, try "file".
- if command -v getrpmtype 1> /dev/null 2> /dev/null; then
- if getrpmtype -n $i | grep source 1> /dev/null 2> /dev/null ; then
- isSource=1
- else
- isSource=0
- fi
- else # use file. This works fine on Slackware, and is the default.
- if file $i | grep RPM | grep " src " 1> /dev/null 2> /dev/null ; then
- isSource=1
- else
- isSource=0
- fi
- fi
-
- ofn=${WORKDIR}/`basename $i .rpm`.cpio
- if $USERPM2CPIO && command -v rpm2cpio 1> /dev/null 2> /dev/null ; then
- rpm2cpio $i > $ofn 2> /dev/null
- if [ ! $? = 0 ]; then
- echo "... rpm2cpio failed. (maybe $i is not an RPM?)"
- ( rm -rf "${WORKDIR}/*" )
- continue
- fi
- else # less reliable than rpm2cpio...
- # get offset of start of payload
- PAYLOADOFFSET=`rpmoffset < $i`
- #identify compression
- PAYLOADHEAD=`dd ibs=${PAYLOADOFFSET} skip=1 if=$i 2> /dev/null | dd bs=10 count=1 2> /dev/null`
- if echo ${PAYLOADHEAD} | od -c | grep '037.213' > /dev/null ; then
- echo "found gzip magic bytes"
- decomp="gzip"
- elif echo ${PAYLOADHEAD} | grep -e "^BZh" > /dev/null ; then
- echo "found bzip magic bytes"
- decomp="bzip2"
- else
- echo " $i - no magic compression identifier found - skipping file"
- ( rm -rf "${WORKDIR}/*" )
- continue
- fi
- echo -n " trying to decompress with ${decomp}..."
- dd ibs=`rpmoffset < $i` skip=1 if=$i 2> /dev/null | ${decomp} -dc > $ofn 2> /dev/null
- if [ $? = 0 ]; then
- echo " OK"
- else
- echo " FAILED"
- echo " $i failed to decompress - skipping file"
- ( rm -rf "${WORKDIR}/*" )
- continue
- fi
- fi
- DEST=${WORKDIR}
- if [ "$isSource" = "1" ]; then
- DEST=$DEST/$(basename $(basename $i .rpm) .src)
- fi
- mkdir -p $DEST
- ( cd $DEST
- cpio -i -m -d < $ofn 1> /dev/null 2> /dev/null
- rm -f $ofn
- find . -type d -perm 700 -exec chmod 755 {} \; )
- ( cd ${WORKDIR} ; tar cf - . ) > `basename $i .rpm`.tar
- gzip -9 `basename $i .rpm`.tar
- if [ "`basename $0`" = "rpm2tgz" ]; then
- mv `basename $i .rpm`.tar.gz `basename $i .rpm`.tgz
- fi
- ( rm -rf "${WORKDIR}/*" )
- echo
+
+ret=0
+dashdash=false
+for file; do
+ if ! ${dashdash} ; then
+ case ${file} in
+ -v|--verbose) continue;;
+ -O|--stdout) continue;;
+ --) dashdash=true; continue;;
+ esac
+ fi
+
+ ${verbose} && printf "Processing file: ${file} ... "
+
+ outfile=${file##*/}
+ outfile=${outfile%.rpm}
+ base=${outfile%.src}
+ DEST="${WORKDIR}/${base}"
+ rm -rf "${DEST}"
+ if ! mkdir "${DEST}" ; then
+ echo "${argv0}: ${file}: ${DEST}: unable to create working directory"
+ rm -rf "${WORKDIR}"
+ exit 1
+ fi
+
+ # extract the CPIO from the RPM and unpack it
+ (
+ decompressor=""
+ if command -v rpm2cpio 2>/dev/null 1>&2 ; then
+ decompressor="rpm2cpio"
+ rpm2cpio "${file}"
+ else
+ # do it by hand :/
+ offset=$(rpmoffset < "${file}")
+ magic=`(dd ibs=${offset} skip=1 if="${file}" count=1 | dd bs=10 count=1 | od -b) 2>/dev/null`
+ case ${magic} in
+ "0000000 102 132 150 "*) decompressor="bzip2";;
+ "0000000 037 213 010 "*|*) decompressor="gzip";;
+ esac
+ 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
+ ret=1
+
+ ${verbose} && echo "FAIL"
+ else
+ # repack the files into the appropriate tar file
+ (
+ cd "${WORKDIR}"
+ tar cf - "./${base}"
+ ) | ${compress} | (
+ if ${stdout} ; then
+ cat
+ else
+ cat > "${outfile}${suffix}"
+ fi
+ )
+
+ ${verbose} && echo "OK"
+ fi
+
+ rm -rf "${DEST}"
done
-rm -rf ${WORKDIR}
+
+rm -rf "${WORKDIR}"
+
+exit ${ret}