/* vi: set sw=4 ts=4: */
/*
 * Mini rpm applet for busybox
 *
 * Copyright (C) 2001,2002 by Laurence Anderson
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 */

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netinet/in.h> /* For ntohl & htonl function */
#include <string.h> /* For strncmp */
#include <sys/mman.h> /* For mmap */
#include <time.h> /* For ctime */

#include "busybox.h"
#include "unarchive.h"

#define RPM_HEADER_MAGIC "\216\255\350"
#define RPM_CHAR_TYPE		1
#define RPM_INT8_TYPE		2
#define RPM_INT16_TYPE		3
#define RPM_INT32_TYPE		4
/* #define RPM_INT64_TYPE	5   ---- These aren't supported (yet) */
#define RPM_STRING_TYPE		6
#define RPM_BIN_TYPE		7
#define RPM_STRING_ARRAY_TYPE	8
#define RPM_I18NSTRING_TYPE	9

#define	RPMTAG_NAME				1000
#define	RPMTAG_VERSION			1001
#define	RPMTAG_RELEASE			1002
#define	RPMTAG_SUMMARY			1004
#define	RPMTAG_DESCRIPTION		1005
#define	RPMTAG_BUILDTIME		1006
#define	RPMTAG_BUILDHOST		1007
#define	RPMTAG_SIZE			1009
#define	RPMTAG_VENDOR			1011
#define	RPMTAG_LICENSE			1014
#define	RPMTAG_PACKAGER			1015
#define	RPMTAG_GROUP			1016
#define RPMTAG_URL			1020
#define	RPMTAG_PREIN			1023
#define	RPMTAG_POSTIN			1024
#define	RPMTAG_FILEFLAGS		1037
#define	RPMTAG_FILEUSERNAME		1039
#define	RPMTAG_FILEGROUPNAME		1040
#define	RPMTAG_SOURCERPM		1044
#define	RPMTAG_PREINPROG		1085
#define	RPMTAG_POSTINPROG		1086
#define	RPMTAG_PREFIXS			1098
#define	RPMTAG_DIRINDEXES		1116
#define	RPMTAG_BASENAMES		1117
#define	RPMTAG_DIRNAMES			1118
#define	RPMFILE_CONFIG			(1 << 0)
#define	RPMFILE_DOC			(1 << 1)

enum rpm_functions_e {
	rpm_query = 1,
	rpm_install = 2,
	rpm_query_info = 4,
	rpm_query_package = 8,
	rpm_query_list = 16,
	rpm_query_list_doc = 32,
	rpm_query_list_config = 64
};

typedef struct {
	uint32_t tag; /* 4 byte tag */
	uint32_t type; /* 4 byte type */
	uint32_t offset; /* 4 byte offset */
	uint32_t count; /* 4 byte count */
} rpm_index;

static void *map;
static rpm_index **mytags;
static int tagcount;

void extract_cpio_gz(int fd);
rpm_index **rpm_gettags(int fd, int *num_tags);
int bsearch_rpmtag(const void *key, const void *item);
char *rpm_getstring(int tag, int itemindex);
int rpm_getint(int tag, int itemindex);
int rpm_getcount(int tag);
void exec_script(int progtag, int datatag, char *prefix);
void fileaction_dobackup(char *filename, int fileref);
void fileaction_setowngrp(char *filename, int fileref);
void fileaction_list(char *filename, int itemno);
void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref));

