/*
 *  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 <unistd.h>
#include <sys/sysmacros.h>     /* major() and minor() */
#include "unarchive.h"
#include "libbb.h"

typedef struct hardlinks_s {
	file_header_t *entry;
	int inode;
	struct hardlinks_s *next;
} hardlinks_t;

char get_header_cpio(archive_handle_t *archive_handle)
{
	static hardlinks_t *saved_hardlinks = NULL;
	static unsigned short pending_hardlinks = 0;
	file_header_t *file_header = archive_handle->file_header;
	char cpio_header[110];
	int namesize;
	char dummy[16];
	int major, minor, nlink, inode;

	if (pending_hardlinks) { /* Deal with any pending hardlinks */
		hardlinks_t *tmp;
		hardlinks_t *oldtmp;

		tmp = saved_hardlinks;
		oldtmp = NULL;

		while (tmp) {
			bb_error_msg_and_die("need to fix this\n");
			if (tmp->entry->link_name) { /* Found a hardlink ready to be extracted */
				file_header = tmp->entry;
				if (oldtmp) {
					oldtmp->next = tmp->next; /* Remove item from linked list */
				} else {
					saved_hardlinks = tmp->next;
				}
				free(tmp);
				continue;
			}
			oldtmp = tmp;
			tmp = tmp->next;
		}
		pending_hardlinks = 0; /* No more pending hardlinks, read next file entry */
	}

	/* There can be padding before archive header */
	data_align(archive_handle, 4);

	if (archive_xread_all_eof(archive_handle, (unsigned char*)cpio_header, 110) == 0) {
		return(EXIT_FAILURE);
	}
	archive_handle->offset += 110;

	if ((strncmp(&cpio_header[0], "07070", 5) != 0) || ((cpio_header[5] != '1') && (cpio_header[5] != '2'))) {
		bb_error_msg_and_die("Unsupported cpio format, use newc or crc");
	}

	{
	    unsigned long tmpsize;
	    sscanf(cpio_header, "%6c%8x%8x%8x%8x%8x%8lx%8lx%16c%8x%8x%8x%8c",
		    dummy, &inode, (unsigned int*)&file_header->mode,
		    (unsigned int*)&file_header->uid, (unsigned int*)&file_header->gid,
		    &nlink, &file_header->mtime, &tmpsize,
		    dummy, &major, &minor, &namesize, dummy);
	    file_header->size = tmpsize;
	}

	file_header->name = (char *) xmalloc(namesize + 1);
	archive_xread_all(archive_handle, file_header->name, namesize); /* Read in filename */
	file_header->name[namesize] = '\0';
	archive_handle->offset += namesize;

	/* Update offset amount and skip padding before file contents */
	data_align(archive_handle, 4);

	if (strcmp(file_header->name, "TRAILER!!!") == 0) {
		printf("%d blocks\n", (int) (archive_handle->offset % 512 ? (archive_handle->offset / 512) + 1 : archive_handle->offset / 512)); /* Always round up */
		if (saved_hardlinks) { /* Bummer - we still have unresolved hardlinks */
			hardlinks_t *tmp = saved_hardlinks;
			hardlinks_t *oldtmp = NULL;
			while (tmp) {
				bb_error_msg("%s not created: cannot resolve hardlink", tmp->entry->name);
				oldtmp = tmp;
				tmp = tmp->next;
				free (oldtmp->entry->name);
				free (oldtmp->entry);
				free (oldtmp);
			}
			saved_hardlinks = NULL;
			pending_hardlinks = 0;
		}
		return(EXIT_FAILURE);
	}

	if (S_ISLNK(file_header->mode)) {
		file_header->link_name = (char *) xmalloc(file_header->size + 1);
		archive_xread_all(archive_handle, file_header->link_name, file_header->size);
		file_header->link_name[file_header->size] = '\0';
		archive_handle->offset += file_header->size;
		file_header->size = 0; /* Stop possible seeks in future */
	} else {
		file_header->link_name = NULL;
	}
	if (nlink > 1 && !S_ISDIR(file_header->mode)) {
		if (file_header->size == 0) { /* Put file on a linked list for later */
			hardlinks_t *new = xmalloc(sizeof(hardlinks_t));
			new->next = saved_hardlinks;
			new->inode = inode;
			new->entry = file_header;
			saved_hardlinks = new;
			return(EXIT_SUCCESS); // Skip this one
		} else { /* Found the file with data in */
			hardlinks_t *tmp = saved_hardlinks;
			pending_hardlinks = 1;
			while (tmp) {
				if (tmp->inode == inode) {
					tmp->entry->link_name = bb_xstrdup(file_header->name);
					nlink--;
				}
				tmp = tmp->next;
			}
			if (nlink > 1) {
				bb_error_msg("error resolving hardlink: did you create the archive with GNU cpio 2.0-2.2?");
			}
		}
	}
	file_header->device = makedev(major, minor);

	if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) {
		archive_handle->action_data(archive_handle);
		archive_handle->action_header(archive_handle->file_header);
	} else {
		data_skip(archive_handle);
	}

	archive_handle->offset += file_header->size;

	free(file_header->link_name);

	return (EXIT_SUCCESS);
}
