/*
 * Copyright (c) 2005-2006 Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <paths.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "path.h"
#include "input.h"
#include "project.h"
#include <limits.h>

extern char *progname;

int fs_count;
int xfs_fs_count;
struct fs_path *fs_table;
struct fs_path *fs_path;

char *mtab_file;
#define PROC_MOUNTS	"/proc/self/mounts"

static int
fs_device_number(
	const char	*name,
	dev_t		*devnum)
{
	struct stat	sbuf;

	if (stat(name, &sbuf) < 0)
		return errno;
	/*
	 * We want to match st_rdev if the path provided is a device
	 * special file.  Otherwise we are looking for the the
	 * device id for the containing filesystem, in st_dev.
	 */
	if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode))
		*devnum = sbuf.st_rdev;
	else
		*devnum = sbuf.st_dev;

	return 0;
}

/*
 * Find the FS table entry for the given path.  The "flags" argument
 * is a mask containing FS_MOUNT_POINT or FS_PROJECT_PATH (or both)
 * to indicate the type of table entry sought.
 */
struct fs_path *
fs_table_lookup(
	const char	*dir,
	uint		flags)
{
	uint		i;
	dev_t		dev = 0;

	if (fs_device_number(dir, &dev))
		return NULL;

	for (i = 0; i < fs_count; i++) {
		if (flags && !(flags & fs_table[i].fs_flags))
			continue;
		if (fs_table[i].fs_datadev == dev)
			return &fs_table[i];
	}
	return NULL;
}

static int
fs_table_insert(
	char		*dir,
	uint		prid,
	uint		flags,
	char		*fsname,
	char		*fslog,
	char		*fsrt)
{
	dev_t		datadev, logdev, rtdev;
	struct fs_path	*tmp_fs_table;
	int		error;

	datadev = logdev = rtdev = 0;
	error = fs_device_number(dir, &datadev);
	if (error)
		goto out_nodev;
	if (fslog) {
		error = fs_device_number(fslog, &logdev);
		if (error)
			goto out_nodev;
	}
	if (fsrt) {
		error = fs_device_number(fsrt, &rtdev);
		if (error)
			goto out_nodev;
	}

	if (!platform_test_xfs_path(dir))
		flags |= FS_FOREIGN;

	/*
	 * Make copies of the directory and data device path.
	 * The log device and real-time device, if non-null,
	 * are already the result of strdup() calls so we
	 * don't need to duplicate those.  In fact, this
	 * function is assumed to "consume" both of those
	 * pointers, meaning if an error occurs they will
	 * both get freed.
	 */
	error = ENOMEM;
	dir = strdup(dir);
	if (!dir)
		goto out_nodev;
	fsname = strdup(fsname);
	if (!fsname)
		goto out_noname;

	tmp_fs_table = realloc(fs_table, sizeof(fs_path_t) * (fs_count + 1));
	if (!tmp_fs_table)
		goto out_norealloc;
	fs_table = tmp_fs_table;

	/* Put foreign filesystems at the end, xfs filesystems at the front */
	if (flags & FS_FOREIGN || fs_count == 0) {
		fs_path = &fs_table[fs_count];
	} else {
		/* move foreign fs entries down, insert new one just before */
		memmove(&fs_table[xfs_fs_count + 1], &fs_table[xfs_fs_count],
			sizeof(fs_path_t)*(fs_count - xfs_fs_count));
		fs_path = &fs_table[xfs_fs_count];
	}
	fs_path->fs_dir = dir;
	fs_path->fs_prid = prid;
	fs_path->fs_flags = flags;
	fs_path->fs_name = fsname;
	fs_path->fs_log = fslog;
	fs_path->fs_rt = fsrt;
	fs_path->fs_datadev = datadev;
	fs_path->fs_logdev = logdev;
	fs_path->fs_rtdev = rtdev;
	fs_count++;
	if (!(flags & FS_FOREIGN))
		xfs_fs_count++;

	return 0;

out_norealloc:
	free(fsname);
out_noname:
	free(dir);
out_nodev:
	/* "Consume" fslog and fsrt even if there's an error */
	free(fslog);
	free(fsrt);

	return error;
}

/*
 * Table iteration (cursor-based) interfaces
 */

/*
 * Initialize an fs_table cursor.  If a directory path is supplied,
 * the cursor is set up to appear as though the table contains only
 * a single entry which represents the directory specified.
 * Otherwise it is set up to prepare for visiting all entries in the
 * global table, starting with the first.  "flags" can be either
 * FS_MOUNT_POINT or FS_PROJECT_PATH to limit what type of entries
 * will be selected by fs_cursor_next_entry().  0 can be used as a
 * wild card (selecting either type).
 */
