/*
 * 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, jfs
 *
 * MINIX, ext3 and Reiserfs bits are currently untested.
 */

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

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

#include "romfs_fs.h"
#include "cramfs_fs.h"
#include "minix_fs.h"
#include "ext2_fs.h"
#include "ext3_fs.h"
#include "xfs_sb.h"

/*
 * Slightly cleaned up version of jfs_superblock to
 * avoid pulling in other kernel header files.
 */
#include "jfs_superblock.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;
}

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

	if (!memcmp(sb->s_magic, JFS_MAGIC, 4)) {
		/* 512 is the VFS Block size */
		*blocks = __le32_to_cpu(sb->s_size) * 512;;
		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	},
	{ 32,	"jfs",		jfs_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;
	int fd = 0;

	progname = argv[0];

	if (argc > 2) {
		fprintf(stderr, "Usage: %s [file]\n", progname);
		return 1;
	}

	if (argc > 1 && strcmp(argv[1], "-")) {
		fd = open(argv[1], O_RDONLY);
		if ( fd < 0 ) {
			perror(argv[1]);
			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(fd, 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;
}
