/*
 * Copyright (c) 2003,2005 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 <xfs/libxfs.h>
#include <sys/stat.h>
#include <sys/disk.h>
#include <sys/mount.h>
#include <sys/ioctl.h>
#include <sys/sysctl.h>

int platform_has_uuid = 1;
extern char *progname;

int
platform_check_ismounted(char *name, char *block, struct stat64 *s, int verbose)
{
	struct stat64	st;
        int cnt, i;
        struct statfs *fsinfo;

	if (!s) {
		if (stat64(block, &st) < 0)
			return 0;
		s = &st;
	}

	/* Remember, FreeBSD can now mount char devices! -- adrian */
	if (((st.st_mode & S_IFMT) != S_IFBLK) &&
	    ((st.st_mode & S_IFMT) != S_IFCHR))
		return 0;

	if ((cnt = getmntinfo(&fsinfo, MNT_NOWAIT)) == 0) {
		fprintf(stderr,
		    _("%s: %s possibly contains a mounted filesystem\n"),
		    progname, name);
		return 1;
	}

        for (i = 0; i < cnt; i++) {
                if (strcmp (name, fsinfo[i].f_mntfromname) != 0)
			continue;

		if (verbose)
			fprintf(stderr,
			    _("%s: %s contains a mounted filesystem\n"),
			    progname, name);
		break;
	}

        return i < cnt;
}

int
platform_check_iswritable(char *name, char *block, struct stat64 *s, int fatal)
{
        int cnt, i;
        struct statfs *fsinfo;

        if ((cnt = getmntinfo(&fsinfo, MNT_NOWAIT)) == 0) {
		fprintf(stderr, _("%s: %s contains a possibly writable, "
				"mounted filesystem\n"), progname, name);
			return fatal;
	}

        for (i = 0; i < cnt; i++) {
                if (strcmp (name, fsinfo[i].f_mntfromname) != 0)
			continue;

		if (fsinfo[i].f_flags &= MNT_RDONLY)
			break;
	}

        if (i == cnt) {
		fprintf(stderr, _("%s: %s contains a mounted and writable "
				"filesystem\n"), progname, name);
		return fatal;
	}
	return 0;
}

int
platform_set_blocksize(int fd, char *path, dev_t device, int blocksize, int fatal)
{
	return fatal;
}

void
platform_flush_device(int fd, dev_t device)
{
	return;
}

void
platform_findsizes(char *path, int fd, long long *sz, int *bsz)
{
	struct stat	st;
	__int64_t	size;
	u_int		ssize;

	if (fstat(fd, &st) < 0) {
		fprintf(stderr, _("%s: "
			"cannot stat the device file \"%s\": %s\n"),
			progname, path, strerror(errno));
		exit(1);
	}

	if ((st.st_mode & S_IFMT) == S_IFREG) {
		*sz = (long long)(st.st_size >> 9);
		*bsz = 512;
		return;
	}

	if ((st.st_mode & S_IFMT) != S_IFCHR) {
		fprintf(stderr, _("%s: Not a device or file: \"%s\"\n"),
			progname, path);
		exit(1);
	}

	if (ioctl(fd, DIOCGMEDIASIZE, &size) != 0) {
		fprintf(stderr, _("%s: DIOCGMEDIASIZE failed on \"%s\": %s\n"),
			progname, path, strerror(errno));
		exit(1);
	}

	if (ioctl(fd, DIOCGSECTORSIZE, &ssize) != 0) {
		fprintf(stderr, _("%s: "
			"DIOCGSECTORSIZE failed on \"%s\": %s\n"),
			progname, path, strerror(errno));
		exit(1);
	}

	*sz = (long long) (size / ssize);
	*bsz = (int)ssize;
}

char *
platform_findrawpath(char *path)
{
	return path;
}

char *
platform_findblockpath(char *path)
{
	return path;
}

int
platform_direct_blockdev(void)
{
	return 0;
}

int
platform_align_blockdev(void)
{
	return sizeof(void *);
}

int
platform_nproc(void)
{
	int		ncpu;
	size_t		len = sizeof(ncpu);
	static int	mib[2] = {CTL_HW, HW_NCPU};

	if (sysctl(mib, 2, &ncpu, &len, NULL, 0) < 0)
		ncpu = 1;

	return ncpu;
}

unsigned long
platform_physmem(void)
{
	unsigned long	physmem;
	size_t		len = sizeof(physmem);
	static int	mib[2] = {CTL_HW, HW_PHYSMEM};

	if (sysctl(mib, 2, &physmem, &len, NULL, 0) < 0) {
		fprintf(stderr, _("%s: can't determine memory size\n"),
			progname);
		exit(1);
	}
	return physmem >> 10;
}
