#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <alloca.h>
#include <inttypes.h>

#include "do_mounts.h"
#include "kinit.h"
#include "fstype.h"
#include "zlib.h"

#define BUF_SZ		65536

/* Find dev_t for e.g. "hda,NULL" or "hdb,2" */
static dev_t
try_name(char *name, int part)
{
	char path[BUF_SZ];
	char buf[BUF_SZ];
	int range;
	unsigned int major, minor;
	dev_t res;
	char *s;
	int len;
	int fd;

	/* read device number from /sys/block/.../dev */
	snprintf(path, sizeof(path), "/sys/block/%s/dev", name);
	fd = open(path, 0, 0);
	if (fd < 0)
		goto fail;
	len = read(fd, buf, BUF_SZ);
	close(fd);

	if (len <= 0 || len == BUF_SZ || buf[len - 1] != '\n')
		goto fail;
	buf[len - 1] = '\0';
	major = strtoul(buf, &s, 10);
	if (*s != ':')
		goto fail;
	minor = strtoul(s+1, &s, 10);
	if (*s)
		goto fail;
	res = makedev(major, minor);

	/* if it's there and we are not looking for a partition - that's it */
	if (!part)
		return res;

	/* otherwise read range from .../range */
	snprintf(path, sizeof(path), "/sys/block/%s/range", name);
	fd = open(path, 0, 0);
	if (fd < 0)
		goto fail;
	len = read(fd, buf, 32);
	close(fd);
	if (len <= 0 || len == 32 || buf[len - 1] != '\n')
		goto fail;
	buf[len - 1] = '\0';
	range = strtoul(buf, &s, 10);
	if (*s)
		goto fail;

	/* if partition is within range - we got it */
	if (part < range) {
		DEBUG(("kinit: try_name %s,%d = %s\n", name, part,
		       bdevname(res+part)));
		return res + part;
	}

fail:
	return (dev_t) 0;
}

/*
 *	Convert a name into device number.  We accept the following variants:
 *
 *	1) device number in hexadecimal	represents itself
 *	2) /dev/nfs represents Root_NFS
 *	3) /dev/<disk_name> represents the device number of disk
 *	4) /dev/<disk_name><decimal> represents the device number
 *         of partition - device number of disk plus the partition number
 *	5) /dev/<disk_name>p<decimal> - same as the above, that form is
 *	   used when disk name of partitioned disk ends on a digit.
 *	6) an actual block device node in the initramfs filesystem
 *
 *	If name doesn't have fall into the categories above, we return 0.
 *	Driverfs is used to check if something is a disk name - it has
 *	all known disks under bus/block/devices.  If the disk name
 *	contains slashes, name of driverfs node has them replaced with
 *	dots.  try_name() does the actual checks, assuming that driverfs
 *	is mounted on rootfs /sys.
 */

static inline dev_t
name_to_dev_t_real(const char *name)
{
	char *p;
	dev_t res = 0;
	char *s;
	int part;
	struct stat st;
	int len;
	const char *devname;

	if ( name[0] == '/' )
		devname = name;
	else {
		char *dname = alloca(strlen(name) + 6);
		sprintf(dname, "/dev/%s", name);
		devname = dname;
	}

	if (!stat(devname, &st) && S_ISBLK(st.st_mode))
		return st.st_rdev;

	if (strncmp(name, "/dev/", 5)) {
		res = (dev_t) strtoul(name, &p, 16);
		if (!*p)
			return res;
	} else {
		name += 5;
	}

	if (!strcmp(name, "nfs"))
		return Root_NFS;

	if (!strncmp(name, "mtd", 3))
		return Root_MTD;

	len = strlen(name);
	s = alloca(len+1);
	memcpy(s, name, len+1);

	for (p = s; *p; p++)
		if (*p == '/')
			*p = '.';
	res = try_name(s, 0);
	if (res)
		return res;

	while (p > s && isdigit(p[-1]))
		p--;
	if (p == s || !*p || *p == '0')
		goto fail;
	part = strtoul(p, NULL, 10);
	*p = '\0';
	res = try_name(s, part);
	if (res)
		return res;

	if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
		goto fail;
	p[-1] = '\0';
	res = try_name(s, part);
	return res;

 fail:
	return (dev_t)0;
}

dev_t
name_to_dev_t(const char *name)
{
	dev_t dev = name_to_dev_t_real(name);

	DEBUG(("kinit: name_to_dev_t(%s) = %s\n", name, bdevname(dev)));
	return dev;
}

/* Create the device node "name" */
int
create_dev(const char *name, dev_t dev)
{
	unlink(name);
	return mknod(name, S_IFBLK|0600, dev);
}

