/*
 * probe.c - identify a block device by its contents, and return a dev
 *           struct with the details
 *
 * Copyright (C) 1999 by Andries Brouwer
 * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
 * Copyright (C) 2001 by Andreas Dilger
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 * %End-Header%
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_SYS_MKDEV_H
#include <sys/mkdev.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include "blkidP.h"
#include "../uuid/uuid.h"
#include "probe.h"

/*
 * This is a special case code to check for an MDRAID device.  We do
 * this special since it requires checking for a superblock at the end
 * of the device.
 */
static int check_mdraid(int fd, unsigned char *ret_uuid)
{
	struct mdp_superblock_s *md;
	blkid_loff_t		offset;
	char			buf[4096];

	if (fd < 0)
		return -BLKID_ERR_PARAM;

	offset = (blkid_get_dev_size(fd) & ~((blkid_loff_t)65535)) - 65536;

	if (blkid_llseek(fd, offset, 0) < 0 ||
	    read(fd, buf, 4096) != 4096)
		return -BLKID_ERR_IO;

	/* Check for magic number */
	if (memcmp("\251+N\374", buf, 4))
		return -BLKID_ERR_PARAM;

	if (!ret_uuid)
		return 0;
	*ret_uuid = 0;

	/* The MD UUID is not contiguous in the superblock, make it so */
	md = (struct mdp_superblock_s *)buf;
	if (md->set_uuid0 || md->set_uuid1 || md->set_uuid2 || md->set_uuid3) {
		memcpy(ret_uuid, &md->set_uuid0, 4);
		memcpy(ret_uuid, &md->set_uuid1, 12);
	}
	return 0;
}

static void set_uuid(blkid_dev dev, uuid_t uuid)
{
	char	str[37];

	if (!uuid_is_null(uuid)) {
		uuid_unparse(uuid, str);
		blkid_set_tag(dev, "UUID", str, sizeof(str));
	}
}

static void get_ext2_info(blkid_dev dev, unsigned char *buf)
{
	struct ext2_super_block *es = (struct ext2_super_block *) buf;
	const char *label = 0;

	DBG(DEBUG_PROBE, printf("ext2_sb.compat = %08X:%08X:%08X\n",
		   blkid_le32(es->s_feature_compat),
		   blkid_le32(es->s_feature_incompat),
		   blkid_le32(es->s_feature_ro_compat)));

	if (strlen(es->s_volume_name))
		label = es->s_volume_name;
	blkid_set_tag(dev, "LABEL", label, sizeof(es->s_volume_name));

	set_uuid(dev, es->s_uuid);
}