int rpm_main(int argc, char **argv)
{
	int opt = 0, func = 0, rpm_fd, offset;

	while ((opt = getopt(argc, argv, "iqpldc")) != -1) {
		switch (opt) {
		case 'i': // First arg: Install mode, with q: Information
			if (!func) func |= rpm_install;
			else func |= rpm_query_info;
			break;
		case 'q': // First arg: Query mode
			if (!func) func |= rpm_query;
			else bb_show_usage();
			break;
		case 'p': // Query a package
			func |= rpm_query_package;
			break;
		case 'l': // List files in a package
			func |= rpm_query_list;
			break;
		case 'd': // List doc files in a package (implies list)
			func |= rpm_query_list;
			func |= rpm_query_list_doc;
			break;
		case 'c': // List config files in a package (implies list)
			func |= rpm_query_list;
			func |= rpm_query_list_config;
			break;
		default:
			bb_show_usage();
		}
	}

	if (optind == argc) bb_show_usage();
	while (optind < argc) {
		rpm_fd = bb_xopen(argv[optind], O_RDONLY);
		mytags = rpm_gettags(rpm_fd, (int *) &tagcount);
		offset = lseek(rpm_fd, 0, SEEK_CUR);
		if (!mytags) { printf("Error reading rpm header\n"); exit(-1); }
		map = mmap(0, offset > getpagesize() ? (offset + offset % getpagesize()) : getpagesize(), PROT_READ, MAP_PRIVATE, rpm_fd, 0); // Mimimum is one page
		if (func & rpm_install) {
			loop_through_files(RPMTAG_BASENAMES, fileaction_dobackup); /* Backup any config files */
			extract_cpio_gz(rpm_fd); // Extact the archive
			loop_through_files(RPMTAG_BASENAMES, fileaction_setowngrp); /* Set the correct file uid/gid's */
		} else if (func & rpm_query && func & rpm_query_package) {
			if (!((func & rpm_query_info) || (func & rpm_query_list))) { // If just a straight query, just give package name
				printf("%s-%s-%s\n", rpm_getstring(RPMTAG_NAME, 0), rpm_getstring(RPMTAG_VERSION, 0), rpm_getstring(RPMTAG_RELEASE, 0));
			}
			if (func & rpm_query_info) {
				/* Do the nice printout */
				time_t bdate_time;
				struct tm *bdate;
				char bdatestring[50];
				printf("Name        : %-29sRelocations: %s\n", rpm_getstring(RPMTAG_NAME, 0), rpm_getstring(RPMTAG_PREFIXS, 0) ? rpm_getstring(RPMTAG_PREFIXS, 0) : "(not relocateable)");
				printf("Version     : %-34sVendor: %s\n", rpm_getstring(RPMTAG_VERSION, 0), rpm_getstring(RPMTAG_VENDOR, 0) ? rpm_getstring(RPMTAG_VENDOR, 0) : "(none)");
				bdate_time = rpm_getint(RPMTAG_BUILDTIME, 0);
				bdate = localtime((time_t *) &bdate_time);
				strftime(bdatestring, 50, "%a %d %b %Y %T %Z", bdate);
				printf("Release     : %-30sBuild Date: %s\n", rpm_getstring(RPMTAG_RELEASE, 0), bdatestring);
				printf("Install date: %-30sBuild Host: %s\n", "(not installed)", rpm_getstring(RPMTAG_BUILDHOST, 0));
				printf("Group       : %-30sSource RPM: %s\n", rpm_getstring(RPMTAG_GROUP, 0), rpm_getstring(RPMTAG_SOURCERPM, 0));
				printf("Size        : %-33dLicense: %s\n", rpm_getint(RPMTAG_SIZE, 0), rpm_getstring(RPMTAG_LICENSE, 0));
				printf("URL         : %s\n", rpm_getstring(RPMTAG_URL, 0));
				printf("Summary     : %s\n", rpm_getstring(RPMTAG_SUMMARY, 0));
				printf("Description :\n%s\n", rpm_getstring(RPMTAG_DESCRIPTION, 0));
			}
			if (func & rpm_query_list) {
				int count, it, flags;
				count = rpm_getcount(RPMTAG_BASENAMES);
				for (it = 0; it < count; it++) {
					flags = rpm_getint(RPMTAG_FILEFLAGS, it);
					switch ((func & rpm_query_list_doc) + (func & rpm_query_list_config))
					{
						case rpm_query_list_doc: if (!(flags & RPMFILE_DOC)) continue; break;
						case rpm_query_list_config: if (!(flags & RPMFILE_CONFIG)) continue; break;
						case rpm_query_list_doc + rpm_query_list_config: if (!((flags & RPMFILE_CONFIG) || (flags & RPMFILE_DOC))) continue; break;
					}
					printf("%s%s\n", rpm_getstring(RPMTAG_DIRNAMES, rpm_getint(RPMTAG_DIRINDEXES, it)), rpm_getstring(RPMTAG_BASENAMES, it));
				}
			}
		}
		optind++;
		free (mytags);
	}
	return 0;
}

void extract_cpio_gz(int fd) {
	archive_handle_t *archive_handle;
	unsigned char magic[2];

	/* Initialise */
	archive_handle = init_handle();
	archive_handle->seek = seek_by_char;
	//archive_handle->action_header = header_list;
	archive_handle->action_data = data_extract_all;
	archive_handle->flags |= ARCHIVE_PRESERVE_DATE;
	archive_handle->flags |= ARCHIVE_CREATE_LEADING_DIRS;
	archive_handle->src_fd = fd;
	archive_handle->offset = 0;

	bb_xread_all(archive_handle->src_fd, &magic, 2);
	if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) {
		bb_error_msg_and_die("Invalid gzip magic");
	}
	check_header_gzip(archive_handle->src_fd);
	chdir("/"); // Install RPM's to root

	archive_handle->src_fd = open_transformer(archive_handle->src_fd, inflate_gunzip);
	archive_handle->offset = 0;
	while (get_header_cpio(archive_handle) == EXIT_SUCCESS);
}


