/*
 * e2initrd_helper.c - Get the filesystem table
 *
 * Copyright 2004 by Theodore Ts'o.
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the GNU Public
 * License.
 * %End-Header%
 */

#include "config.h"
#include <stdio.h>
#include <unistd.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <ctype.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <utime.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
extern int optind;
extern char *optarg;
#endif

#include "ext2fs/ext2_fs.h"
#include "ext2fs/ext2fs.h"
#include "blkid/blkid.h"
#include "support/nls-enable.h"

#include "../version.h"

static const char * program_name = "e2initrd_helper";
static char * device_name;
static int open_flag;
static int root_type;
static blkid_cache cache = NULL;

struct mem_file {
	char	*buf;
	int	size;
	int	ptr;
};

struct fs_info {
	char  *device;
	char  *mountpt;
	char  *type;
	char  *opts;
	int   freq;
	int   passno;
	int   flags;
	struct fs_info *next;
};

static void usage(void)
{
	fprintf(stderr,
		_("Usage: %s -r device\n"), program_name);
	exit (1);
}

static errcode_t get_file(ext2_filsys fs, const char * filename,
		   struct mem_file *ret_file)
{
	errcode_t	retval;
	char 		*buf;
	ext2_file_t	e2_file = NULL;
	unsigned int	got;
	struct ext2_inode inode;
	ext2_ino_t	ino;

	ret_file->buf = 0;
	ret_file->size = 0;
	ret_file->ptr = 0;

	retval = ext2fs_namei(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
			      filename, &ino);
	if (retval)
		return retval;

	retval = ext2fs_read_inode(fs, ino, &inode);
	if (retval)
		return retval;

	if (inode.i_size_high || (inode.i_size > 65536))
		return EFBIG;

	buf = malloc(inode.i_size + 1);
	if (!buf)
		return ENOMEM;
	memset(buf, 0, inode.i_size+1);

	retval = ext2fs_file_open(fs, ino, 0, &e2_file);
	if (retval)
		goto errout;

	retval = ext2fs_file_read(e2_file, buf, inode.i_size, &got);
	if (retval)
		goto errout;

	retval = ext2fs_file_close(e2_file);
	if (retval)
		goto errout;

	ret_file->buf = buf;
	ret_file->size = (int) got;
	return 0;

errout:
	free(buf);
	if (e2_file)
		ext2fs_file_close(e2_file);
	return retval;
}

static char *get_line(struct mem_file *file)
{
	char	*cp, *ret;
	int	s = 0;

	cp = file->buf + file->ptr;
	while (*cp && *cp != '\n') {
		cp++;
		s++;
	}
	ret = malloc(s+1);
	if (!ret)
		return 0;
	ret[s]=0;
	memcpy(ret, file->buf + file->ptr, s);
	while (*cp && (*cp == '\n' || *cp == '\r')) {
		cp++;
		s++;
	}
	file->ptr += s;
	return ret;
}

static int mem_file_eof(struct mem_file *file)
{
	return (file->ptr >= file->size);
}

/*
 * fstab parsing code
 */
static char *string_copy(const char *s)
{
	char	*ret;

	if (!s)
		return 0;
	ret = malloc(strlen(s)+1);
	if (ret)
		strcpy(ret, s);
	return ret;
}

static char *skip_over_blank(char *cp)
{
	while (*cp && isspace(*cp))
		cp++;
	return cp;
}

static char *skip_over_word(char *cp)
{
	while (*cp && !isspace(*cp))
		cp++;
	return cp;
}

static char *parse_word(char **buf)
{
	char *word, *next;

	word = *buf;
	if (*word == 0)
		return 0;

	word = skip_over_blank(word);
	next = skip_over_word(word);
	if (*next)
		*next++ = 0;
	*buf = next;
	return word;
}

static void parse_escape(char *word)
{
	char	*p, *q;
	int	ac, i;

	if (!word)
		return;

	for (p = word, q = word; *p; p++, q++) {
		*q = *p;
		if (*p != '\\')
			continue;
		if (*++p == 0)
			break;
		if (*p == 't') {
			*q = '\t';
			continue;
		}
		if (*p == 'n') {
			*q = '\n';
			continue;
		}
		if (!isdigit(*p)) {
			*q = *p;
			continue;
		}
		ac = 0;
		for (i = 0; i < 3; i++, p++) {
			if (!isdigit(*p))
				break;
			ac = (ac * 8) + (*p - '0');
		}
		*q = ac;
		p--;
	}
	*q = 0;
}