void
fs_cursor_initialise(
	char		*dir,
	uint		flags,
	fs_cursor_t	*cur)
{
	fs_path_t	*path;

	memset(cur, 0, sizeof(*cur));
	if (dir) {
		if ((path = fs_table_lookup(dir, flags)) == NULL)
			return;
		cur->local = *path;
		cur->count = 1;
		cur->table = &cur->local;
	} else {
		cur->count = fs_count;
		cur->table = fs_table;
	}
	cur->flags = flags;
}

/*
 * Use the cursor to find the next entry in the table having the
 * type specified by the cursor's "flags" field.
 */
struct fs_path *
fs_cursor_next_entry(
	fs_cursor_t	*cur)
{
	while (cur->index < cur->count) {
		fs_path_t	*next = &cur->table[cur->index++];

		if (!cur->flags || (cur->flags & next->fs_flags))
			return next;
	}
	return NULL;
}


#if defined(HAVE_GETMNTENT)
#include <mntent.h>

/*
 * Determines whether the "logdev" or "rtdev" mount options are
 * present for the given mount point.  If so, the value for each (a
 * device path) is returned in the pointers whose addresses are
 * provided.  The pointers are assigned NULL for an option not
 * present.  Note that the path buffers returned are allocated
 * dynamically and it is the caller's responsibility to free them.
 */
static int
fs_extract_mount_options(
	struct mntent	*mnt,
	char		**logp,
	char		**rtp)
{
	char		*fslog, *fsrt;

	/*
	 * Extract log device and realtime device from mount options.
	 *
	 * Note: the glibc hasmntopt implementation requires that the
	 * character in mnt_opts immediately after the search string
	 * must be a NULL ('\0'), a comma (','), or an equals ('=').
	 * Therefore we cannot search for 'logdev=' directly.
	 */
	if ((fslog = hasmntopt(mnt, "logdev")) && fslog[6] == '=')
		fslog += 7;
	if ((fsrt = hasmntopt(mnt, "rtdev")) && fsrt[5] == '=')
		fsrt += 6;

	/* Do this only after we've finished processing mount options */
	if (fslog) {
		fslog = strndup(fslog, strcspn(fslog, " ,"));
		if (!fslog)
			goto out_nomem;
	}
	if (fsrt) {
		fsrt = strndup(fsrt, strcspn(fsrt, " ,"));
		if (!fsrt) {
			free(fslog);
			goto out_nomem;
		}
	}
	*logp = fslog;
	*rtp = fsrt;

	return 0;

out_nomem:
	*logp = NULL;
	*rtp = NULL;
	fprintf(stderr, _("%s: unable to extract mount options for \"%s\"\n"),
		progname, mnt->mnt_dir);
	return ENOMEM;
}

/*
 * If *path is NULL, initialize the fs table with all xfs mount points in mtab
 * If *path is specified, search for that path in mtab
 *
 * Everything - path, devices, and mountpoints - are boiled down to realpath()
 * for comparison, but fs_table is populated with what comes from getmntent.
 */
static int
fs_table_initialise_mounts(
	char		*path)
{
	struct mntent	*mnt;
	FILE		*mtp;
	char		*fslog, *fsrt;
	int		error, found;
	char		rpath[PATH_MAX], rmnt_fsname[PATH_MAX], rmnt_dir[PATH_MAX];

	error = found = 0;
	fslog = fsrt = NULL;

	if (!mtab_file) {
		mtab_file = PROC_MOUNTS;
		if (access(mtab_file, R_OK) != 0)
			mtab_file = MOUNTED;
	}

	if ((mtp = setmntent(mtab_file, "r")) == NULL)
		return ENOENT;

	/* Use realpath to resolve symlinks, relative paths, etc */
	if (path)
		if (!realpath(path, rpath))
			return errno;

	while ((mnt = getmntent(mtp)) != NULL) {
		if (!realpath(mnt->mnt_dir, rmnt_dir))
			continue;
		if (!realpath(mnt->mnt_fsname, rmnt_fsname))
			continue;

		if (path &&
		    ((strcmp(rpath, rmnt_dir) != 0) &&
		     (strcmp(rpath, rmnt_fsname) != 0)))
			continue;
		if (fs_extract_mount_options(mnt, &fslog, &fsrt))
			continue;
		(void) fs_table_insert(mnt->mnt_dir, 0, FS_MOUNT_POINT,
					mnt->mnt_fsname, fslog, fsrt);
		if (path) {
			found = 1;
			break;
		}
	}
	endmntent(mtp);

	if (path && !found)
		error = ENXIO;

	return error;
}

#elif defined(HAVE_GETMNTINFO)
#include <sys/mount.h>

/*
 * If *path is NULL, initialize the fs table with all xfs mount points in mtab
 * If *path is specified, search for that path in mtab
 *
 * Everything - path, devices, and mountpoints - are boiled down to realpath()
 * for comparison, but fs_table is populated with what comes from getmntinfo.
 */
