/* vi: set sw=4 ts=4: */
/*
 * Mini rpm applet for busybox
 *
 * Copyright (C) 2001,2002 by Laurence Anderson
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#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 {
	u_int32_t tag; /* 4 byte tag */
	u_int32_t type; /* 4 byte type */
	u_int32_t offset; /* 4 byte offset */
	u_int32_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_SHARED, 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 */
			u_int8_t version; /* 1 byte version number */
			u_int32_t reserved; /* 4 bytes reserved */
			u_int32_t entries; /* Number of entries in header (4 bytes) */
			u_int32_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++] = malloc(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)
{
	rpm_index **tmp = (rpm_index **) item;
	return ((int) key - tmp[0]->tag);
}

int rpm_getcount(int tag)
{
	rpm_index **found;
	found = bsearch((void *) 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((void *) 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;
	found = bsearch((void *) 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 = my_getpwnam(rpm_getstring(RPMTAG_FILEUSERNAME, fileref));
	gid = my_getgrnam(rpm_getstring(RPMTAG_FILEGROUPNAME, fileref));
	chown (filename, uid, gid);
}

void fileaction_list(char *filename, int 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);
	}
}
