/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_link_resolver.c 201100 2009-12-28 03:05:31Z kientzle $");

#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif

#include "archive.h"
#include "archive_entry.h"

/*
 * This is mostly a pretty straightforward hash table implementation.
 * The only interesting bit is the different strategies used to
 * match up links.  These strategies match those used by various
 * archiving formats:
 *   tar - content stored with first link, remainder refer back to it.
 *       This requires us to match each subsequent link up with the
 *       first appearance.
 *   cpio - Old cpio just stored body with each link, match-ups were
 *       implicit.  This is trivial.
 *   new cpio - New cpio only stores body with last link, match-ups
 *       are implicit.  This is actually quite tricky; see the notes
 *       below.
 */

/* Users pass us a format code, we translate that into a strategy here. */
#define ARCHIVE_ENTRY_LINKIFY_LIKE_TAR	0
#define ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE 1
#define ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO 2
#define ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO 3

/* Initial size of link cache. */
#define	links_cache_initial_size 1024

struct links_entry {
	struct links_entry	*next;
	struct links_entry	*previous;
	struct archive_entry	*canonical;
	struct archive_entry	*entry;
	size_t			 hash;
	unsigned int		 links; /* # links not yet seen */
};

struct archive_entry_linkresolver {
	struct links_entry	**buckets;
	struct links_entry	 *spare;
	unsigned long		  number_entries;
	size_t			  number_buckets;
	int			  strategy;
};

#define	NEXT_ENTRY_DEFERRED	1
#define	NEXT_ENTRY_PARTIAL	2
#define	NEXT_ENTRY_ALL		(NEXT_ENTRY_DEFERRED | NEXT_ENTRY_PARTIAL)

static struct links_entry *find_entry(struct archive_entry_linkresolver *,
		    struct archive_entry *);
static void grow_hash(struct archive_entry_linkresolver *);
static struct links_entry *insert_entry(struct archive_entry_linkresolver *,
		    struct archive_entry *);
static struct links_entry *next_entry(struct archive_entry_linkresolver *,
    int);

struct archive_entry_linkresolver *
archive_entry_linkresolver_new(void)
{
	struct archive_entry_linkresolver *res;

	/* Check for positive power-of-two */
	if (links_cache_initial_size == 0 ||
	    (links_cache_initial_size & (links_cache_initial_size - 1)) != 0)
		return (NULL);

	res = calloc(1, sizeof(struct archive_entry_linkresolver));
	if (res == NULL)
		return (NULL);
	res->number_buckets = links_cache_initial_size;
	res->buckets = calloc(res->number_buckets, sizeof(res->buckets[0]));
	if (res->buckets == NULL) {
		free(res);
		return (NULL);
	}
	return (res);
}

void
archive_entry_linkresolver_set_strategy(struct archive_entry_linkresolver *res,
    int fmt)
{
	int fmtbase = fmt & ARCHIVE_FORMAT_BASE_MASK;

	switch (fmtbase) {
	case ARCHIVE_FORMAT_7ZIP:
	case ARCHIVE_FORMAT_AR:
	case ARCHIVE_FORMAT_ZIP:
		res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
		break;
	case ARCHIVE_FORMAT_CPIO:
		switch (fmt) {
		case ARCHIVE_FORMAT_CPIO_SVR4_NOCRC:
		case ARCHIVE_FORMAT_CPIO_SVR4_CRC:
			res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO;
			break;
		default:
			res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
			break;
		}
		break;
	case ARCHIVE_FORMAT_MTREE:
		res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE;
		break;
	case ARCHIVE_FORMAT_ISO9660:
	case ARCHIVE_FORMAT_SHAR:
	case ARCHIVE_FORMAT_TAR:
	case ARCHIVE_FORMAT_XAR:
		res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_TAR;
		break;
	default:
		res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
		break;
	}
}

void
archive_entry_linkresolver_free(struct archive_entry_linkresolver *res)
{
	struct links_entry *le;

	if (res == NULL)
		return;

	while ((le = next_entry(res, NEXT_ENTRY_ALL)) != NULL)
		archive_entry_free(le->entry);
	free(res->buckets);
	free(res);
}

