/*
 * fstype.c, by rmk
 *
 * Detect filesystem type (on stdin) and output strings for two
 * environment variables:
 *  FSTYPE - filesystem type
 *  FSSIZE - filesystem size (if known)
 *
 * We currently detect (in order):
 *  gzip, cramfs, romfs, xfs, minix, ext3, ext2, reiserfs
 *
 * MINIX, ext3 and Reiserfs bits are currently untested.
 */

#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <endian.h>
#include <netinet/in.h>

#define cpu_to_be32(x) __cpu_to_be32(x)	/* Needed by romfs_fs.h */

#include <linux/romfs_fs.h>
#include <linux/cramfs_fs.h>
#include <linux/minix_fs.h>
#define _LINUX_EXT2_FS_SB
#include <linux/ext2_fs.h>
#include "ext3_fs.h"
#include "xfs_sb.h"

/*
 * reiserfs_fs.h is too sick to include directly.
 * Use a cleaned up version.
 */
#include "reiserfs_fs.h"

char *progname;

#define ARRAY_SIZE(x)	(sizeof(x) / sizeof(x[0]))

#define BLOCK_SIZE_BITS 10
#define BLOCK_SIZE	(1 << BLOCK_SIZE_BITS)
#define BYTES_TO_BLOCKS(x) (((x) + (BLOCK_SIZE - 1)) >> BLOCK_SIZE_BITS)

static int fstype(const char *type, unsigned long size)
{
	fprintf(stdout, "FSTYPE=%s\nFSSIZE=%lu\n", type, size);
	return 0;
}

static int readfile(int fd, off_t off, void *buf, size_t size)
{
	int ret;

	if (lseek(fd, off, SEEK_SET) == -1) {
		perror("lseek");
		return 1;
	}

	ret = read(fd, buf, size);
	if (ret == -1) {
		perror("read");
		return 1;
	}
	if (ret != BLOCK_SIZE) {
		fprintf(stderr, "%s: short read\n", progname);
		return 1;
	}
	return 0;
}

static int gzip_image(const unsigned char *buf, unsigned long *blocks)
{
	if (buf[0] == 037 && (buf[1] == 0213 || buf[1] == 0236)) {
		*blocks = 0;
		return 1;
	}
	return 0;
}

static int cramfs_image(const unsigned char *buf, unsigned long *blocks)
{
	const struct cramfs_super *sb =
		(const struct cramfs_super *)buf;

	if (sb->magic == CRAMFS_MAGIC) {
		if (sb->flags & CRAMFS_FLAG_FSID_VERSION_2)
			*blocks = sb->fsid.blocks;
		else
			*blocks = 0;
		return 1;
	}
	return 0;
}

static int romfs_image(const unsigned char *buf, unsigned long *blocks)
{
        const struct romfs_super_block *sb =
		(const struct romfs_super_block *)buf;

	if (sb->word0 == ROMSB_WORD0 && sb->word1 == ROMSB_WORD1) {
		*blocks = (unsigned long)BYTES_TO_BLOCKS(__be32_to_cpu(sb->size));
		return 1;
	}
	return 0;
}

static int minix_image(const unsigned char *buf, unsigned long *blocks)
{
	const struct minix_super_block *sb =
		(const struct minix_super_block *)buf;

	if (sb->s_magic == MINIX_SUPER_MAGIC ||
	    sb->s_magic == MINIX_SUPER_MAGIC2) {
		*blocks = sb->s_nzones << sb->s_log_zone_size;
		return 1;
	}
	return 0;
}

static int ext3_image(const unsigned char *buf, unsigned long *blocks)
{
	const struct ext3_super_block *sb =
		(const struct ext3_super_block *)buf;

	if (sb->s_magic == __cpu_to_le16(EXT2_SUPER_MAGIC) &&
	    sb->s_feature_compat & __cpu_to_le32(EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
		*blocks = __le32_to_cpu(sb->s_blocks_count);
		return 1;
	}
	return 0;
}

static int ext2_image(const unsigned char *buf, unsigned long *blocks)
{
	const struct ext2_super_block *sb =
		(const struct ext2_super_block *)buf;

	if (sb->s_magic == __cpu_to_le16(EXT2_SUPER_MAGIC)) {
		*blocks = __le32_to_cpu(sb->s_blocks_count);
		return 1;
	}
	return 0;
}

static int reiserfs_image(const unsigned char *buf, unsigned long *blocks)
{
	const struct reiserfs_super_block *sb =
		(const struct reiserfs_super_block *)buf;

	if (memcmp(REISERFS_MAGIC(sb), REISERFS_SUPER_MAGIC_STRING,
		   sizeof(REISERFS_SUPER_MAGIC_STRING) - 1) == 0 ||
	    memcmp(REISERFS_MAGIC(sb), REISER2FS_SUPER_MAGIC_STRING,
		   sizeof(REISER2FS_SUPER_MAGIC_STRING) - 1) == 0 ||
	    memcmp(REISERFS_MAGIC(sb), REISER2FS_JR_SUPER_MAGIC_STRING,
		   sizeof(REISER2FS_JR_SUPER_MAGIC_STRING) - 1) == 0) {
		*blocks = REISERFS_BLOCK_COUNT(sb) *
			  (REISERFS_BLOCKSIZE(sb) / BLOCK_SIZE);
		return 1;
	}
	return 0;
}

static int xfs_image(const unsigned char *buf, unsigned long *blocks)
{
	const struct xfs_sb *sb =
		(const struct xfs_sb *)buf;

	if (__be32_to_cpu(sb->sb_magicnum) == XFS_SB_MAGIC) {
		*blocks = __be64_to_cpu(sb->sb_dblocks) *
			  (__be32_to_cpu(sb->sb_blocksize) / BLOCK_SIZE);
		return 1;
	}
	return 0;
}

struct imagetype {
	off_t		block;
	const char	name[12];
	int		(*identify)(const unsigned char *, unsigned long *);
};

static struct imagetype images[] = {
	{ 0,	"gzip",		gzip_image	},
	{ 0,	"cramfs",	cramfs_image	},
	{ 0,	"romfs",	romfs_image	},
	{ 0,	"xfs",		xfs_image	},
	{ 1,	"minix",	minix_image	},
	{ 1,	"ext3",		ext3_image	},
	{ 1,	"ext2",		ext2_image	},
	{ 8,	"reiserfs",	reiserfs_image	},
	{ 64,	"reiserfs",	reiserfs_image	}
};

int main(int argc, char *argv[])
{
	unsigned char buf[BLOCK_SIZE];
	unsigned long size = 0;
	off_t cur_block = (off_t)-1;
	unsigned int i;
	int ret;

	progname = argv[0];

	if (argc != 1) {
		fprintf(stderr, "Usage: %s < file\n", progname);
		return 1;
	}

	for (i = 0; i < ARRAY_SIZE(images); i++) {
		if (cur_block != images[i].block) {
			/*
			 * Read block.
			 */
			cur_block = images[i].block;
			ret = readfile(0, cur_block * BLOCK_SIZE, buf,
				       BLOCK_SIZE);
			if (ret != 0)
				return ret;
		}

		if (images[i].identify(buf, &size))
			return fstype(images[i].name, size);
	}

	fstype("unknown", 0);
	return 0;
}
