/* vi: set sw=4 ts=4: */
/*
 * Mini ar implementation for busybox
 *
 * Copyright (C) 2000 by Glenn McGrath
 *
 * Based in part on BusyBox tar, Debian dpkg-deb and GNU ar.
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 *
 * Archive creation support:
 * Copyright (C) 2010 Nokia Corporation. All rights reserved.
 * Written by Alexander Shishkin.
 *
 * There is no single standard to adhere to so ar may not portable
 * between different systems
 * http://www.unix-systems.org/single_unix_specification_v2/xcu/ar.html
 */

//usage:#define ar_trivial_usage
//usage:       "[-o] [-v] [-p] [-t] [-x] ARCHIVE FILES"
//usage:#define ar_full_usage "\n\n"
//usage:       "Extract or list FILES from an ar archive\n"
//usage:     "\n	-o	Preserve original dates"
//usage:     "\n	-p	Extract to stdout"
//usage:     "\n	-t	List"
//usage:     "\n	-x	Extract"
//usage:     "\n	-v	Verbose"

#include "libbb.h"
#include "archive.h"
#include "ar.h"

#if ENABLE_FEATURE_AR_CREATE
/* filter out entries with same names as specified on the command line */
static char FAST_FUNC filter_replaceable(archive_handle_t *handle)
{
	if (find_list_entry(handle->accept, handle->file_header->name))
		return EXIT_FAILURE;

	return EXIT_SUCCESS;
}

static void output_ar_header(archive_handle_t *handle)
{
	/* GNU ar 2.19.51.0.14 creates malformed archives
	 * if input files are >10G. It also truncates files >4GB
	 * (uses "size mod 4G"). We abort in this case:
	 * We could add support for up to 10G files, but this is unlikely to be useful.
	 * Note that unpacking side limits all fields to "unsigned int" data type,
	 * and treats "all ones" as an error indicator. Thus max we allow here is UINT_MAX-1.
	 */
	enum {
		/* for 2nd field: mtime */
		MAX11CHARS = UINT_MAX > 0xffffffff ? (unsigned)99999999999 : UINT_MAX-1,
		/* for last field: filesize */
		MAX10CHARS = UINT_MAX > 0xffffffff ? (unsigned)9999999999 : UINT_MAX-1,
	};

	struct file_header_t *fh = handle->file_header;

	if (handle->offset & 1) {
		xwrite(handle->src_fd, "\n", 1);
		handle->offset++;
	}

	/* Careful! The widths should be exact. Fields must be separated */
	if (sizeof(off_t) > 4 && fh->size > (off_t)MAX10CHARS) {
		bb_error_msg_and_die("'%s' is bigger than ar can handle", fh->name);
	}
	fdprintf(handle->src_fd, "%-16.16s%-12lu%-6u%-6u%-8o%-10"OFF_FMT"u`\n",
			fh->name,
			(sizeof(time_t) > 4 && fh->mtime > MAX11CHARS) ? (long)0 : (long)fh->mtime,
			fh->uid > 99999 ? 0 : (int)fh->uid,
			fh->gid > 99999 ? 0 : (int)fh->gid,
			(int)fh->mode & 07777777,
			fh->size
	);

	handle->offset += AR_HEADER_LEN;
}

/*
 * when replacing files in an existing archive, copy from the
 * original archive those files that are to be left intact
 */
static void FAST_FUNC copy_data(archive_handle_t *handle)
{
	archive_handle_t *out_handle = handle->ar__out;
	struct file_header_t *fh = handle->file_header;

	out_handle->file_header = fh;
	output_ar_header(out_handle);

	bb_copyfd_exact_size(handle->src_fd, out_handle->src_fd, fh->size);
	out_handle->offset += fh->size;
}

static int write_ar_header(archive_handle_t *handle)
{
	char *fn;
	char fn_h[17]; /* 15 + "/" + NUL */
	struct stat st;
	int fd;

	fn = llist_pop(&handle->accept);
	if (!fn)
		return -1;

	xstat(fn, &st);

	handle->file_header->mtime = st.st_mtime;
	handle->file_header->uid = st.st_uid;
	handle->file_header->gid = st.st_gid;
	handle->file_header->mode = st.st_mode;
	handle->file_header->size = st.st_size;
	handle->file_header->name = fn_h;
//TODO: if ENABLE_FEATURE_AR_LONG_FILENAMES...
	sprintf(fn_h, "%.15s/", bb_basename(fn));

	output_ar_header(handle);

	fd = xopen(fn, O_RDONLY);
	bb_copyfd_exact_size(fd, handle->src_fd, st.st_size);
	close(fd);
	handle->offset += st.st_size;

	return 0;
}

