/*
 * volume_id - reads filesystem label and uuid
 *
 * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library 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
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include "volume_id_internal.h"


/* Some detection routines do not set label or uuid anyway,
 * so they are disabled. */

/* Looks for partitions, we don't use it: */
#define ENABLE_FEATURE_VOLUMEID_MAC           0
/* #define ENABLE_FEATURE_VOLUMEID_MSDOS      0 - NB: this one
 * was not properly added to probe table anyway - ??! */

/* None of RAIDs have label or uuid, except LinuxRAID: */
#define ENABLE_FEATURE_VOLUMEID_HIGHPOINTRAID 0
#define ENABLE_FEATURE_VOLUMEID_ISWRAID       0
#define ENABLE_FEATURE_VOLUMEID_LSIRAID       0
#define ENABLE_FEATURE_VOLUMEID_LVM           0
#define ENABLE_FEATURE_VOLUMEID_NVIDIARAID    0
#define ENABLE_FEATURE_VOLUMEID_PROMISERAID   0
#define ENABLE_FEATURE_VOLUMEID_SILICONRAID   0
#define ENABLE_FEATURE_VOLUMEID_VIARAID       0

/* These filesystems also have no label or uuid: */
#define ENABLE_FEATURE_VOLUMEID_MINIX         0
#define ENABLE_FEATURE_VOLUMEID_HPFS          0
#define ENABLE_FEATURE_VOLUMEID_UFS           0


typedef int FAST_FUNC (*raid_probe_fptr)(struct volume_id *id, /*uint64_t off,*/ uint64_t size);
typedef int FAST_FUNC (*probe_fptr)(struct volume_id *id /*, uint64_t off*/);

static const raid_probe_fptr raid1[] = {
#if ENABLE_FEATURE_VOLUMEID_LINUXRAID
	volume_id_probe_linux_raid,
#endif
#if ENABLE_FEATURE_VOLUMEID_ISWRAID
	volume_id_probe_intel_software_raid,
#endif
#if ENABLE_FEATURE_VOLUMEID_LSIRAID
	volume_id_probe_lsi_mega_raid,
#endif
#if ENABLE_FEATURE_VOLUMEID_VIARAID
	volume_id_probe_via_raid,
#endif
#if ENABLE_FEATURE_VOLUMEID_SILICONRAID
	volume_id_probe_silicon_medley_raid,
#endif
#if ENABLE_FEATURE_VOLUMEID_NVIDIARAID
	volume_id_probe_nvidia_raid,
#endif
#if ENABLE_FEATURE_VOLUMEID_PROMISERAID
	volume_id_probe_promise_fasttrack_raid,
#endif
#if ENABLE_FEATURE_VOLUMEID_HIGHPOINTRAID
	volume_id_probe_highpoint_45x_raid,
#endif
};

static const probe_fptr raid2[] = {
#if ENABLE_FEATURE_VOLUMEID_LVM
	volume_id_probe_lvm1,
	volume_id_probe_lvm2,
#endif
#if ENABLE_FEATURE_VOLUMEID_HIGHPOINTRAID
	volume_id_probe_highpoint_37x_raid,
#endif
#if ENABLE_FEATURE_VOLUMEID_LUKS
	volume_id_probe_luks,
#endif
};

/* signature in the first block, only small buffer needed */
static const probe_fptr fs1[] = {
#if ENABLE_FEATURE_VOLUMEID_FAT
	volume_id_probe_vfat,
#endif
#if ENABLE_FEATURE_VOLUMEID_MAC
	volume_id_probe_mac_partition_map,
#endif
#if ENABLE_FEATURE_VOLUMEID_XFS
	volume_id_probe_xfs,
#endif
};

