/*
 * 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, 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 <asm/byteorder.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"

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

#define htonl __cpu_to_be32

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

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	},
	{ 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;
}
