/*
 * rpmunpack for busybox
 *
 * rpmunpack.c  -  Utility program to unpack an RPM archive
 *
 * Gero Kuhlmann <gero@gkminix.han.de> 1998
 *
 *  This program is public domain software; you can do whatever you like
 *  with this source, including modifying and redistributing it.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
 
#include "busybox.h" 
#include <fcntl.h>

/*
 * Some general definitions
 */
#define BUFSIZE		512
#define RPM_MAGIC	"\355\253\356\333"
#define GZ_MAGIC_1	'\037'
#define GZ_MAGIC_2	'\213'

/*
 * Global variables
 */
static char buffer[BUFSIZE];
static char *progname;
static int infile, outfile;

/*
 * Read a specified number of bytes from input file
 */
static void myread(int num)
{
  int err;

  if ((err = read(infile, buffer, num)) != num) {
	if (err < 0)
		perror(progname);
	else
		fprintf(stderr, "Unexpected end of input file!\n");
	exit(1);
  }
}

/*
 * Main program
 */
int rpmunpack_main(int argc, char **argv)
{
  int len, status = 0;

  /* Get our own program name */
  if ((progname = strrchr(argv[0], '/')) == NULL)
	progname = argv[0];
  else
	progname++;

  /* Check for command line parameters */
	if (argc>=2 && *argv[1]=='-') {
           usage(rpmunpack_usage);
	}

  /* Open input file */
  if (argc == 1)
	infile = STDIN_FILENO;
  else if ((infile = open(argv[1], O_RDONLY)) < 0) {
	perror(progname);
	exit(1);
  }

  /* Read magic ID and output filename */
  myread(4);
  if (strncmp(buffer, RPM_MAGIC, 4)) {
	fprintf(stderr, "Input file is not in RPM format!\n");
	exit(1);
  }
  myread(6);		/* Skip flags */
  myread(64);
  buffer[64] = '\0';

  /* Open output file */
  strcat(buffer, ".cpio.gz");
  if (infile == STDIN_FILENO)
	outfile = STDOUT_FILENO;
  else if ((outfile = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) {
	perror(progname);
	exit(1);
  }

  /*
   * Now search for the GZIP signature. This is rather awkward, but I don't
   * know any other way how to find out the exact starting position of the
   * archive within the input file. There are a couple of data structures
   * and texts (obviously descriptions, installation shell scripts etc.)
   * coming before the archive, but even they start at different offsets
   * with different RPM files. However, it looks like the GZIP signature
   * never appears before offset 0x200, so we skip these first couple of
   * bytes to make the signature scan a little more reliable.
   */
  myread(0x200 - 74);
  while (status < 2) {
	myread(1);
	if (status == 0 && buffer[0] == GZ_MAGIC_1)
		status++;
	else if (status == 1 && buffer[0] == GZ_MAGIC_2)
		status++;
	else
		status = 0;
  }
  buffer[0] = GZ_MAGIC_1;
  buffer[1] = GZ_MAGIC_2;
  if (write(outfile, buffer, 2) < 0) {
	perror(progname);
	exit(1);
  }

  /* Now simply copy the GZIP archive into the output file */
  while ((len = read(infile, buffer, BUFSIZE)) > 0) {
	if (write(outfile, buffer, len) < 0) {
		perror(progname);
		exit(1);
	}
  }
  if (len < 0) {
	perror(progname);
	exit(1);
  }
  close(outfile);
  close(infile);
  exit(0);
}