/* fill buffer with maximum */
static const probe_fptr fs2[] = {
#if ENABLE_FEATURE_VOLUMEID_LINUXSWAP
	volume_id_probe_linux_swap,
#endif
#if ENABLE_FEATURE_VOLUMEID_EXT
	volume_id_probe_ext,
#endif
#if ENABLE_FEATURE_VOLUMEID_BTRFS
	volume_id_probe_btrfs,
#endif
#if ENABLE_FEATURE_VOLUMEID_REISERFS
	volume_id_probe_reiserfs,
#endif
#if ENABLE_FEATURE_VOLUMEID_JFS
	volume_id_probe_jfs,
#endif
#if ENABLE_FEATURE_VOLUMEID_UDF
	volume_id_probe_udf,
#endif
#if ENABLE_FEATURE_VOLUMEID_ISO9660
	volume_id_probe_iso9660,
#endif
#if ENABLE_FEATURE_VOLUMEID_HFS
	volume_id_probe_hfs_hfsplus,
#endif
#if ENABLE_FEATURE_VOLUMEID_UFS
	volume_id_probe_ufs,
#endif
#if ENABLE_FEATURE_VOLUMEID_NTFS
	volume_id_probe_ntfs,
#endif
#if ENABLE_FEATURE_VOLUMEID_CRAMFS
	volume_id_probe_cramfs,
#endif
#if ENABLE_FEATURE_VOLUMEID_ROMFS
	volume_id_probe_romfs,
#endif
#if ENABLE_FEATURE_VOLUMEID_HPFS
	volume_id_probe_hpfs,
#endif
#if ENABLE_FEATURE_VOLUMEID_SYSV
	volume_id_probe_sysv,
#endif
#if ENABLE_FEATURE_VOLUMEID_MINIX
	volume_id_probe_minix,
#endif
#if ENABLE_FEATURE_VOLUMEID_OCFS2
	volume_id_probe_ocfs2,
#endif
};

int FAST_FUNC volume_id_probe_all(struct volume_id *id, /*uint64_t off,*/ uint64_t size)
{
	unsigned i;

	/* probe for raid first, cause fs probes may be successful on raid members */
	if (size) {
		for (i = 0; i < ARRAY_SIZE(raid1); i++) {
			if (raid1[i](id, /*off,*/ size) == 0)
				goto ret;
			if (id->error)
				goto ret;
		}
	}

	for (i = 0; i < ARRAY_SIZE(raid2); i++) {
		if (raid2[i](id /*,off*/) == 0)
			goto ret;
		if (id->error)
			goto ret;
	}

	/* signature in the first block, only small buffer needed */
	for (i = 0; i < ARRAY_SIZE(fs1); i++) {
		if (fs1[i](id /*,off*/) == 0)
			goto ret;
		if (id->error)
			goto ret;
	}

	/* fill buffer with maximum */
	volume_id_get_buffer(id, 0, SB_BUFFER_SIZE);

	for (i = 0; i < ARRAY_SIZE(fs2); i++) {
		if (fs2[i](id /*,off*/) == 0)
			goto ret;
		if (id->error)
			goto ret;
	}

 ret:
	volume_id_free_buffer(id);
	return (- id->error); /* 0 or -1 */

}

/* open volume by device node */
struct volume_id* FAST_FUNC volume_id_open_node(int fd)
{
	struct volume_id *id;

	id = xzalloc(sizeof(struct volume_id));
	id->fd = fd;
	///* close fd on device close */
	//id->fd_close = 1;
	return id;
}

#ifdef UNUSED
/* open volume by major/minor */
struct volume_id* FAST_FUNC volume_id_open_dev_t(dev_t devt)
{
	struct volume_id *id;
	char *tmp_node[VOLUME_ID_PATH_MAX];

	tmp_node = xasprintf("/dev/.volume_id-%u-%u-%u",
		(unsigned)getpid(), (unsigned)major(devt), (unsigned)minor(devt));

	/* create temporary node to open block device */
	unlink(tmp_node);
	if (mknod(tmp_node, (S_IFBLK | 0600), devt) != 0)
		bb_perror_msg_and_die("can't mknod(%s)", tmp_node);

	id = volume_id_open_node(tmp_node);
	unlink(tmp_node);
	free(tmp_node);
	return id;
}
#endif

void FAST_FUNC free_volume_id(struct volume_id *id)
{
	if (id == NULL)
		return;

	//if (id->fd_close != 0) - always true
		close(id->fd);
	volume_id_free_buffer(id);
#ifdef UNUSED_PARTITION_CODE
	free(id->partitions);
#endif
	free(id);
}