void
archive_entry_linkify(struct archive_entry_linkresolver *res,
    struct archive_entry **e, struct archive_entry **f)
{
	struct links_entry *le;
	struct archive_entry *t;

	*f = NULL; /* Default: Don't return a second entry. */

	if (*e == NULL) {
		le = next_entry(res, NEXT_ENTRY_DEFERRED);
		if (le != NULL) {
			*e = le->entry;
			le->entry = NULL;
		}
		return;
	}

	/* If it has only one link, then we're done. */
	if (archive_entry_nlink(*e) == 1)
		return;
	/* Directories, devices never have hardlinks. */
	if (archive_entry_filetype(*e) == AE_IFDIR
	    || archive_entry_filetype(*e) == AE_IFBLK
	    || archive_entry_filetype(*e) == AE_IFCHR)
		return;

	switch (res->strategy) {
	case ARCHIVE_ENTRY_LINKIFY_LIKE_TAR:
		le = find_entry(res, *e);
		if (le != NULL) {
			archive_entry_unset_size(*e);
			archive_entry_copy_hardlink(*e,
			    archive_entry_pathname(le->canonical));
		} else
			insert_entry(res, *e);
		return;
	case ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE:
		le = find_entry(res, *e);
		if (le != NULL) {
			archive_entry_copy_hardlink(*e,
			    archive_entry_pathname(le->canonical));
		} else
			insert_entry(res, *e);
		return;
	case ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO:
		/* This one is trivial. */
		return;
	case ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO:
		le = find_entry(res, *e);
		if (le != NULL) {
			/*
			 * Put the new entry in le, return the
			 * old entry from le.
			 */
			t = *e;
			*e = le->entry;
			le->entry = t;
			/* Make the old entry into a hardlink. */
			archive_entry_unset_size(*e);
			archive_entry_copy_hardlink(*e,
			    archive_entry_pathname(le->canonical));
			/* If we ran out of links, return the
			 * final entry as well. */
			if (le->links == 0) {
				*f = le->entry;
				le->entry = NULL;
			}
		} else {
			/*
			 * If we haven't seen it, tuck it away
			 * for future use.
			 */
			le = insert_entry(res, *e);
			if (le == NULL)
				/* XXX We should return an error code XXX */
				return;
			le->entry = *e;
			*e = NULL;
		}
		return;
	default:
		break;
	}
	return;
}

static struct links_entry *
find_entry(struct archive_entry_linkresolver *res,
    struct archive_entry *entry)
{
	struct links_entry	*le;
	size_t			 hash, bucket;
	dev_t			 dev;
	int64_t			 ino;

	/* Free a held entry. */
	if (res->spare != NULL) {
		archive_entry_free(res->spare->canonical);
		archive_entry_free(res->spare->entry);
		free(res->spare);
		res->spare = NULL;
	}

	dev = archive_entry_dev(entry);
	ino = archive_entry_ino64(entry);
	hash = (size_t)(dev ^ ino);

	/* Try to locate this entry in the links cache. */
	bucket = hash & (res->number_buckets - 1);
	for (le = res->buckets[bucket]; le != NULL; le = le->next) {
		if (le->hash == hash
		    && dev == archive_entry_dev(le->canonical)
		    && ino == archive_entry_ino64(le->canonical)) {
			/*
			 * Decrement link count each time and release
			 * the entry if it hits zero.  This saves
			 * memory and is necessary for detecting
			 * missed links.
			 */
			--le->links;
			if (le->links > 0)
				return (le);
			/* Remove it from this hash bucket. */
			if (le->previous != NULL)
				le->previous->next = le->next;
			if (le->next != NULL)
				le->next->previous = le->previous;
			if (res->buckets[bucket] == le)
				res->buckets[bucket] = le->next;
			res->number_entries--;
			/* Defer freeing this entry. */
			res->spare = le;
			return (le);
		}
	}
	return (NULL);
}