/* mount a filesystem, possibly trying a set of different types */
const char *
mount_block(const char *source, const char *target,
	    const char *type, unsigned long flags,
	    const void *data)
{
	char *fslist, *p, *ep;
	const char *rp;
	ssize_t fsbytes;

	if ( type ) {
		DEBUG(("kinit: trying to mount %s on %s with type %s\n",
		       source, target, type));
		int rv = mount(source, target, type, flags, data);
		/* Mount readonly if necessary */
		if ( rv == -1 && errno == EACCES && !(flags & MS_RDONLY) )
			rv = mount(source, target, type, flags|MS_RDONLY, data);
		return rv ? NULL : type;
	}

	fsbytes = readfile("/proc/filesystems", &fslist);

	errno = EINVAL;
	if ( fsbytes < 0 )
		return NULL;

	p = fslist;
	ep = fslist+fsbytes;

	rp = NULL;

	while ( p < ep ) {
		type = p;
		p = strchr(p, '\n');
		if (!p)
			break;
		*p++ = '\0';
		if (*type != '\t')/* We can't mount a block device as a "nodev" fs */
			continue;

		type++;
		rp = mount_block(source, target, type, flags, data);
		if ( rp )
			break;
		if ( errno != EINVAL )
			break;
	}

	free(fslist);
	return rp;
}

/* mount the root filesystem from a block device */
static int
mount_block_root(int argc, char *argv[], dev_t root_dev,
		 const char *type, unsigned long flags)
{
	const char *data, *rp;

	data = get_arg(argc, argv, "rootflags=");
	create_dev("/dev/root", root_dev);

	errno = 0;

	if ( type ) {
		if ( (rp = mount_block("/dev/root", "/root", type, flags, data)) )
			goto ok;
		if ( errno != EINVAL )
			goto bad;
	}

	if ( !errno && (rp = mount_block("/dev/root", "/root", NULL, flags, data)) )
		goto ok;

 bad:
	if ( errno != EINVAL ) {
	        /*
		 * Allow the user to distinguish between failed open
		 * and bad superblock on root device.
		 */
		fprintf(stderr, "%s: Cannot open root device %s\n",
			progname, bdevname(root_dev));
		return -errno;
	} else {
		fprintf(stderr, "%s: Unable to mount root fs on device %s\n",
			progname, bdevname(root_dev));
		return -ESRCH;
	}

ok:
	printf("%s: Mounted root (%s filesystem)%s.\n",
	       progname, rp, (flags & MS_RDONLY) ? " readonly" : "");
	return 0;
}

int
mount_root(int argc, char *argv[], dev_t root_dev, const char *root_dev_name)
{
	unsigned long flags = MS_RDONLY|MS_VERBOSE;
	int ret;
	const char *type = get_arg(argc, argv, "rootfstype=");

	if (get_flag(argc, argv, "rw")) {
		DEBUG(("kinit: rw flag specified\n"));
		flags &= ~MS_RDONLY;
	}

	if (type) {
		if (!strcmp(type, "nfs"))
			root_dev = Root_NFS;
		else if (!strcmp(type, "jffs2") && !major(root_dev))
			root_dev = Root_MTD;
	}

	switch (root_dev) {
	case Root_NFS:
		ret = mount_nfs_root(argc, argv, flags);
		break;
	case Root_MTD:
		ret = mount_mtd_root(argc, argv, root_dev_name, type, flags);
		break;
	default:
		ret = mount_block_root(argc, argv, root_dev, type, flags);
		break;
	}

	if (!ret)
		chdir("/root");

	return ret;
}

int do_mounts(int argc, char *argv[])
{
	const char *root_dev_name = get_arg(argc, argv, "root=");
	const char *root_delay = get_arg(argc, argv, "rootdelay=");
	const char *load_ramdisk = get_arg(argc, argv, "load_ramdisk=");
	dev_t root_dev = 0;

	DEBUG(("kinit: do_mounts\n"));

	if (root_delay) {
		int delay = atoi(root_delay);
		fprintf(stderr, "Waiting %d s before mounting root device...\n", delay);
		sleep(delay);
	}

	md_run(argc, argv);

	if (root_dev_name) {
		root_dev = name_to_dev_t(root_dev_name);
	} else if (get_arg(argc, argv, "nfsroot=") ||
		   get_arg(argc, argv, "nfsaddrs=")) {
		root_dev = Root_NFS;
	} else {
		long rootdev;
		getintfile("/proc/sys/kernel/real-root-dev", &rootdev);
		root_dev = (dev_t)rootdev;
	}

	DEBUG(("kinit: root_dev = %s\n", bdevname(root_dev)));

	if ( initrd_load(argc, argv, root_dev) ) {
		DEBUG(("initrd loaded\n"));
		return 0;
	}

	if ( load_ramdisk && atoi(load_ramdisk) ) {
		if (ramdisk_load(argc, argv, root_dev))
			root_dev = Root_RAM0;
	}

	return mount_root(argc, argv, root_dev, root_dev_name);
}
