/*
 * plausible.c --- Figure out if a pathname is ext* or something else.
 *
 * Copyright 2014, Oracle, Inc.
 *
 * Some parts are:
 * Copyright 1995, 1996, 1997, 1998, 1999, 2000 by Theodore Ts'o.
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the GNU Public
 * License.
 * %End-Header%
 */

#ifndef _LARGEFILE_SOURCE
#define _LARGEFILE_SOURCE
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif

#include "config.h"
#include <fcntl.h>
#include <time.h>
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_MAGIC_H
#include <magic.h>
#endif
#include "plausible.h"
#include "ext2fs/ext2fs.h"
#include "nls-enable.h"
#include "blkid/blkid.h"

#ifdef HAVE_MAGIC_H
static magic_t (*dl_magic_open)(int);
static const char *(*dl_magic_file)(magic_t, const char *);
static int (*dl_magic_load)(magic_t, const char *);
static void (*dl_magic_close)(magic_t);

#ifdef HAVE_DLOPEN
#include <dlfcn.h>

static void *magic_handle;

static int magic_library_available(void)
{
	if (!magic_handle) {
		magic_handle = dlopen("libmagic.so.1", RTLD_NOW);
		if (!magic_handle)
			return 0;

		dl_magic_open = (magic_t (*)(int))
			dlsym(magic_handle, "magic_open");
		dl_magic_file = (const char *(*)(magic_t, const char *))
			dlsym(magic_handle, "magic_file");
		dl_magic_load = (int (*)(magic_t, const char *))
			dlsym(magic_handle, "magic_load");
		dl_magic_close = (void (*)(magic_t))
			dlsym(magic_handle, "magic_close");
	}

	if (!dl_magic_open || !dl_magic_file ||
	    !dl_magic_load || !dl_magic_close)
		return 0;
	return 1;
}
#else
static int magic_library_available(void)
{
	dl_magic_open = magic_open;
	dl_magic_file = magic_file;
	dl_magic_load = magic_load;
	dl_magic_close = magic_close;

	return 1;
}
#endif
#endif

static void print_ext2_info(const char *device)

{
	struct ext2_super_block	*sb;
	ext2_filsys		fs;
	errcode_t		retval;
	time_t			tm;
	char			buf[80];

	retval = ext2fs_open2(device, 0, EXT2_FLAG_64BITS, 0, 0,
			      unix_io_manager, &fs);
	if (retval)
		return;
	sb = fs->super;

	if (sb->s_mtime) {
		tm = sb->s_mtime;
		if (sb->s_last_mounted[0]) {
			memset(buf, 0, sizeof(buf));
			strncpy(buf, sb->s_last_mounted,
				sizeof(sb->s_last_mounted));
			printf(_("\tlast mounted on %s on %s"), buf,
			       ctime(&tm));
		} else
			printf(_("\tlast mounted on %s"), ctime(&tm));
	} else if (sb->s_mkfs_time) {
		tm = sb->s_mkfs_time;
		printf(_("\tcreated on %s"), ctime(&tm));
	} else if (sb->s_wtime) {
		tm = sb->s_wtime;
		printf(_("\tlast modified on %s"), ctime(&tm));
	}
	ext2fs_close_free(&fs);
}

/*
 * return 1 if there is no partition table, 0 if a partition table is
 * detected, and -1 on an error.
 */
#ifdef HAVE_BLKID_PROBE_ENABLE_PARTITIONS
static int check_partition_table(const char *device)
{
	blkid_probe pr;
	const char *value;
	int ret;

	pr = blkid_new_probe_from_filename(device);
	if (!pr)
		return -1;

	ret = blkid_probe_enable_partitions(pr, 1);
	if (ret < 0)
		goto errout;

	ret = blkid_probe_enable_superblocks(pr, 0);
	if (ret < 0)
		goto errout;

	ret = blkid_do_fullprobe(pr);
	if (ret < 0)
		goto errout;

	ret = blkid_probe_lookup_value(pr, "PTTYPE", &value, NULL);
	if (ret == 0)
		fprintf(stderr, _("Found a %s partition table in %s\n"),
			value, device);
	else
		ret = 1;

errout:
	blkid_free_probe(pr);
	return ret;
}
#else
static int check_partition_table(const char *device EXT2FS_ATTR((unused)))
{
	return -1;
}
#endif

