diff options
-rw-r--r-- | Makefile | 2 | ||||
-rwxr-xr-x | rpm2targz | 33 | ||||
-rw-r--r-- | rpmoffset.c | 45 |
3 files changed, 54 insertions, 26 deletions
@@ -30,7 +30,7 @@ install: rpmoffset $(dodir) $(DESTDIR)$(bindir) $(dobin) rpm2targz rpmoffset $(DESTDIR)$(bindir) set -e ; \ - for t in tar tarbz2 tbz2 tarlzma tgz ; do \ + for t in tar tarbz2 tbz2 tarlzma tgz tarxz txz ; do \ $(dosym) rpm2targz $(DESTDIR)$(bindir)/rpm2$$t ; \ done $(dosym) rpm2targz $(DESTDIR)$(bindir)/rpmunpack @@ -71,14 +71,16 @@ else fi compress="cat" -case ${argv0} in - rpmunpack) suffix="";; - rpm2tar) suffix=".tar";; - rpm2tarbz2) compress="bzip2" suffix=".tar.bz2";; - rpm2tbz2) compress="bzip2" suffix=".tbz2";; - rpm2tarlzma) compress="lzma" suffix=".tar.lzma";; - rpm2tgz) compress="gzip" suffix=".tgz";; - rpm2targz|*) compress="gzip" suffix=".tar.gz";; +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";; + 2targz|*) compress="gzip" suffix=".tar.gz";; esac case ${argv0} in rpm2tar*) strip=true;; @@ -143,17 +145,18 @@ for file; do # extract the CPIO from the RPM and unpack it ( decompressor="" - if command -v rpm2cpio 2>/dev/null 1>&2 ; then + # 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 :/ - 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 + 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 diff --git a/rpmoffset.c b/rpmoffset.c index b8f5a04..0a3c488 100644 --- a/rpmoffset.c +++ b/rpmoffset.c @@ -19,18 +19,36 @@ # define BUFSIZ 8192 #endif -#define MAGIC_SIZE 3 +typedef struct { + const char *type; + const unsigned char *magic; + const size_t len; +} magic_t; + +static const unsigned char magic_gzip[] = { '\037', '\213', '\010' }; +static const unsigned char magic_bzip2[] = { 'B', 'Z', 'h' }; +static const unsigned char magic_xz[] = { 0xFD, '7', 'z', 'X', 'Z', 0x00 }; +static const magic_t magics[] = { +#define DECLARE_MAGIC_T(t) { .type = #t, .magic = magic_##t, .len = sizeof(magic_##t), }, + DECLARE_MAGIC_T(gzip) + DECLARE_MAGIC_T(bzip2) + DECLARE_MAGIC_T(xz) +#undef DECLARE_MAGIC_T +}; +#define MAGIC_SIZE_MIN 3 +#define MAGIC_SIZE_MAX 6 int main(int argc, char *argv[]) { + int show_magic = 0; size_t i, read_cnt, offset, left; FILE *fp = stdin; char p[BUFSIZ]; - const char magics[][MAGIC_SIZE] = { - { '\037', '\213', '\010' }, /* gzip */ - { 'B', 'Z', 'h' }, /* bzip */ - }; + if (argc == 2 && !strcmp(argv[1], "-v")) { + show_magic = 1; + --argc; + } if (argc != 1) { puts("Usage: rpmoffset < rpmfile"); @@ -41,23 +59,30 @@ int main(int argc, char *argv[]) offset = left = 0; while (1) { read_cnt = fread(p + left, 1, sizeof(p) - left, fp); - if (read_cnt + left < MAGIC_SIZE) + if (read_cnt + left < MAGIC_SIZE_MIN) break; for (i = 0; i < ARRAY_SIZE(magics); ++i) { - char *needle = memmem(p, sizeof(p), magics[i], MAGIC_SIZE); + const char *needle; + + if (read_cnt + left < magics[i].len) + continue; + + needle = memmem(p, sizeof(p), magics[i].magic, magics[i].len); if (needle) { + if (show_magic) + printf("%s ", magics[i].type); printf("%zu\n", offset + (needle - p)); return 0; } } - memmove(p, p + left + read_cnt - MAGIC_SIZE + 1, MAGIC_SIZE - 1); + memmove(p, p + left + read_cnt - MAGIC_SIZE_MIN + 1, MAGIC_SIZE_MIN - 1); offset += read_cnt; if (left == 0) { - offset -= MAGIC_SIZE - 1; - left = MAGIC_SIZE - 1; + offset -= MAGIC_SIZE_MIN - 1; + left = MAGIC_SIZE_MIN - 1; } } |