static int
fs_table_initialise_mounts(
	char		*path)
{
	struct statfs	*stats;
	int		i, count, error, found;
	char		rpath[PATH_MAX], rmntfromname[PATH_MAX], rmntonname[PATH_MAX];

	error = found = 0;
	if ((count = getmntinfo(&stats, 0)) < 0) {
		fprintf(stderr, _("%s: getmntinfo() failed: %s\n"),
				progname, strerror(errno));
		return 0;
	}

	/* Use realpath to resolve symlinks, relative paths, etc */
	if (path)
		if (!realpath(path, rpath))
			return errno;

	for (i = 0; i < count; i++) {
		if (!realpath(stats[i].f_mntfromname, rmntfromname))
			continue;
		if (!realpath(stats[i].f_mntonname, rmntonname))
			continue;

		if (path &&
		    ((strcmp(rpath, rmntonname) != 0) &&
		     (strcmp(rpath, rmntfromname) != 0)))
			continue;
		/* TODO: external log and realtime device? */
		(void) fs_table_insert(stats[i].f_mntonname, 0,
					FS_MOUNT_POINT, stats[i].f_mntfromname,
					NULL, NULL);
		if (path) {
			found = 1;
			break;
		}
	}
	if (path && !found)
		error = ENXIO;

	return error;
}

#else
# error "How do I extract info about mounted filesystems on this platform?"
#endif

/*
 * Given a directory, match it up to a filesystem mount point.
 */
static struct fs_path *
fs_mount_point_from_path(
	const char	*dir)
{
	fs_cursor_t	cursor;
	fs_path_t	*fs;
	dev_t		dev = 0;

	if (fs_device_number(dir, &dev))
		return NULL;

	fs_cursor_initialise(NULL, FS_MOUNT_POINT, &cursor);
	while ((fs = fs_cursor_next_entry(&cursor))) {
		if (fs->fs_datadev == dev)
			break;
	}
	return fs;
}

static void
fs_table_insert_mount(
	char		*mount)
{
	int		error;

	error = fs_table_initialise_mounts(mount);
	if (error)
		fprintf(stderr, _("%s: cannot setup path for mount %s: %s\n"),
			progname, mount, strerror(error));
}

static int
fs_table_initialise_projects(
	char		*project)
{
	fs_project_path_t *path;
	fs_path_t	*fs;
	prid_t		prid = 0;
	int		error = 0, found = 0;

	if (project)
		prid = prid_from_string(project);

	setprpathent();
	while ((path = getprpathent()) != NULL) {
		if (project && prid != path->pp_prid)
			continue;
		fs = fs_mount_point_from_path(path->pp_pathname);
		if (!fs) {
			fprintf(stderr, _("%s: cannot find mount point for path `%s': %s\n"),
					progname, path->pp_pathname, strerror(errno));
			continue;
		}
		(void) fs_table_insert(path->pp_pathname, path->pp_prid,
					FS_PROJECT_PATH, fs->fs_name,
					NULL, NULL);
		if (project) {
			found = 1;
			break;
		}
	}
	endprpathent();

	if (project && !found)
		error = ENOENT;

	return error;
}

static void
fs_table_insert_project(
	char		*project)
{
	int		error;

	error = fs_table_initialise_projects(project);
	if (error)
		fprintf(stderr, _("%s: cannot setup path for project %s: %s\n"),
			progname, project, strerror(error));
}

/*
 * Initialize fs_table to contain the given set of mount points and
 * projects.  If mount_count is zero, mounts is ignored and the
 * table is populated with mounted filesystems.  If project_count is
 * zero, projects is ignored and the table is populated with all
 * projects defined in the projects file.
 */
void
fs_table_initialise(
	int	mount_count,
	char	*mounts[],
	int	project_count,
	char	*projects[])
{
	int	error;
	int	i;

	if (mount_count) {
		for (i = 0; i < mount_count; i++)
			fs_table_insert_mount(mounts[i]);
	} else {
		error = fs_table_initialise_mounts(NULL);
		if (error)
			goto out_error;
	}
	if (project_count) {
		for (i = 0; i < project_count; i++)
			fs_table_insert_project(projects[i]);
	} else {
		error = fs_table_initialise_projects(NULL);
		if (error)
			goto out_error;
	}

	return;

out_error:
	fprintf(stderr, _("%s: cannot initialise path table: %s\n"),
		progname, strerror(error));
}

void
fs_table_insert_project_path(
	char		*dir,
	prid_t		prid)
{
	fs_path_t	*fs;
	int		error = 0;

	fs = fs_mount_point_from_path(dir);
	if (fs)
		error = fs_table_insert(dir, prid, FS_PROJECT_PATH,
					fs->fs_name, NULL, NULL);
	else
		error = ENOENT;

	if (error) {
		fprintf(stderr, _("%s: cannot setup path for project dir %s: %s\n"),
				progname, dir, strerror(error));
		exit(1);
	}
}