/*
 * return 1 if the device looks plausible, creating the file if necessary
 */
int check_plausibility(const char *device, int flags, int *ret_is_dev)
{
	int fd, ret, is_dev = 0;
	ext2fs_struct_stat s;
	int fl = O_RDONLY;
	blkid_cache cache = NULL;
	char *fs_type = NULL;
	char *fs_label = NULL;

	fd = ext2fs_open_file(device, fl, 0666);
	if ((fd < 0) && (errno == ENOENT) && (flags & NO_SIZE)) {
		fprintf(stderr, _("The file %s does not exist and no "
				  "size was specified.\n"), device);
		exit(1);
	}
	if ((fd < 0) && (errno == ENOENT) && (flags & CREATE_FILE)) {
		fl |= O_CREAT;
		fd = ext2fs_open_file(device, fl, 0666);
		if (fd >= 0 && (flags & VERBOSE_CREATE))
			printf(_("Creating regular file %s\n"), device);
	}
	if (fd < 0) {
		fprintf(stderr, _("Could not open %s: %s\n"),
			device, error_message(errno));
		if (errno == ENOENT)
			fputs(_("\nThe device apparently does not exist; "
				"did you specify it correctly?\n"), stderr);
		exit(1);
	}

	if (ext2fs_fstat(fd, &s) < 0) {
		perror("stat");
		exit(1);
	}
	close(fd);

	if (S_ISBLK(s.st_mode))
		is_dev = 1;
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
	/* On FreeBSD, all disk devices are character specials */
	if (S_ISCHR(s.st_mode))
		is_dev = 1;
#endif
	if (ret_is_dev)
		*ret_is_dev = is_dev;

	if ((flags & CHECK_BLOCK_DEV) && !is_dev) {
		printf(_("%s is not a block special device.\n"), device);
		return 0;
	}

	/*
	 * Note: we use the older-style blkid API's here because we
	 * want as much functionality to be available when using the
	 * internal blkid library, when e2fsprogs is compiled for
	 * non-Linux systems that will probably not have the libraries
	 * from util-linux available.  We only use the newer
	 * blkid-probe interfaces to access functionality not
	 * available in the original blkid library.
	 */
	if ((flags & CHECK_FS_EXIST) && blkid_get_cache(&cache, NULL) >= 0) {
		fs_type = blkid_get_tag_value(cache, "TYPE", device);
		if (fs_type)
			fs_label = blkid_get_tag_value(cache, "LABEL", device);
		blkid_put_cache(cache);
	}

	if (fs_type) {
		if (fs_label)
			printf(_("%s contains a %s file system "
				 "labelled '%s'\n"), device, fs_type, fs_label);
		else
			printf(_("%s contains a %s file system\n"), device,
			       fs_type);
		if (strncmp(fs_type, "ext", 3) == 0)
			print_ext2_info(device);
		free(fs_type);
		free(fs_label);
		return 0;
	}

#ifdef HAVE_MAGIC_H
	if ((flags & CHECK_FS_EXIST) &&
	    !getenv("E2FSPROGS_LIBMAGIC_SUPPRESS") &&
	    magic_library_available()) {
		const char *msg;
		magic_t mag;
		int has_magic = 0;

		mag = dl_magic_open(MAGIC_RAW | MAGIC_SYMLINK | MAGIC_DEVICES |
				    MAGIC_ERROR | MAGIC_NO_CHECK_ELF |
				    MAGIC_NO_CHECK_COMPRESS);
		dl_magic_load(mag, NULL);

		msg = dl_magic_file(mag, device);
		if (msg && strcmp(msg, "data") && strcmp(msg, "empty")) {
			printf(_("%s contains `%s' data\n"), device, msg);
			has_magic = 1;
		}

		dl_magic_close(mag);
		return !has_magic;
	}
#endif

	ret = check_partition_table(device);
	if (ret >= 0)
		return ret;

	return 1;
}

