/*
 * lstat.c - Get information about a SAMFS file.
 *
 */

/*
 *    SAM-QFS_notice_begin
 *
 *      Solaris 2.x Sun Storage & Archiving Management File System
 *
 *		Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
 *
 *		U.S. Government Rights - Commercial software. Government users are
 *	subject to the Sun Microsystems, Inc. standard license agreement and applicable
 *	provisions of the FAR and its supplements.
 *
 *      	Use is subject to license terms. Sun, Sun Microsystems and the Sun logo
 *	are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S.
 *	and other countries.
 *
 *    SAM-QFS_notice_end
 */

/*
 *	LGPL NOTICE
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#pragma ident "$Revision$"


/* Feature test switches. */
	/* None. */

/* ANSI C headers. */
	/* None. */

/*
 * POSIX headers.
 */
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>

/* Solaris headers. */
	/* None. */

/*
 * SAM-FS headers.
 */
#ifdef	linux
#include "sam/linux_types.h"
#endif	/* linux */
#include "pub/stat.h"
#include "sam/syscall.h"
#include "sam/lib.h"

/* Local headers. */
	/* None. */

/* Macros. */
	/* None. */

/* Types. */
	/* None. */

/* Structures. */
	/* None. */

/* Private data. */
	/* None. */

/* Private functions. */
	/* None. */

/* Public data. */
	/* None. */

/* Function macros. */
	/* None. */

/* Signal catching functions. */
	/* None. */


int
sam_lstat(
const char *path,
struct sam_stat *buf,
size_t bufsize)
{
#ifdef sun
#define	L_STAT stat64
#else
#define	L_STAT stat
#endif
	struct L_STAT stat_buf;
	int err;
	struct sam_stat_arg arg;

	memset(&arg, 0, sizeof (arg));
	arg.path.ptr = (char *)path;
	arg.buf.ptr = buf;
	arg.bufsize = bufsize;
	err = sam_syscall(SC_lstat, &arg, sizeof (arg));

	/*
	 * if not ours, or samfs not loaded, do regular stat
	 */

	if (err && (errno == ENOSYS || errno == ENOPKG)) {
		memset(buf, 0, sizeof (struct sam_stat));
		err = L_STAT(path, &stat_buf);
		if (!err) {
			buf->st_mode = stat_buf.st_mode;
			buf->st_ino = stat_buf.st_ino;
			buf->st_dev = stat_buf.st_dev;
			buf->st_nlink = stat_buf.st_nlink;
			buf->st_uid = stat_buf.st_uid;
			buf->st_gid = stat_buf.st_gid;
			buf->st_size = stat_buf.st_size;
#if (defined(SUSE_LINUX) && (KERNEL_MAJOR < 5)) || (defined(RHE_LINUX) && (KERNEL_MAJOR == 4) && (KERNEL_MINOR < 19))
			buf->st_atime = stat_buf.st_atime;
			buf->st_mtime = stat_buf.st_mtime;
			buf->st_ctime = stat_buf.st_ctime;
#else
			buf->st_atime = stat_buf.st_atim.tv_sec;
			buf->st_mtime = stat_buf.st_mtim.tv_sec;
			buf->st_ctime = stat_buf.st_ctim.tv_sec;
#endif
			buf->rdev = stat_buf.st_rdev;
			buf->st_blocks = stat_buf.st_blocks;
		}
	}
	return (err);
}
