/*
 *  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"

file_header_t *get_header_tar(FILE * tar_stream)
{
	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;
	file_header_t *tar_entry = NULL;
	long sum = 0;
	long i;

	if (archive_offset % 512 != 0) {
		seek_sub_file(tar_stream, 512 - (archive_offset % 512));
	}

	if (fread(tar.raw, 1, 512, tar_stream) != 512) {
		/* Unfortunatly its common for tar files to have all sorts of
		 * trailing garbage, fail silently */
		return (NULL);
	}
	archive_offset += 512;

	/* 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
			return (NULL);
	}

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

	/* 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 (NULL);
	}

	/* convert to type'ed variables */
	tar_entry = xcalloc(1, sizeof(file_header_t));
	if (tar.formated.prefix[0] == 0) {
		tar_entry->name = xstrdup(tar.formated.name);
	} else {
		tar_entry->name =
			concat_path_file(tar.formated.prefix, tar.formated.name);
	}

	tar_entry->mode = strtol(tar.formated.mode, NULL, 8);
	tar_entry->uid = strtol(tar.formated.uid, NULL, 8);
	tar_entry->gid = strtol(tar.formated.gid, NULL, 8);
	tar_entry->size = strtol(tar.formated.size, NULL, 8);
	tar_entry->mtime = strtol(tar.formated.mtime, NULL, 8);
	tar_entry->link_name =
		strlen(tar.formated.linkname) ? xstrdup(tar.formated.linkname) : NULL;
	tar_entry->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
	switch (tar.formated.typeflag) {
# ifdef CONFIG_FEATURE_TAR_OLD_FORMAT
	case 0:
		tar_entry->mode |= S_IFREG;
		break;
	case 1:
		error_msg("internal hard link not handled\n");
		break;
	case 2:
		tar_entry->mode |= S_IFLNK;
		break;
	case 3:
		tar_entry->mode |= S_IFCHR;
		break;
	case 4:
		tar_entry->mode |= S_IFBLK;
		break;
	case 5:
		tar_entry->mode |= S_IFDIR;
		break;
	case 6:
		tar_entry->mode |= S_IFIFO;
		break;
# endif
# ifdef CONFIG_FEATURE_GNUTAR_LONG_FILENAME
	case 'L': {
			char *longname;

			longname = xmalloc(tar_entry->size + 1);
			fread(longname, 1, tar_entry->size, tar_stream);
			archive_offset += tar_entry->size;
			longname[tar_entry->size] = '\0';

			tar_entry = get_header_tar(tar_stream);
			tar_entry->name = longname;
			break;
		}
	case 'K': {
			char *longname;

			longname = xmalloc(tar_entry->size + 1);
			fread(longname, 1, tar_entry->size, tar_stream);
			archive_offset += tar_entry->size;
			longname[tar_entry->size] = '\0';

			tar_entry = get_header_tar(tar_stream);
			tar_entry->link_name = longname;
			break;
		}
# endif
	}
#endif

	return (tar_entry);
}