static int parse_fstab_line(char *line, struct fs_info *fs)
{
	char	*dev, *device, *mntpnt, *type, *opts, *freq, *passno, *cp;

	if ((cp = strchr(line, '#')))
		*cp = 0;	/* Ignore everything after the comment char */
	cp = line;

	device = parse_word(&cp);
	mntpnt = parse_word(&cp);
	type = parse_word(&cp);
	opts = parse_word(&cp);
	freq = parse_word(&cp);
	passno = parse_word(&cp);

	if (!device)
		return -1;	/* Allow blank lines */

	if (!mntpnt || !type)
		return -1;

	parse_escape(device);
	parse_escape(mntpnt);
	parse_escape(type);
	parse_escape(opts);
	parse_escape(freq);
	parse_escape(passno);

	dev = blkid_get_devname(cache, device, NULL);
	if (dev)
		device = dev;

	if (strchr(type, ','))
		type = 0;

	fs->device = string_copy(device);
	fs->mountpt = string_copy(mntpnt);
	fs->type = string_copy(type);
	fs->opts = string_copy(opts ? opts : "");
	fs->freq = freq ? atoi(freq) : -1;
	fs->passno = passno ? atoi(passno) : -1;
	fs->flags = 0;
	fs->next = NULL;

	free(dev);

	return 0;
}

static void free_fstab_line(struct fs_info *fs)
{
	if (fs->device)
		fs->device = 0;
	if (fs->mountpt)
		fs->mountpt = 0;
	if (fs->type)
		fs->type = 0;
	if (fs->opts)
		fs->opts = 0;
	memset(fs, 0, sizeof(struct fs_info));
}


static void PRS(int argc, char **argv)
{
	int c;

#ifdef ENABLE_NLS
	setlocale(LC_MESSAGES, "");
	setlocale(LC_CTYPE, "");
	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
	textdomain(NLS_CAT_NAME);
	set_com_err_gettext(gettext);
#endif

	while ((c = getopt(argc, argv, "rv")) != EOF) {
		switch (c) {
		case 'r':
			root_type++;
			break;

		case 'v':
			printf("%s %s (%s)\n", program_name,
			       E2FSPROGS_VERSION, E2FSPROGS_DATE);
			break;
		default:
			usage();
		}
	}
	if (optind < argc - 1 || optind == argc)
		usage();
	device_name = blkid_get_devname(NULL, argv[optind], NULL);
	if (!device_name) {
		com_err(program_name, 0, _("Unable to resolve '%s'"),
			argv[optind]);
		exit(1);
	}
}

static void get_root_type(ext2_filsys fs)
{
	errcode_t retval;
	struct mem_file file;
	char 		*buf;
	struct fs_info fs_info;
	int		ret;

	retval = get_file(fs, "/etc/fstab", &file);
	if (retval) {
		com_err(program_name, retval, "couldn't open /etc/fstab");
		exit(1);
	}

	while (!mem_file_eof(&file)) {
		buf = get_line(&file);
		if (!buf)
			continue;

		ret = parse_fstab_line(buf, &fs_info);
		if (ret < 0)
			goto next_line;

		if (!strcmp(fs_info.mountpt, "/"))
			printf("%s\n", fs_info.type);

		free_fstab_line(&fs_info);

	next_line:
		free(buf);
	}
}


int main (int argc, char ** argv)
{
	errcode_t retval;
	ext2_filsys fs;
	io_manager io_ptr;

	add_error_table(&et_ext2_error_table);

	blkid_get_cache(&cache, NULL);
	PRS(argc, argv);

#ifdef CONFIG_TESTIO_DEBUG
	if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
		io_ptr = test_io_manager;
		test_io_backing_manager = unix_io_manager;
	} else
#endif
		io_ptr = unix_io_manager;
	retval = ext2fs_open (device_name, open_flag, 0, 0, io_ptr, &fs);
        if (retval)
		exit(1);

	if (root_type)
		get_root_type(fs);

	remove_error_table(&et_ext2_error_table);
	return (ext2fs_close (fs) ? 1 : 0);
}
