aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rwxr-xr-xrpm2targz33
-rw-r--r--rpmoffset.c45
3 files changed, 54 insertions, 26 deletions
diff --git a/Makefile b/Makefile
index f051455..5b720f7 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/rpm2targz b/rpm2targz
index e439b08..1fe7a3a 100755
--- a/rpm2targz
+++ b/rpm2targz
@@ -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;
}
}