static int write_ar_archive(archive_handle_t *handle)
{
	struct stat st;
	archive_handle_t *out_handle;

	xfstat(handle->src_fd, &st, handle->ar__name);

	/* if archive exists, create a new handle for output.
	 * we create it in place of the old one.
	 */
	if (st.st_size != 0) {
		out_handle = init_handle();
		xunlink(handle->ar__name);
		out_handle->src_fd = xopen(handle->ar__name, O_WRONLY | O_CREAT | O_TRUNC);
		out_handle->accept = handle->accept;
	} else {
		out_handle = handle;
	}

	handle->ar__out = out_handle;

	xwrite(out_handle->src_fd, AR_MAGIC "\n", AR_MAGIC_LEN + 1);
	out_handle->offset += AR_MAGIC_LEN + 1;

	/* skip to the end of the archive if we have to append stuff */
	if (st.st_size != 0) {
		handle->filter = filter_replaceable;
		handle->action_data = copy_data;
		unpack_ar_archive(handle);
	}

	while (write_ar_header(out_handle) == 0)
		continue;

	/* optional, since we exit right after we return */
	if (ENABLE_FEATURE_CLEAN_UP) {
		close(handle->src_fd);
		if (out_handle->src_fd != handle->src_fd)
			close(out_handle->src_fd);
	}

	return EXIT_SUCCESS;
}
#endif /* FEATURE_AR_CREATE */

static void FAST_FUNC header_verbose_list_ar(const file_header_t *file_header)
{
	const char *mode = bb_mode_string(file_header->mode);
	char *mtime;

	mtime = ctime(&file_header->mtime);
	mtime[16] = ' ';
	memmove(&mtime[17], &mtime[20], 4);
	mtime[21] = '\0';
	printf("%s %u/%u%7"OFF_FMT"u %s %s\n", &mode[1],
			(int)file_header->uid, (int)file_header->gid,
			file_header->size,
			&mtime[4], file_header->name
	);
}

#define AR_OPT_VERBOSE          (1 << 0)
#define AR_OPT_PRESERVE_DATE    (1 << 1)
/* "ar r" implies create, but warns about it. c suppresses warning.
 * bbox accepts but ignores it: */
#define AR_OPT_CREATE           (1 << 2)

#define AR_CMD_PRINT            (1 << 3)
#define FIRST_CMD               AR_CMD_PRINT
#define AR_CMD_LIST             (1 << 4)
#define AR_CMD_EXTRACT          (1 << 5)
#define AR_CMD_INSERT           (1 << 6)

int ar_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int ar_main(int argc UNUSED_PARAM, char **argv)
{
	archive_handle_t *archive_handle;
	unsigned opt, t;

	archive_handle = init_handle();

	/* --: prepend '-' to the first argument if required */
	/* -1: at least one param is reqd */
	/* one of p,t,x[,r] is required */
	opt_complementary = "--:-1:p:t:x"IF_FEATURE_AR_CREATE(":r");
	opt = getopt32(argv, "voc""ptx"IF_FEATURE_AR_CREATE("r"));
	argv += optind;

	t = opt / FIRST_CMD;
	if (t & (t-1)) /* more than one of p,t,x[,r] are specified */
		bb_show_usage();

	if (opt & AR_CMD_PRINT) {
		archive_handle->action_data = data_extract_to_stdout;
	}
	if (opt & AR_CMD_LIST) {
		archive_handle->action_header = header_list;
	}
	if (opt & AR_CMD_EXTRACT) {
		archive_handle->action_data = data_extract_all;
	}
	if (opt & AR_OPT_PRESERVE_DATE) {
		archive_handle->ah_flags |= ARCHIVE_RESTORE_DATE;
	}
	if (opt & AR_OPT_VERBOSE) {
		archive_handle->action_header = header_verbose_list_ar;
	}
#if ENABLE_FEATURE_AR_CREATE
	archive_handle->ar__name = *argv;
#endif
	archive_handle->src_fd = xopen(*argv++,
			(opt & AR_CMD_INSERT)
				? O_RDWR | O_CREAT
				: O_RDONLY
	);

	if (*argv)
		archive_handle->filter = filter_accept_list;
	while (*argv) {
		llist_add_to_end(&archive_handle->accept, *argv++);
	}

#if ENABLE_FEATURE_AR_CREATE
	if (opt & AR_CMD_INSERT)
		return write_ar_archive(archive_handle);
#endif

	unpack_ar_archive(archive_handle);

	return EXIT_SUCCESS;
}
