/*
 * BSD/OSF partition parsing code
 *
 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 *
 * Inspired by fdisk, partx, Linux kernel, libparted and openbsd header files.
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include "partitions.h"
#include "pt-bsd.h"

/* Returns 'blkid_idmag' in 512-sectors */
#define BLKID_MAG_SECTOR(_mag)  (((_mag)->kboff / 2)  + ((_mag)->sboff >> 9))

/* Returns 'blkid_idmag' in bytes */
#define BLKID_MAG_OFFSET(_mag)  ((_mag)->kboff << 10) + ((_mag)->sboff)

/* Returns 'blkid_idmag' offset in bytes within the last sector */
#define BLKID_MAG_LASTOFFSET(_mag) \
		 (BLKID_MAG_OFFSET(_mag) - (BLKID_MAG_SECTOR(_mag) << 9))

static int probe_bsd_pt(blkid_probe pr, const struct blkid_idmag *mag)
{
	struct bsd_disklabel *l;
	struct bsd_partition *p;
	const char *name = "bsd" ;
	blkid_parttable tab = NULL;
	blkid_partition parent;
	blkid_partlist ls;
	int i, nparts = BSD_MAXPARTITIONS;
	unsigned char *data;
	int rc = BLKID_PROBE_NONE;

	if (blkid_partitions_need_typeonly(pr))
		/* caller does not ask for details about partitions */
		return rc;

	data = blkid_probe_get_sector(pr, BLKID_MAG_SECTOR(mag));
	if (!data) {
		if (errno)
			rc = -errno;
		goto nothing;
	}

	l = (struct bsd_disklabel *) data + BLKID_MAG_LASTOFFSET(mag);

	ls = blkid_probe_get_partlist(pr);
	if (!ls)
		goto nothing;

	/* try to determine the real type of BSD system according to
	 * (parental) primary partition */
	parent = blkid_partlist_get_parent(ls);
	if (parent) {
		switch(blkid_partition_get_type(parent)) {
		case MBR_FREEBSD_PARTITION:
			name = "freebsd";
			break;
		case MBR_NETBSD_PARTITION:
			name = "netbsd";
			break;
		case MBR_OPENBSD_PARTITION:
			name = "openbsd";
			break;
		default:
			DBG(LOWPROBE, ul_debug(
				"WARNING: BSD label detected on unknown (0x%x) "
				"primary partition",
				blkid_partition_get_type(parent)));
			break;
		}
	}

	tab = blkid_partlist_new_parttable(ls, name, BLKID_MAG_OFFSET(mag));
	if (!tab) {
		rc = -ENOMEM;
		goto nothing;
	}

	if (le16_to_cpu(l->d_npartitions) < BSD_MAXPARTITIONS)
		nparts = le16_to_cpu(l->d_npartitions);

	else if (le16_to_cpu(l->d_npartitions) > BSD_MAXPARTITIONS)
		DBG(LOWPROBE, ul_debug(
			"WARNING: ignore %d more BSD partitions",
			le16_to_cpu(l->d_npartitions) - BSD_MAXPARTITIONS));

	for (i = 0, p = l->d_partitions; i < nparts; i++, p++) {
		blkid_partition par;
		uint32_t start, size;

		/* TODO: in fdisk-mode returns all non-zero (p_size) partitions */
		if (p->p_fstype == BSD_FS_UNUSED)
			continue;

		start = le32_to_cpu(p->p_offset);
		size = le32_to_cpu(p->p_size);

		if (parent && blkid_partition_get_start(parent) == start
			   && blkid_partition_get_size(parent) == size) {
			DBG(LOWPROBE, ul_debug(
				"WARNING: BSD partition (%d) same like parent, "
				"ignore", i));
			continue;
		}
		if (parent && !blkid_is_nested_dimension(parent, start, size)) {
			DBG(LOWPROBE, ul_debug(
				"WARNING: BSD partition (%d) overflow "
				"detected, ignore", i));
			continue;
		}

		par = blkid_partlist_add_partition(ls, tab, start, size);
		if (!par) {
			rc = -ENOMEM;
			goto nothing;
		}

		blkid_partition_set_type(par, p->p_fstype);
	}

	return BLKID_PROBE_OK;

nothing:
	return rc;
}


/*
 * All BSD variants use the same magic string (little-endian),
 * and the same disklabel.
 *
 * The difference between {Free,Open,...}BSD is in the (parental)
 * primary partition type.
 *
 * See also: http://en.wikipedia.org/wiki/BSD_disklabel
 *
 * The location of BSD disk label is architecture specific and in defined by
 * LABELSECTOR and LABELOFFSET macros in the disklabel.h file. The location
 * also depends on BSD variant, FreeBSD uses only one location, NetBSD and
 * OpenBSD are more creative...
 *
 * The basic overview:
 *
 * arch                    | LABELSECTOR | LABELOFFSET
 * ------------------------+-------------+------------
 * amd64 arm hppa hppa64   |             |
 * i386, macppc, mvmeppc   |      1      |      0
 * sgi, aviion, sh, socppc |             |
 * ------------------------+-------------+------------
 * alpha luna88k mac68k    |      0      |     64
 * sparc(OpenBSD) vax      |             |
 * ------------------------+-------------+------------
 * sparc64 sparc(NetBSD)   |      0      |    128
 * ------------------------+-------------+------------
 *
 * ...and more (see http://fxr.watson.org/fxr/ident?v=NETBSD;i=LABELSECTOR)
 *
 */
const struct blkid_idinfo bsd_pt_idinfo =
{
	.name		= "bsd",
	.probefunc	= probe_bsd_pt,
	.magics		=
	{
		{ .magic = "\x57\x45\x56\x82", .len = 4, .sboff = 512 },
		{ .magic = "\x57\x45\x56\x82", .len = 4, .sboff = 64 },
		{ .magic = "\x57\x45\x56\x82", .len = 4, .sboff = 128 },
		{ NULL }
	}
};