static int probe_ext3(int fd __BLKID_ATTR((unused)),
		      blkid_cache cache __BLKID_ATTR((unused)),
		      blkid_dev dev,
		      const struct blkid_magic *id __BLKID_ATTR((unused)), 
		      unsigned char *buf)
{
	struct ext2_super_block *es;

	es = (struct ext2_super_block *)buf;

	/* Distinguish between jbd and ext2/3 fs */
	if (blkid_le32(es->s_feature_incompat) &
	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
		return -BLKID_ERR_PARAM;

	/* Distinguish between ext3 and ext2 */
	if (!(blkid_le32(es->s_feature_compat) &
	      EXT3_FEATURE_COMPAT_HAS_JOURNAL))
		return -BLKID_ERR_PARAM;

	get_ext2_info(dev, buf);

	blkid_set_tag(dev, "SEC_TYPE", "ext2", sizeof("ext2"));

	return 0;
}

static int probe_ext2(int fd __BLKID_ATTR((unused)),
		      blkid_cache cache __BLKID_ATTR((unused)),
		      blkid_dev dev,
		      const struct blkid_magic *id __BLKID_ATTR((unused)), 
		      unsigned char *buf)
{
	struct ext2_super_block *es;

	es = (struct ext2_super_block *)buf;

	/* Distinguish between jbd and ext2/3 fs */
	if (blkid_le32(es->s_feature_incompat) &
	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
		return -BLKID_ERR_PARAM;

	get_ext2_info(dev, buf);

	return 0;
}

static int probe_jbd(int fd __BLKID_ATTR((unused)),
		     blkid_cache cache __BLKID_ATTR((unused)),
		     blkid_dev dev,
		     const struct blkid_magic *id __BLKID_ATTR((unused)),
		     unsigned char *buf)
{
	struct ext2_super_block *es = (struct ext2_super_block *) buf;

	if (!(blkid_le32(es->s_feature_incompat) &
	      EXT3_FEATURE_INCOMPAT_JOURNAL_DEV))
		return -BLKID_ERR_PARAM;

	get_ext2_info(dev, buf);

	return 0;
}

static int probe_vfat(int fd __BLKID_ATTR((unused)),
		      blkid_cache cache __BLKID_ATTR((unused)),
		      blkid_dev dev,
		      const struct blkid_magic *id __BLKID_ATTR((unused)),
		      unsigned char *buf)
{
	struct vfat_super_block *vs;
	char serno[10];
	const char *label = 0;
	int label_len = 0;

	vs = (struct vfat_super_block *)buf;

	if (strncmp(vs->vs_label, "NO NAME", 7)) {
		char *end = vs->vs_label + sizeof(vs->vs_label) - 1;

		while (*end == ' ' && end >= vs->vs_label)
			--end;
		if (end >= vs->vs_label) {
			label = vs->vs_label;
			label_len = end - vs->vs_label + 1;
		}
	}

	/* We can't just print them as %04X, because they are unaligned */
	sprintf(serno, "%02X%02X-%02X%02X", vs->vs_serno[3], vs->vs_serno[2],
		vs->vs_serno[1], vs->vs_serno[0]);
	blkid_set_tag(dev, "LABEL", label, label_len);
	blkid_set_tag(dev, "UUID", serno, sizeof(serno));

	return 0;
}

static int probe_msdos(int fd __BLKID_ATTR((unused)),
		       blkid_cache cache __BLKID_ATTR((unused)),
		       blkid_dev dev,
		       const struct blkid_magic *id __BLKID_ATTR((unused)),
		       unsigned char *buf)
{
	struct msdos_super_block *ms = (struct msdos_super_block *) buf;
	char serno[10];
	const char *label = 0;
	int label_len = 0;

	if (strncmp(ms->ms_label, "NO NAME", 7)) {
		char *end = ms->ms_label + sizeof(ms->ms_label) - 1;

		while (*end == ' ' && end >= ms->ms_label)
			--end;
		if (end >= ms->ms_label) {
			label = ms->ms_label;
			label_len = end - ms->ms_label + 1;
		}
	}

	/* We can't just print them as %04X, because they are unaligned */
	sprintf(serno, "%02X%02X-%02X%02X", ms->ms_serno[3], ms->ms_serno[2],
		ms->ms_serno[1], ms->ms_serno[0]);
	blkid_set_tag(dev, "UUID", serno, 0);
	blkid_set_tag(dev, "LABEL", label, label_len);
	blkid_set_tag(dev, "SEC_TYPE", "msdos", sizeof("msdos"));

	return 0;
}

static int probe_xfs(int fd __BLKID_ATTR((unused)),
		     blkid_cache cache __BLKID_ATTR((unused)),
		     blkid_dev dev,
		     const struct blkid_magic *id __BLKID_ATTR((unused)),
		     unsigned char *buf)
{
	struct xfs_super_block *xs;
	const char *label = 0;

	xs = (struct xfs_super_block *)buf;

	if (strlen(xs->xs_fname))
		label = xs->xs_fname;
	blkid_set_tag(dev, "LABEL", label, sizeof(xs->xs_fname));
	set_uuid(dev, xs->xs_uuid);
	return 0;
}

static int probe_reiserfs(int fd __BLKID_ATTR((unused)),
			  blkid_cache cache __BLKID_ATTR((unused)),
			  blkid_dev dev,
			  const struct blkid_magic *id, unsigned char *buf)
{
	struct reiserfs_super_block *rs = (struct reiserfs_super_block *) buf;
	unsigned int blocksize;
	const char *label = 0;

	blocksize = blkid_le16(rs->rs_blocksize);

	/* If the superblock is inside the journal, we have the wrong one */
	if (id->bim_kboff/(blocksize>>10) > blkid_le32(rs->rs_journal_block))
		return -BLKID_ERR_BIG;

	/* LABEL/UUID are only valid for later versions of Reiserfs v3.6. */
	if (!strcmp(id->bim_magic, "ReIsEr2Fs") ||
	    !strcmp(id->bim_magic, "ReIsEr3Fs")) {
		if (strlen(rs->rs_label))
			label = rs->rs_label;
		set_uuid(dev, rs->rs_uuid);
	}
	blkid_set_tag(dev, "LABEL", label, sizeof(rs->rs_label));

	return 0;
}

static int probe_jfs(int fd __BLKID_ATTR((unused)),
		     blkid_cache cache __BLKID_ATTR((unused)),
		     blkid_dev dev,
		     const struct blkid_magic *id __BLKID_ATTR((unused)),
		     unsigned char *buf)
{
	struct jfs_super_block *js;
	const char *label = 0;

	js = (struct jfs_super_block *)buf;

	if (strlen((char *) js->js_label))
		label = (char *) js->js_label;
	blkid_set_tag(dev, "LABEL", label, sizeof(js->js_label));
	set_uuid(dev, js->js_uuid);
	return 0;
}

static int probe_romfs(int fd __BLKID_ATTR((unused)),
		       blkid_cache cache __BLKID_ATTR((unused)),
		       blkid_dev dev,
		       const struct blkid_magic *id __BLKID_ATTR((unused)),
		       unsigned char *buf)
{
	struct romfs_super_block *ros;
	const char *label = 0;

	ros = (struct romfs_super_block *)buf;

	if (strlen((char *) ros->ros_volume))
		label = (char *) ros->ros_volume;
	blkid_set_tag(dev, "LABEL", label, 0);
	return 0;
}

static int probe_cramfs(int fd __BLKID_ATTR((unused)), 
		       blkid_cache cache __BLKID_ATTR((unused)), 
		       blkid_dev dev,
		       const struct blkid_magic *id __BLKID_ATTR((unused)), 
		       unsigned char *buf)
{
	struct cramfs_super_block *csb;
	const char *label = 0;

	csb = (struct cramfs_super_block *)buf;

	if (strlen((char *) csb->name))
		label = (char *) csb->name;
	blkid_set_tag(dev, "LABEL", label, 0);
	return 0;
}

static int probe_swap0(int fd __BLKID_ATTR((unused)),
		       blkid_cache cache __BLKID_ATTR((unused)),
		       blkid_dev dev,
		       const struct blkid_magic *id __BLKID_ATTR((unused)),
		       unsigned char *buf __BLKID_ATTR((unused)))
{
	blkid_set_tag(dev, "UUID", 0, 0);
	blkid_set_tag(dev, "LABEL", 0, 0);
	return 0;
}

static int probe_swap1(int fd,
		       blkid_cache cache __BLKID_ATTR((unused)),
		       blkid_dev dev,
		       const struct blkid_magic *id __BLKID_ATTR((unused)),
		       unsigned char *buf __BLKID_ATTR((unused)))
{
	struct swap_id_block *sws;

	probe_swap0(fd, cache, dev, id, buf);
	/*
	 * Version 1 swap headers are always located at offset of 1024
	 * bytes, although the swap signature itself is located at the
	 * end of the page (which may vary depending on hardware
	 * pagesize).
	 */
	if (lseek(fd, 1024, SEEK_SET) < 0) return 1;
	sws = (struct swap_id_block *)xmalloc(1024);
	if (read(fd, sws, 1024) != 1024) {
		free(sws);
		return 1;
	}

	/* arbitrary sanity check.. is there any garbage down there? */
	if (sws->sws_pad[32] == 0 && sws->sws_pad[33] == 0)  {
		if (sws->sws_volume[0])
			blkid_set_tag(dev, "LABEL", (const char*)sws->sws_volume,
				      sizeof(sws->sws_volume));
		if (sws->sws_uuid[0])
			set_uuid(dev, sws->sws_uuid);
	}
	free(sws);

	return 0;
}

static const char
* const udf_magic[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02",
		 "NSR03", "TEA01", 0 };

static int probe_udf(int fd, blkid_cache cache __BLKID_ATTR((unused)),
		     blkid_dev dev __BLKID_ATTR((unused)),
		     const struct blkid_magic *id __BLKID_ATTR((unused)),
		     unsigned char *buf __BLKID_ATTR((unused)))
{
	int j, bs;
	struct iso_volume_descriptor isosb;
	const char * const * m;

	/* determine the block size by scanning in 2K increments
	   (block sizes larger than 2K will be null padded) */
	for (bs = 1; bs < 16; bs++) {
		lseek(fd, bs*2048+32768, SEEK_SET);
		if (read(fd, (char *)&isosb, sizeof(isosb)) != sizeof(isosb))
			return 1;
		if (isosb.id[0])
			break;
	}

	/* Scan up to another 64 blocks looking for additional VSD's */
	for (j = 1; j < 64; j++) {
		if (j > 1) {
			lseek(fd, j*bs*2048+32768, SEEK_SET);
			if (read(fd, (char *)&isosb, sizeof(isosb))
			    != sizeof(isosb))
				return 1;
		}
		/* If we find NSR0x then call it udf:
		   NSR01 for UDF 1.00
		   NSR02 for UDF 1.50
		   NSR03 for UDF 2.00 */
		if (!strncmp(isosb.id, "NSR0", 4))
			return 0;
		for (m = udf_magic; *m; m++)
			if (!strncmp(*m, isosb.id, 5))
				break;
		if (*m == 0)
			return 1;
	}
	return 1;
}

static int probe_ocfs(int fd __BLKID_ATTR((unused)),
		      blkid_cache cache __BLKID_ATTR((unused)),
		      blkid_dev dev,
		      const struct blkid_magic *id __BLKID_ATTR((unused)),
		      unsigned char *buf)
{
	struct ocfs_volume_header ovh;
	struct ocfs_volume_label ovl;
	__u32 major;

	memcpy(&ovh, buf, sizeof(ovh));
	memcpy(&ovl, buf+512, sizeof(ovl));

	major = ocfsmajor(ovh);
	if (major == 1)
		blkid_set_tag(dev,"SEC_TYPE","ocfs1",sizeof("ocfs1"));
	else if (major >= 9)
		blkid_set_tag(dev,"SEC_TYPE","ntocfs",sizeof("ntocfs"));

	blkid_set_tag(dev, "LABEL", (const char*)ovl.label, ocfslabellen(ovl));
	blkid_set_tag(dev, "MOUNT", (const char*)ovh.mount, ocfsmountlen(ovh));
	set_uuid(dev, ovl.vol_id);
	return 0;
}

static int probe_ocfs2(int fd __BLKID_ATTR((unused)),
		       blkid_cache cache __BLKID_ATTR((unused)),
		       blkid_dev dev,
		       const struct blkid_magic *id __BLKID_ATTR((unused)),
		       unsigned char *buf)
{
	struct ocfs2_super_block *osb;

	osb = (struct ocfs2_super_block *)buf;

	blkid_set_tag(dev, "LABEL", (const char*)osb->s_label, sizeof(osb->s_label));
	set_uuid(dev, osb->s_uuid);
	return 0;
}

static int probe_oracleasm(int fd __BLKID_ATTR((unused)),
			   blkid_cache cache __BLKID_ATTR((unused)),
			   blkid_dev dev,
			   const struct blkid_magic *id __BLKID_ATTR((unused)),
			   unsigned char *buf)
{
	struct oracle_asm_disk_label *dl;

	dl = (struct oracle_asm_disk_label *)buf;

	blkid_set_tag(dev, "LABEL", dl->dl_id, sizeof(dl->dl_id));
	return 0;
}

/*
 * BLKID_BLK_OFFS is at least as large as the highest bim_kboff defined
 * in the type_array table below + bim_kbalign.
 *
 * When probing for a lot of magics, we handle everything in 1kB buffers so
 * that we don't have to worry about reading each combination of block sizes.
 */
#define BLKID_BLK_OFFS	64	/* currently reiserfs */

/*
 * Various filesystem magics that we can check for.  Note that kboff and
 * sboff are in kilobytes and bytes respectively.  All magics are in
 * byte strings so we don't worry about endian issues.
 */
static const struct blkid_magic type_array[] = {
/*  type     kboff   sboff len  magic			probe */
  { "oracleasm", 0,	32,  8, "ORCLDISK",		probe_oracleasm },
  { "ntfs",      0,      3,  8, "NTFS    ",             0 },
  { "jbd",	 1,   0x38,  2, "\123\357",		probe_jbd },
  { "ext3",	 1,   0x38,  2, "\123\357",		probe_ext3 },
  { "ext2",	 1,   0x38,  2, "\123\357",		probe_ext2 },
  { "reiserfs",	 8,   0x34,  8, "ReIsErFs",		probe_reiserfs },
  { "reiserfs", 64,   0x34,  9, "ReIsEr2Fs",		probe_reiserfs },
  { "reiserfs", 64,   0x34,  9, "ReIsEr3Fs",		probe_reiserfs },
  { "reiserfs", 64,   0x34,  8, "ReIsErFs",		probe_reiserfs },
  { "reiserfs",	 8,	20,  8, "ReIsErFs",		probe_reiserfs },
  { "vfat",      0,   0x52,  5, "MSWIN",                probe_vfat },
  { "vfat",      0,   0x52,  8, "FAT32   ",             probe_vfat },
  { "vfat",      0,   0x36,  5, "MSDOS",                probe_msdos },
  { "vfat",      0,   0x36,  8, "FAT16   ",             probe_msdos },
  { "vfat",      0,   0x36,  8, "FAT12   ",             probe_msdos },
  { "minix",     1,   0x10,  2, "\177\023",             0 },
  { "minix",     1,   0x10,  2, "\217\023",             0 },
  { "minix",	 1,   0x10,  2, "\150\044",		0 },
  { "minix",	 1,   0x10,  2, "\170\044",		0 },
  { "vxfs",	 1,	 0,  4, "\365\374\001\245",	0 },
  { "xfs",	 0,	 0,  4, "XFSB",			probe_xfs },
  { "romfs",	 0,	 0,  8, "-rom1fs-",		probe_romfs },
  { "bfs",	 0,	 0,  4, "\316\372\173\033",	0 },
  { "cramfs",	 0,	 0,  4, "E=\315\050",		probe_cramfs },
  { "qnx4",	 0,	 4,  6, "QNX4FS",		0 },
  { "udf",	32,	 1,  5, "BEA01",		probe_udf },
  { "udf",	32,	 1,  5, "BOOT2",		probe_udf },
  { "udf",	32,	 1,  5, "CD001",		probe_udf },
  { "udf",	32,	 1,  5, "CDW02",		probe_udf },
  { "udf",	32,	 1,  5, "NSR02",		probe_udf },
  { "udf",	32,	 1,  5, "NSR03",		probe_udf },
  { "udf",	32,	 1,  5, "TEA01",		probe_udf },
  { "iso9660",	32,	 1,  5, "CD001",		0 },
  { "iso9660",	32,	 9,  5, "CDROM",		0 },
  { "jfs",	32,	 0,  4, "JFS1",			probe_jfs },
  { "hfs",	 1,	 0,  2, "BD",			0 },
  { "ufs",	 8,  0x55c,  4, "T\031\001\000",	0 },
  { "hpfs",	 8,	 0,  4, "I\350\225\371",	0 },
  { "sysv",	 0,  0x3f8,  4, "\020~\030\375",	0 },
  { "swap",	 0,  0xff6, 10, "SWAP-SPACE",		probe_swap0 },
  { "swap",	 0,  0xff6, 10, "SWAPSPACE2",		probe_swap1 },
  { "swap",	 0, 0x1ff6, 10, "SWAP-SPACE",		probe_swap0 },
  { "swap",	 0, 0x1ff6, 10, "SWAPSPACE2",		probe_swap1 },
  { "swap",	 0, 0x3ff6, 10, "SWAP-SPACE",		probe_swap0 },
  { "swap",	 0, 0x3ff6, 10, "SWAPSPACE2",		probe_swap1 },
  { "swap",	 0, 0x7ff6, 10, "SWAP-SPACE",		probe_swap0 },
  { "swap",	 0, 0x7ff6, 10, "SWAPSPACE2",		probe_swap1 },
  { "swap",	 0, 0xfff6, 10, "SWAP-SPACE",		probe_swap0 },
  { "swap",	 0, 0xfff6, 10, "SWAPSPACE2",		probe_swap1 },
  { "ocfs",	 0,	 8,  9,	"OracleCFS",		probe_ocfs },
  { "ocfs2",	 1,	 0,  6,	"OCFSV2",		probe_ocfs2 },
  { "ocfs2",	 2,	 0,  6,	"OCFSV2",		probe_ocfs2 },
  { "ocfs2",	 4,	 0,  6,	"OCFSV2",		probe_ocfs2 },
  { "ocfs2",	 8,	 0,  6,	"OCFSV2",		probe_ocfs2 },
  {   NULL,	 0,	 0,  0, NULL,			NULL }
};

/*
 * Verify that the data in dev is consistent with what is on the actual
 * block device (using the devname field only).  Normally this will be
 * called when finding items in the cache, but for long running processes
 * is also desirable to revalidate an item before use.
 *
 * If we are unable to revalidate the data, we return the old data and
 * do not set the BLKID_BID_FL_VERIFIED flag on it.
 */
blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev)
{
	const struct blkid_magic *id;
	unsigned char *bufs[BLKID_BLK_OFFS + 1], *buf;
	const char *type;
	struct stat st;
	time_t diff, now;
	int fd, idx;

	if (!dev)
		return NULL;

	now = time(0);
	diff = now - dev->bid_time;

	if ((now < dev->bid_time) ||
	    (diff < BLKID_PROBE_MIN) ||
	    (dev->bid_flags & BLKID_BID_FL_VERIFIED &&
	     diff < BLKID_PROBE_INTERVAL))
		return dev;

	DBG(DEBUG_PROBE,
	    printf("need to revalidate %s (time since last check %lu)\n",
		   dev->bid_name, diff));

	if (((fd = open(dev->bid_name, O_RDONLY)) < 0) ||
	    (fstat(fd, &st) < 0)) {
		if (errno == ENXIO || errno == ENODEV || errno == ENOENT) {
			blkid_free_dev(dev);
			return NULL;
		}
		/* We don't have read permission, just return cache data. */
		DBG(DEBUG_PROBE,
		    printf("returning unverified data for %s\n",
			   dev->bid_name));
		return dev;
	}

	memset(bufs, 0, sizeof(bufs));

	/*
	 * Iterate over the type array.  If we already know the type,
	 * then try that first.  If it doesn't work, then blow away
	 * the type information, and try again.
	 *
	 */
try_again:
	type = 0;
	if (!dev->bid_type || !strcmp(dev->bid_type, "mdraid")) {
		uuid_t	uuid;

		if (check_mdraid(fd, uuid) == 0) {
			set_uuid(dev, uuid);
			type = "mdraid";
			goto found_type;
		}
	}
	for (id = type_array; id->bim_type; id++) {
		if (dev->bid_type &&
		    strcmp(id->bim_type, dev->bid_type))
			continue;

		idx = id->bim_kboff + (id->bim_sboff >> 10);
		if (idx > BLKID_BLK_OFFS || idx < 0)
			continue;
		buf = bufs[idx];
		if (!buf) {
			if (lseek(fd, idx << 10, SEEK_SET) < 0)
				continue;

			buf = (unsigned char *)xmalloc(1024);

			if (read(fd, buf, 1024) != 1024) {
				free(buf);
				continue;
			}
			bufs[idx] = buf;
		}

		if (memcmp(id->bim_magic, buf + (id->bim_sboff&0x3ff),
			   id->bim_len))
			continue;

		if ((id->bim_probe == NULL) ||
		    (id->bim_probe(fd, cache, dev, id, buf) == 0)) {
			type = id->bim_type;
			goto found_type;
		}
	}

	if (!id->bim_type && dev->bid_type) {
		/*
		 * Zap the device filesystem type and try again
		 */
		blkid_set_tag(dev, "TYPE", 0, 0);
		blkid_set_tag(dev, "SEC_TYPE", 0, 0);
		blkid_set_tag(dev, "LABEL", 0, 0);
		blkid_set_tag(dev, "UUID", 0, 0);
		goto try_again;
	}

	if (!dev->bid_type) {
		blkid_free_dev(dev);
		return NULL;
	}

found_type:
	if (dev && type) {
		dev->bid_devno = st.st_rdev;
		dev->bid_time = time(0);
		dev->bid_flags |= BLKID_BID_FL_VERIFIED;
		cache->bic_flags |= BLKID_BIC_FL_CHANGED;

		blkid_set_tag(dev, "TYPE", type, 0);

		DBG(DEBUG_PROBE, printf("%s: devno 0x%04llx, type %s\n",
			   dev->bid_name, st.st_rdev, type));
	}

	close(fd);

	return dev;
}

int blkid_known_fstype(const char *fstype)
{
	const struct blkid_magic *id;

	for (id = type_array; id->bim_type; id++) {
		if (strcmp(fstype, id->bim_type) == 0)
			return 1;
	}
	return 0;
}

#ifdef TEST_PROGRAM
int main(int argc, char **argv)
{
	blkid_dev dev;
	blkid_cache cache;
	int ret;

	blkid_debug_mask = DEBUG_ALL;
	if (argc != 2) {
		fprintf(stderr, "Usage: %s device\n"
			"Probe a single device to determine type\n", argv[0]);
		exit(1);
	}
	if ((ret = blkid_get_cache(&cache, bb_dev_null)) != 0) {
		fprintf(stderr, "%s: error creating cache (%d)\n",
			argv[0], ret);
		exit(1);
	}
	dev = blkid_get_dev(cache, argv[1], BLKID_DEV_NORMAL);
	if (!dev) {
		printf("%s: %s has an unsupported type\n", argv[0], argv[1]);
		return (1);
	}
	printf("%s is type %s\n", argv[1], dev->bid_type ?
		dev->bid_type : "(null)");
	if (dev->bid_label)
		printf("\tlabel is '%s'\n", dev->bid_label);
	if (dev->bid_uuid)
		printf("\tuuid is %s\n", dev->bid_uuid);

	blkid_free_dev(dev);
	return (0);
}
#endif
