/* vi: set sw=4 ts=4: */
/*
 * Mini rpm2cpio implementation for busybox
 *
 * Copyright (C) 2001 by Laurence Anderson
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */

//usage:#define rpm2cpio_trivial_usage
//usage:       "package.rpm"
//usage:#define rpm2cpio_full_usage "\n\n"
//usage:       "Output a cpio archive of the rpm file"

#include "libbb.h"
#include "archive.h"
#include "rpm.h"

enum { rpm_fd = STDIN_FILENO };

static unsigned skip_header(void)
{
	struct rpm_header header;
	unsigned len;

	xread(rpm_fd, &header, sizeof(header));
//	if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC_STR, 3) != 0) {
//		bb_error_msg_and_die("invalid RPM header magic");
//	}
//	if (header.version != 1) {
//		bb_error_msg_and_die("unsupported RPM header version");
//	}
	if (header.magic_and_ver != htonl(RPM_HEADER_MAGICnVER)) {
		bb_error_msg_and_die("invalid RPM header magic or unsupported version");
		// ": %x != %x", header.magic_and_ver, htonl(RPM_HEADER_MAGICnVER));
	}

	/* Seek past index entries, and past store */
	len = 16 * ntohl(header.entries) + ntohl(header.size);
	seek_by_jump(rpm_fd, len);

	return sizeof(header) + len;
}

/* No getopt required */
int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
{
	struct rpm_lead lead;
	unsigned pos;

	if (argv[1]) {
		xmove_fd(xopen(argv[1], O_RDONLY), rpm_fd);
	}
	xread(rpm_fd, &lead, sizeof(lead));

	/* Just check the magic, the rest is irrelevant */
	if (lead.magic != htonl(RPM_LEAD_MAGIC)) {
		bb_error_msg_and_die("invalid RPM magic");
	}

	/* Skip the signature header, align to 8 bytes */
	pos = skip_header();
	seek_by_jump(rpm_fd, (-(int)pos) & 7);

	/* Skip the main header */
	skip_header();

#if 0
	/* This works, but doesn't report uncompress errors (they happen in child) */
	setup_unzip_on_fd(rpm_fd /*fail_if_not_detected: 1*/);
	if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0)
		bb_error_msg_and_die("error unpacking");
#else
	/* BLOAT */
	{
		union {
			uint8_t b[4];
			uint16_t b16[2];
			uint32_t b32[1];
		} magic;
		IF_DESKTOP(long long) int FAST_FUNC (*unpack)(int src_fd, int dst_fd);

		xread(rpm_fd, magic.b16, sizeof(magic.b16[0]));
		if (magic.b16[0] == GZIP_MAGIC) {
			unpack = unpack_gz_stream;
		} else
		if (ENABLE_FEATURE_SEAMLESS_BZ2
		 && magic.b16[0] == BZIP2_MAGIC
		) {
			unpack = unpack_bz2_stream;
		} else
		if (ENABLE_FEATURE_SEAMLESS_XZ
		 && magic.b16[0] == XZ_MAGIC1
		) {
			xread(rpm_fd, magic.b32, sizeof(magic.b32[0]));
			if (magic.b32[0] != XZ_MAGIC2)
				goto no_magic;
			/* unpack_xz_stream wants fd at position 6, no need to seek */
			//xlseek(rpm_fd, -6, SEEK_CUR);
			unpack = unpack_xz_stream;
		} else {
 no_magic:
			bb_error_msg_and_die("no gzip"
					IF_FEATURE_SEAMLESS_BZ2("/bzip2")
					IF_FEATURE_SEAMLESS_XZ("/xz")
					" magic");
		}
		if (unpack(rpm_fd, STDOUT_FILENO) < 0)
			bb_error_msg_and_die("error unpacking");
	}
#endif

	if (ENABLE_FEATURE_CLEAN_UP) {
		close(rpm_fd);
	}

	return 0;
}