static struct links_entry *
next_entry(struct archive_entry_linkresolver *res, int mode)
{
	struct links_entry	*le;
	size_t			 bucket;

	/* Free a held entry. */
	if (res->spare != NULL) {
		archive_entry_free(res->spare->canonical);
		archive_entry_free(res->spare->entry);
		free(res->spare);
		res->spare = NULL;
	}

	/* Look for next non-empty bucket in the links cache. */
	for (bucket = 0; bucket < res->number_buckets; bucket++) {
		for (le = res->buckets[bucket]; le != NULL; le = le->next) {
			if (le->entry != NULL &&
			    (mode & NEXT_ENTRY_DEFERRED) == 0)
				continue;
			if (le->entry == NULL &&
			    (mode & NEXT_ENTRY_PARTIAL) == 0)
				continue;
			/* Remove it from this hash bucket. */
			if (le->next != NULL)
				le->next->previous = le->previous;
			if (le->previous != NULL)
				le->previous->next = le->next;
			else
				res->buckets[bucket] = le->next;
			res->number_entries--;
			/* Defer freeing this entry. */
			res->spare = le;
			return (le);
		}
	}
	return (NULL);
}

static struct links_entry *
insert_entry(struct archive_entry_linkresolver *res,
    struct archive_entry *entry)
{
	struct links_entry *le;
	size_t hash, bucket;

	/* Add this entry to the links cache. */
	le = calloc(1, sizeof(struct links_entry));
	if (le == NULL)
		return (NULL);
	le->canonical = archive_entry_clone(entry);

	/* If the links cache is getting too full, enlarge the hash table. */
	if (res->number_entries > res->number_buckets * 2)
		grow_hash(res);

	hash = (size_t)(archive_entry_dev(entry) ^ archive_entry_ino64(entry));
	bucket = hash & (res->number_buckets - 1);

	/* If we could allocate the entry, record it. */
	if (res->buckets[bucket] != NULL)
		res->buckets[bucket]->previous = le;
	res->number_entries++;
	le->next = res->buckets[bucket];
	le->previous = NULL;
	res->buckets[bucket] = le;
	le->hash = hash;
	le->links = archive_entry_nlink(entry) - 1;
	return (le);
}

static void
grow_hash(struct archive_entry_linkresolver *res)
{
	struct links_entry *le, **new_buckets;
	size_t new_size;
	size_t i, bucket;

	/* Try to enlarge the bucket list. */
	new_size = res->number_buckets * 2;
	if (new_size < res->number_buckets)
		return;
	new_buckets = calloc(new_size, sizeof(struct links_entry *));

	if (new_buckets == NULL)
		return;

	for (i = 0; i < res->number_buckets; i++) {
		while (res->buckets[i] != NULL) {
			/* Remove entry from old bucket. */
			le = res->buckets[i];
			res->buckets[i] = le->next;

			/* Add entry to new bucket. */
			bucket = le->hash & (new_size - 1);

			if (new_buckets[bucket] != NULL)
				new_buckets[bucket]->previous = le;
			le->next = new_buckets[bucket];
			le->previous = NULL;
			new_buckets[bucket] = le;
		}
	}
	free(res->buckets);
	res->buckets = new_buckets;
	res->number_buckets = new_size;
}

struct archive_entry *
archive_entry_partial_links(struct archive_entry_linkresolver *res,
    unsigned int *links)
{
	struct archive_entry	*e;
	struct links_entry	*le;

	/* Free a held entry. */
	if (res->spare != NULL) {
		archive_entry_free(res->spare->canonical);
		archive_entry_free(res->spare->entry);
		free(res->spare);
		res->spare = NULL;
	}

	le = next_entry(res, NEXT_ENTRY_PARTIAL);
	if (le != NULL) {
		e = le->canonical;
		if (links != NULL)
			*links = le->links;
		le->canonical = NULL;
	} else {
		e = NULL;
		if (links != NULL)
			*links = 0;
	}
	return (e);
}