rpm_index **rpm_gettags(int fd, int *num_tags)
{
	rpm_index **tags = calloc(200, sizeof(struct rpmtag *)); /* We should never need mode than 200, and realloc later */
	int pass, tagindex = 0;
	lseek(fd, 96, SEEK_CUR); /* Seek past the unused lead */

	for (pass = 0; pass < 2; pass++) { /* 1st pass is the signature headers, 2nd is the main stuff */
		struct {
			char magic[3]; /* 3 byte magic: 0x8e 0xad 0xe8 */
			uint8_t version; /* 1 byte version number */
			uint32_t reserved; /* 4 bytes reserved */
			uint32_t entries; /* Number of entries in header (4 bytes) */
			uint32_t size; /* Size of store (4 bytes) */
		} header;
		rpm_index *tmpindex;
		int storepos;

		read(fd, &header, sizeof(header));
		if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC, 3) != 0) return NULL; /* Invalid magic */
		if (header.version != 1) return NULL; /* This program only supports v1 headers */
		header.size = ntohl(header.size);
		header.entries = ntohl(header.entries);
		storepos = lseek(fd,0,SEEK_CUR) + header.entries * 16;

		while (header.entries--) {
			tmpindex = tags[tagindex++] = xmalloc(sizeof(rpm_index));
			read(fd, tmpindex, sizeof(rpm_index));
			tmpindex->tag = ntohl(tmpindex->tag); tmpindex->type = ntohl(tmpindex->type); tmpindex->count = ntohl(tmpindex->count);
			tmpindex->offset = storepos + ntohl(tmpindex->offset);
			if (pass==0) tmpindex->tag -= 743;
		}
		lseek(fd, header.size, SEEK_CUR); /* Seek past store */
		if (pass==0) lseek(fd, (8 - (lseek(fd,0,SEEK_CUR) % 8)) % 8, SEEK_CUR); /* Skip padding to 8 byte boundary after reading signature headers */
	}
	tags = realloc(tags, tagindex * sizeof(struct rpmtag *)); /* realloc tags to save space */
	*num_tags = tagindex;
	return tags; /* All done, leave the file at the start of the gzipped cpio archive */
}

int bsearch_rpmtag(const void *key, const void *item)
{
	int *tag = (int *)key;
	rpm_index **tmp = (rpm_index **) item;
	return (*tag - tmp[0]->tag);
}

int rpm_getcount(int tag)
{
	rpm_index **found;
	found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
	if (!found) return 0;
	else return found[0]->count;
}

char *rpm_getstring(int tag, int itemindex)
{
	rpm_index **found;
	found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
	if (!found || itemindex >= found[0]->count) return NULL;
	if (found[0]->type == RPM_STRING_TYPE || found[0]->type == RPM_I18NSTRING_TYPE || found[0]->type == RPM_STRING_ARRAY_TYPE) {
		int n;
		char *tmpstr = (char *) (map + found[0]->offset);
		for (n=0; n < itemindex; n++) tmpstr = tmpstr + strlen(tmpstr) + 1;
		return tmpstr;
	} else return NULL;
}

int rpm_getint(int tag, int itemindex)
{
	rpm_index **found;
	int n, *tmpint;
	/* gcc throws warnings here when sizeof(void*)!=sizeof(int) ...
	 * it's ok to ignore it because tag won't be used as a pointer */
	found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
	if (!found || itemindex >= found[0]->count) return -1;
	tmpint = (int *) (map + found[0]->offset);
	if (found[0]->type == RPM_INT32_TYPE) {
		for (n=0; n<itemindex; n++) tmpint = (int *) ((void *) tmpint + 4);
		return ntohl(*tmpint);
	} else if (found[0]->type == RPM_INT16_TYPE) {
		for (n=0; n<itemindex; n++) tmpint = (int *) ((void *) tmpint + 2);
		return ntohs(*tmpint);
	} else if (found[0]->type == RPM_INT8_TYPE) {
		for (n=0; n<itemindex; n++) tmpint = (int *) ((void *) tmpint + 1);
		return ntohs(*tmpint);
	} else return -1;
}

void fileaction_dobackup(char *filename, int fileref)
{
	struct stat oldfile;
	int stat_res;
	char *newname;
	if (rpm_getint(RPMTAG_FILEFLAGS, fileref) & RPMFILE_CONFIG) { /* Only need to backup config files */
		stat_res = lstat (filename, &oldfile);
		if (stat_res == 0 && S_ISREG(oldfile.st_mode)) { /* File already exists  - really should check MD5's etc to see if different */
			newname = bb_xstrdup(filename);
			newname = strcat(newname, ".rpmorig");
			copy_file(filename, newname, FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS);
			remove_file(filename, FILEUTILS_RECUR | FILEUTILS_FORCE);
			free(newname);
		}
	}
}

void fileaction_setowngrp(char *filename, int fileref)
{
	int uid, gid;
	uid = bb_xgetpwnam(rpm_getstring(RPMTAG_FILEUSERNAME, fileref));
	gid = bb_xgetgrnam(rpm_getstring(RPMTAG_FILEGROUPNAME, fileref));
	chown (filename, uid, gid);
}

void fileaction_list(char *filename, int ATTRIBUTE_UNUSED fileref)
{
	printf("%s\n", filename);
}

void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref))
{
	int count = 0;
	char *filename, *tmp_dirname, *tmp_basename;
	while (rpm_getstring(filetag, count)) {
		tmp_dirname = rpm_getstring(RPMTAG_DIRNAMES, rpm_getint(RPMTAG_DIRINDEXES, count)); /* 1st put on the directory */
		tmp_basename = rpm_getstring(RPMTAG_BASENAMES, count);
		filename = xmalloc(strlen(tmp_basename) + strlen(tmp_dirname) + 1);
		strcpy(filename, tmp_dirname); /* First the directory name */
		strcat(filename, tmp_basename); /* then the filename */
		fileaction(filename, count++);
		free(filename);
	}
}
