/*
 *  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 Library 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 <stdlib.h>
#include <string.h>
#include "unarchive.h"
#include "libbb.h"

extern char get_header_tar(archive_handle_t *archive_handle)
{
	file_header_t *file_header = archive_handle->file_header;
	union {
		unsigned char raw[512];
		struct {
			char name[100];	/*   0-99 */
			char mode[8];	/* 100-107 */
			char uid[8];	/* 108-115 */
			char gid[8];	/* 116-123 */
			char size[12];	/* 124-135 */
			char mtime[12];	/* 136-147 */
			char chksum[8];	/* 148-155 */
			char typeflag;	/* 156-156 */
			char linkname[100];	/* 157-256 */
			char magic[6];	/* 257-262 */
			char version[2];	/* 263-264 */
			char uname[32];	/* 265-296 */
			char gname[32];	/* 297-328 */
			char devmajor[8];	/* 329-336 */
			char devminor[8];	/* 337-344 */
			char prefix[155];	/* 345-499 */
			char padding[12];	/* 500-512 */
		} formated;
	} tar;
	long sum = 0;
	long i;
	char *tmp;

	/* Align header */
	archive_handle->offset += data_align(archive_handle->src_fd, archive_handle->offset, 512);

	if (xread_all_eof(archive_handle->src_fd, tar.raw, 512) == 0) {
		/* End of file */
		return(EXIT_FAILURE);
	}
	archive_handle->offset += 512;

	/* If there is no filename its an empty header */
	if (tar.formated.name[0] == 0) {
		return(EXIT_SUCCESS);
	}

	/* Check header has valid magic, "ustar" is for the proper tar
	 * 0's are for the old tar format
	 */
	if (strncmp(tar.formated.magic, "ustar", 5) != 0) {
#ifdef CONFIG_FEATURE_TAR_OLD_FORMAT
		if (strncmp(tar.formated.magic, "\0\0\0\0\0", 5) != 0)
#endif
			error_msg_and_die("Invalid tar magic");
	}

	/* Do checksum on headers */
	for (i =  0; i < 148 ; i++) {
		sum += tar.raw[i];
	}
	sum += ' ' * 8;
	for (i =  156; i < 512 ; i++) {
		sum += tar.raw[i];
	}
	if (sum != strtol(tar.formated.chksum, NULL, 8)) {
		error_msg("Invalid tar header checksum");
		return(EXIT_FAILURE);
	}

	/* convert to type'ed variables */
	if (tar.formated.prefix[0] == 0) {
		file_header->name = strdup(tar.formated.name);
	} else {
		file_header->name = concat_path_file(tar.formated.prefix, tar.formated.name);
	}
	tmp = last_char_is(archive_handle->file_header->name, '/');
	if (tmp) {
		*tmp = '\0';
	}

	file_header->mode = strtol(tar.formated.mode, NULL, 8);
	file_header->uid = strtol(tar.formated.uid, NULL, 8);
	file_header->gid = strtol(tar.formated.gid, NULL, 8);
	file_header->size = strtol(tar.formated.size, NULL, 8);
	file_header->mtime = strtol(tar.formated.mtime, NULL, 8);
	file_header->link_name = (tar.formated.linkname[0] != '\0') ? 
	    xstrdup(tar.formated.linkname) : NULL;
	file_header->device = (dev_t) ((strtol(tar.formated.devmajor, NULL, 8) << 8) +
				 strtol(tar.formated.devminor, NULL, 8));

#if defined CONFIG_FEATURE_TAR_OLD_FORMAT || defined CONFIG_FEATURE_GNUTAR_LONG_FILENAME
	/* Fix mode, used by the old format */
	switch (tar.formated.typeflag) {
# ifdef CONFIG_FEATURE_TAR_OLD_FORMAT
	case 0:
		file_header->mode |= S_IFREG;
		break;
	case 1:
		error_msg("Internal hard link not supported");
		break;
	case 2:
		file_header->mode |= S_IFLNK;
		break;
	case 3:
		file_header->mode |= S_IFCHR;
		break;
	case 4:
		file_header->mode |= S_IFBLK;
		break;
	case 5:
		file_header->mode |= S_IFDIR;
		break;
	case 6:
		file_header->mode |= S_IFIFO;
		break;
# endif
# ifdef CONFIG_FEATURE_GNUTAR_LONG_FILENAME
	case 'L': {
			char *longname;

			longname = xmalloc(file_header->size + 1);
			xread_all(archive_handle->src_fd, longname, file_header->size);
			longname[file_header->size] = '\0';
			archive_handle->offset += file_header->size;

			get_header_tar(archive_handle);
			file_header->name = longname;
			break;
		}
	case 'K': {
			char *linkname;

			linkname = xmalloc(file_header->size + 1);
			xread_all(archive_handle->src_fd, linkname, file_header->size);
			linkname[file_header->size] = '\0';
			archive_handle->offset += file_header->size;

			get_header_tar(archive_handle);
			file_header->name = linkname;
			break;
		}
# endif
	}
#endif
	if (archive_handle->filter(archive_handle->accept, archive_handle->reject, archive_handle->file_header->name) == EXIT_SUCCESS) {
		archive_handle->action_header(archive_handle->file_header);
		archive_handle->flags |= ARCHIVE_EXTRACT_QUIET;
		archive_handle->action_data(archive_handle);
		archive_handle->passed = add_to_list(archive_handle->passed, archive_handle->file_header->name);
	} else {
		data_skip(archive_handle);			
	}
	archive_handle->offset += file_header->size;

	return(EXIT_SUCCESS);
}

