/*
 * 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 (*raid_probe_fptr)(struct volume_id *id, uint64_t off, uint64_t size);
typedef int (*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_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 volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size)
{
	unsigned i;

	if (id == NULL)
		return -EINVAL;

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

	for (i = 0; i < ARRAY_SIZE(raid2); i++)
		if (raid2[i](id, off) == 0)
			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;

	/* 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;
	return -1;

 ret:
	/* If the filestystem in recognized, we free the allocated buffers,
	   otherwise they will stay in place for the possible next probe call */
	volume_id_free_buffer(id);

	return 0;
}

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

	fd = open(path, O_RDONLY);
	if (fd < 0)
		return NULL;
	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 *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("cannot mknod(%s)", tmp_node);

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

void 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);
}
