/*****************************************************************************
 *                                                                           *
 * DH_FILE.C                                                                 *
 *                                                                           *
 * Freely redistributable and modifiable.  Use at your own risk.             *
 *                                                                           *
 * Copyright 1994 The Downhill Project                                       *
 *                                                                           *
 *****************************************************************************/


/* Include stuff *************************************************************/
#include "INCLUDE/DH.H"
#include <utime.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>


/* Function stuff ************************************************************/

/* Read info about a link ================================================== */
#if (_DOWNHILL_POSIX_SOURCE == 0)
int readlink(char* file_Name,char* buf_Mem,int buf_Size)
{
	/* See if the file exists */
	if (access(file_Name,X_OK) == -1)
	{
		errno = ENOENT;
	}
	else
	{
		errno = EINVAL;
	}

	/* Either way, it's not a link */	
	return -1;
}
#endif

/* Set the time of a file ================================================== */
#if (_DOWNHILL_POSIX_SOURCE == 0)
int utimes(char* file_Name,struct timeval file_Time[])
{
	struct utimbuf file_Utime;

	/* Fill out the structure */
	file_Utime.actime = file_Time[0].tv_sec;
	file_Utime.modtime = file_Time[1].tv_sec;

	/* And call utime() */
	return utime(file_Name,&file_Utime);
}
#endif

/* Change the ownership of a file ========================================== */
int chown(char* file_Name,uid_t file_User,gid_t file_Group)
{
	/* Pretend we did something */
	return 0;
}

/* Change the ownership of a file descriptor =============================== */
#if (_DOWNHILL_POSIX_SOURCE == 0)
int fchown(int file_Fd,uid_t file_User,gid_t file_Group)
{
	/* Pretend we did something */
	return 0;
}
#endif

/* Create a Downhill_File_Stat structure from a _stat structure ============ */
static void downhill_Stat_Create(struct Downhill_File_Stat* file_Info,
             struct _stat* file_InfoReal)
{
	file_Info->st_dev = file_InfoReal->st_dev;
	file_Info->st_ino = file_InfoReal->st_ino;
	file_Info->st_mode = file_InfoReal->st_mode;
	file_Info->st_nlink = file_InfoReal->st_nlink;
	file_Info->st_uid = Downhill_User_IdReal;
	file_Info->st_gid = Downhill_Group_IdReal;
	file_Info->st_rdev = file_InfoReal->st_rdev;
	file_Info->st_size = file_InfoReal->st_size;
	file_Info->st_atime = file_InfoReal->st_atime;
	file_Info->st_mtime = file_InfoReal->st_mtime;
	file_Info->st_ctime = file_InfoReal->st_ctime;
#if (_DOWNHILL_POSIX_SOURCE == 0)
	file_Info->st_blksize = _DOWNHILL_STAT_BLOCKSIZE;
#endif
}

/* Stat a file ============================================================= */
int Downhill_File_Stat(char* file_Name,struct Downhill_File_Stat* file_Info)
{
	struct _stat file_InfoReal;

	/* Get the stat information */
	if (_stat(file_Name,&file_InfoReal) != 0)
	{
		return -1;
	}

	/* Fill in the structure */
	downhill_Stat_Create(file_Info,&file_InfoReal);

	return 0;
}

/* Stat a file descriptor ================================================== */
int Downhill_File_StatFd(int file_Fd,struct Downhill_File_Stat* file_Info)
{
	struct _stat file_InfoReal;

	/* Get the fstat information */
	if (_fstat(file_Fd,&file_InfoReal) != 0)
	{
		return -1;
	}

	/* Fill in the structure */
	downhill_Stat_Create(file_Info,&file_InfoReal);

	return 0;
}

/* Stat a file or a symlink ================================================ */
#if (_DOWNHILL_POSIX_SOURCE == 0)
int lstat(char* file_Path,struct stat* file_Stat)
{
	/* It can't be a link, so just stat file */
	return stat(file_Path,file_Stat);
}
#endif

/* Set the host file status ================================================ */
#if (_DOWNHILL_POSIX_SOURCE == 0)
int sethostent(int host_Stayopen)
{
	return 0;
}
#endif

/* Close the host file ===================================================== */
#if (_DOWNHILL_POSIX_SOURCE == 0)
int endhostent(void)
{
	return 0;
}
#endif

/* Truncate an open file =================================================== */
#if (_DOWNHILL_POSIX_SOURCE == 0)
int ftruncate(int file_Fd,off_t file_Size)
{
	return chsize(file_Fd,file_Size);
}
#endif

/* Truncate a file ========================================================= */
#if (_DOWNHILL_POSIX_SOURCE == 0)
int truncate(char* file_Name,off_t file_Size)
{
	int file_Fd;
	int truncate_Result;

	file_Fd = open(file_Name,O_WRONLY);
	if (file_Fd == -1)
	{
		return -1;
	}
	truncate_Result = ftruncate(file_Fd,file_Size);
	close(file_Fd);

	return truncate_Result;
}
#endif
