/* vi: set sw=4 ts=4: */
/*
 * Mini ar implementation for busybox 
 *
 * Copyright (C) 2000 by Glenn McGrath
 * Written by Glenn McGrath <bug1@optushome.com.au> 1 June 2000
 * 		
 * Based in part on BusyBox tar, Debian dpkg-deb and GNU ar.
 *
 * 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 <fcntl.h>
#include <stdlib.h>
#include <getopt.h>
#include <unistd.h>
#include "busybox.h"

extern int ar_main(int argc, char **argv)
{
	const int preserve_date = 1;	/* preserve original dates */
	const int verbose = 2;		/* be verbose */
	const int display = 4;		/* display contents */
	const int extract_to_file = 8;	/* extract contents of archive */
	const int extract_to_stdout = 16;	/* extract to stdout */

	FILE *src_file = NULL, *dst_file = NULL;
	int funct = 0, opt=0;

	ar_headers_t *head, *ar_extract_list=NULL;

	ar_extract_list = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t));
	head = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t));

	while ((opt = getopt(argc, argv, "ovtpx")) != -1) {
		switch (opt) {
		case 'o':
			funct |= preserve_date;
			break;
		case 'v':
			funct |= verbose;
			break;
		case 't':
			funct |= display;
			break;
		case 'p':
			funct |= extract_to_stdout;
			break;
		case 'x':
			funct |= extract_to_file;
			break;
		default:
			show_usage();
		}
	}
 
	/* check the src filename was specified */
	if (optind == argc) {
		show_usage();
	}

	if ( (src_file = wfopen(argv[optind], "r")) < 0) {
		error_msg_and_die("Cannot read %s", argv[optind]);
	}

	optind++;	
	head = get_ar_headers(src_file);
	/* find files to extract or display */
	/* search through argv and build extract list */
	for (;optind < argc; optind++) {
		ar_headers_t *ar_entry;
		ar_entry = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t));
		ar_entry = head;
		while (ar_entry->next != NULL) {
			if (strcmp(argv[optind], ar_entry->name) == 0) {
				ar_headers_t *tmp;
				tmp = (ar_headers_t *) xmalloc(sizeof(ar_headers_t));
				*tmp = *ar_extract_list;
				*ar_extract_list = *ar_entry;
				ar_extract_list->next = tmp;
				break;					
			}
			ar_entry=ar_entry->next;
		}
	}

	/* if individual files not found extract all files */	
	if (ar_extract_list->next==NULL) {
		ar_extract_list = head;
	}

	/* find files to extract or display */	
	while (ar_extract_list->next != NULL) {
		if (funct & extract_to_file) {
			dst_file = wfopen(ar_extract_list->name, "w");				
		}
		else if (funct & extract_to_stdout) {
			dst_file = stdout;
		}
		if ((funct & extract_to_file) || (funct & extract_to_stdout)) {
			fseek(src_file, ar_extract_list->offset, SEEK_SET);
			copy_file_chunk(src_file, dst_file, ar_extract_list->size);			
		}
		if (funct & verbose) {
			printf("%s %d/%d %8d %s ", mode_string(ar_extract_list->mode), 
				ar_extract_list->uid, ar_extract_list->gid,
				(int) ar_extract_list->size, time_string(ar_extract_list->mtime));
		}
		if ((funct & display) || (funct & verbose)){
			printf("%s\n", ar_extract_list->name);
		}
		ar_extract_list = ar_extract_list->next;
	}
	return EXIT_SUCCESS;
}
