mirror of
git://slackware.nl/current.git
synced 2024-12-28 09:59:53 +01:00
65b9f8df0a
a/gawk-5.2.1-x86_64-1.txz: Upgraded. a/rpm2tgz-1.2.2-x86_64-7.txz: Rebuilt. Take rpmoffset fixes from Gentoo. Thanks to allend. d/ccache-4.7.4-x86_64-1.txz: Upgraded. d/meson-0.64.1-x86_64-1.txz: Upgraded. d/parallel-20221122-noarch-1.txz: Upgraded. kde/fcitx5-configtool-5.0.16-x86_64-1.txz: Upgraded. l/SDL2-2.26.0-x86_64-1.txz: Upgraded. l/glib2-2.74.1-x86_64-2.txz: Rebuilt. [PATCH 1/2] Revert "Handling collision between standard i/o file descriptors and newly created ones." [PATCH 2/2] glib-unix: Add test to make sure g_unix_open_pipe will intrude standard range. Thanks to marav. l/newt-0.52.22-x86_64-1.txz: Upgraded. l/pipewire-0.3.60-x86_64-2.txz: Rebuilt. [PATCH] alsa: force playback start when buffer is full. Thanks to marav. tcl/tcl-8.6.13-x86_64-1.txz: Upgraded. tcl/tk-8.6.13-x86_64-1.txz: Upgraded. x/libglvnd-1.6.0-x86_64-1.txz: Upgraded. x/wayland-protocols-1.30-noarch-1.txz: Upgraded. xap/blueman-2.3.5-x86_64-1.txz: Upgraded.
144 lines
3.3 KiB
C
144 lines
3.3 KiB
C
|
|
/* Find how deeply inside an .RPM the real data is */
|
|
/* kept, and report the offset in bytes */
|
|
|
|
/* Wouldn't it be a lot more sane if we could just untar these things? */
|
|
|
|
#ifndef _GNU_SOURCE
|
|
# define _GNU_SOURCE
|
|
#endif
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#ifndef ARRAY_SIZE
|
|
# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
|
#endif
|
|
#ifndef BUFSIZ
|
|
# define BUFSIZ 8192
|
|
#endif
|
|
|
|
#if !defined(__GLIBC__)
|
|
static void *rp_memmem(const void *buf, size_t buflen, const void *pattern, size_t len)
|
|
{
|
|
char *bf = (char *)buf, *pt = (char *)pattern, *p = bf;
|
|
|
|
while (len <= (buflen - (p - bf))) {
|
|
if (NULL != (p = memchr(p, (int)(*pt), buflen - (p - bf)))) {
|
|
if (0 == memcmp(p, pattern, len))
|
|
return p;
|
|
else
|
|
++p;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
return NULL;
|
|
}
|
|
#define memmem(a,b,c,d) rp_memmem(a,b,c,d)
|
|
#endif
|
|
|
|
typedef struct {
|
|
const char *type;
|
|
const unsigned char *magic;
|
|
const size_t len;
|
|
} magic_t;
|
|
|
|
/* LZMA is some fuzzy crap */
|
|
int is_magic_lzma(const char *buf)
|
|
{
|
|
const unsigned char *ubuf = (const void *)buf;
|
|
return (ubuf[0] == 0x5d && ubuf[4] < 0x20) &&
|
|
(!memcmp(buf + 10, "\x00\x00\x00", 3) ||
|
|
!memcmp(buf + 5, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8));
|
|
}
|
|
#define magic_lzma_len 13
|
|
|
|
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 unsigned char magic_zstd[] = { 0x28, 0xB5, 0x2F, 0xFD };
|
|
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)
|
|
DECLARE_MAGIC_T(zstd)
|
|
#undef DECLARE_MAGIC_T
|
|
};
|
|
#define MAGIC_SIZE_MIN 3
|
|
#define MAGIC_SIZE_MAX 13
|
|
|
|
static int show_magic;
|
|
|
|
static int magic_finish(const char *magic, size_t offset)
|
|
{
|
|
if (show_magic)
|
|
printf("%s ", magic);
|
|
printf("%zu\n", offset);
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
size_t i, read_cnt, offset, left, lzma_offset;
|
|
FILE *fp = stdin;
|
|
char p[BUFSIZ];
|
|
|
|
if (argc == 2 && !strcmp(argv[1], "-v")) {
|
|
show_magic = 1;
|
|
--argc;
|
|
}
|
|
|
|
if (argc != 1) {
|
|
puts("Usage: rpmoffset < rpmfile");
|
|
return 1;
|
|
}
|
|
/* fp = fopen(argv[1], "r"); */
|
|
|
|
lzma_offset = 0;
|
|
offset = left = 0;
|
|
while (1) {
|
|
read_cnt = fread(p + left, 1, sizeof(p) - left, fp);
|
|
if (read_cnt + left < MAGIC_SIZE_MIN)
|
|
break;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(magics); ++i) {
|
|
const char *needle;
|
|
|
|
if (read_cnt + left < magics[i].len)
|
|
continue;
|
|
|
|
needle = memmem(p, sizeof(p), magics[i].magic, magics[i].len);
|
|
if (needle)
|
|
return magic_finish(magics[i].type, offset + (needle - p));
|
|
}
|
|
|
|
/* Scan for LZMA magic, but don't return yet ... */
|
|
if (!lzma_offset && read_cnt + left >= magic_lzma_len) {
|
|
for (i = 0; i <= read_cnt + left - magic_lzma_len; ++i)
|
|
if (is_magic_lzma(p + i)) {
|
|
lzma_offset = offset + i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
memmove(p, p + left + read_cnt - MAGIC_SIZE_MIN + 1, MAGIC_SIZE_MIN - 1);
|
|
|
|
offset += read_cnt;
|
|
if (left == 0) {
|
|
offset -= MAGIC_SIZE_MIN - 1;
|
|
left = MAGIC_SIZE_MIN - 1;
|
|
}
|
|
}
|
|
|
|
/* Delay till the end for LZMA archives since it is too fuzzy */
|
|
if (lzma_offset)
|
|
return magic_finish("lzma", lzma_offset);
|
|
|
|
if (ferror(stdin))
|
|
perror(argv[0]);
|
|
|
|
return 1;
|
|
}
|