/*********************************************************
 * Copyright (C) 1998 VMware, Inc. All rights reserved.
 *
 * This program 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 version 2.1 and no later version.
 *
 * This program 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 Lesser GNU General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
 *
 *********************************************************/

/*
 * file.h --
 *
 *	Interface to host file system and related utility functions.
 */

#ifndef _FILE_H_
#define _FILE_H_

#ifdef __cplusplus
extern "C"{
#endif

#include <stdio.h>
#define INCLUDE_ALLOW_USERLEVEL
#define INCLUDE_ALLOW_VMCORE
#include "includeCheck.h"

#include "fileIO.h"
#include "unicodeTypes.h"

#ifdef N_PLAT_NLM
#define FILE_MAXPATH	256
#elif defined(_WIN32)
#define FILE_MAXPATH	MAX_PATH
#else
# ifdef __FreeBSD__
#  include <sys/param.h> // For __FreeBSD_version
# endif
# if defined(__FreeBSD__)
#  include <sys/syslimits.h>  // PATH_MAX
# else 
#  include <limits.h>  // PATH_MAX
# endif 
#define FILE_MAXPATH	PATH_MAX
#endif

#define FILE_SEARCHPATHTOKEN ";"


/*
 * Opaque, platform-specific stucture for supporting the directory walking API.
 */

typedef struct WalkDirContextImpl WalkDirContextImpl;
typedef const WalkDirContextImpl *WalkDirContext;

/*
 * When File_MakeTempEx2 is called, it creates a temporary file or a directory
 * in a specified directory. File_MakeTempEx2 calls a user-specified callback
 * function to get the filename. Callback function should be of type
 * File_MakeTempCreateNameFunc.
 *
 * 'num' specifies nth time this function is called.
 *
 * 'data' specifies the payload that the user specified when executing
 * File_MakeTempEx2 function.
 *
 * If successful, this function should return a dynamically allocated string
 * with the filename.
 *
 * File_MakeTempEx2 frees the fileName after a successful call to this
 * function.
 *
 */

typedef Unicode File_MakeTempCreateNameFunc(int num,
                                            void *data);

#if defined(__APPLE__)
typedef enum {
   FILEMACOS_UNMOUNT_SUCCESS,
   FILEMACOS_UNMOUNT_SUCCESS_ALREADY,
   FILEMACOS_UNMOUNT_ERROR,
} FileMacosUnmountStatus;

EXTERN FileMacosUnmountStatus FileMacos_UnmountDev(char const *bsdDev,
                                                   Bool wholeDev,
                                                   Bool eject,
                                                   Bool su);

EXTERN void FileMacos_MountDevAsyncNoResult(char const *bsdDev,
                                            Bool su);

EXTERN Bool FileMacos_IsOnExternalDevice(int fd);
EXTERN Bool FileMacos_IsOnSparseDmg(int fd);
EXTERN Bool FileMacos_IsSliceDevice(char const *bsdDev);

EXTERN char *FileMacos_DiskDevToUserFriendlyName(char const *bsdDiskDev);

EXTERN char *FileMacos_DiskDeviceToUniqueID(char const *bsdPath);
EXTERN char *FileMacos_UniqueIDToDiskDevice(char const *identifier);
#elif defined VMX86_SERVER
EXTERN int File_GetVMFSBlockSize(ConstUnicode pathName, uint32 *blockSize);
EXTERN int File_GetVMFSMountInfo(ConstUnicode pathName,
                                 char **fsType,
                                 uint32 *version,
                                 char **remoteIP,
                                 char **remoteMountPoint,
                                 char **localMountPoint);
#endif

EXTERN Bool File_SupportsZeroedThick(ConstUnicode pathName);

EXTERN Bool File_Exists(ConstUnicode pathName);

EXTERN int File_Unlink(ConstUnicode pathName);

EXTERN int File_UnlinkIfExists(ConstUnicode pathName);

EXTERN int File_UnlinkDelayed(ConstUnicode pathName);

EXTERN int File_UnlinkNoFollow(ConstUnicode pathName);

EXTERN void File_SplitName(ConstUnicode pathName,
                           Unicode *volume, 
                           Unicode *dir, 
                           Unicode *base);

EXTERN void File_GetPathName(ConstUnicode fullPath, 
                             Unicode *pathName, 
                             Unicode *base);

EXTERN Unicode File_StripSlashes(ConstUnicode path);

EXTERN Unicode File_PathJoin(ConstUnicode dirName,
                             ConstUnicode baseName);

EXTERN Bool File_CreateDirectory(ConstUnicode pathName);
EXTERN Bool File_EnsureDirectory(ConstUnicode pathName);

EXTERN Bool File_DeleteEmptyDirectory(ConstUnicode pathName);

EXTERN Bool File_CreateDirectoryHierarchy(ConstUnicode pathName);

EXTERN Bool File_DeleteDirectoryTree(ConstUnicode pathName);

EXTERN int File_ListDirectory(ConstUnicode pathName,
                              Unicode **ids);

/*
 * Simple file-system walk.
 */

EXTERN WalkDirContext File_WalkDirectoryStart(ConstUnicode parentPath);
EXTERN Bool File_WalkDirectoryNext(WalkDirContext context,
                                   Unicode *path);
EXTERN void File_WalkDirectoryEnd(WalkDirContext context);

EXTERN Bool File_IsDirectory(ConstUnicode pathName);

EXTERN Bool File_IsFile(ConstUnicode pathName);

EXTERN Bool File_IsSymLink(ConstUnicode fileName);

EXTERN Bool File_IsCharDevice(ConstUnicode pathName);

EXTERN Bool File_IsRemote(ConstUnicode pathName);

EXTERN Bool File_IsEmptyDirectory(ConstUnicode pathName);

EXTERN Unicode File_Cwd(ConstUnicode drive); // XXX belongs to `process' module

EXTERN Unicode File_FullPath(ConstUnicode pathName);

EXTERN Bool File_IsFullPath(ConstUnicode pathName);

EXTERN uint64 File_GetFreeSpace(ConstUnicode pathName,
                                Bool doNotAscend);

EXTERN uint64 File_GetCapacity(ConstUnicode pathName);

/* Deprecated; use Util_GetSafeTmpDir if you can */
EXTERN char *File_GetTmpDir(Bool useConf);

/* Deprecated; use Util_MakeSafeTemp if you can */
EXTERN int File_MakeTemp(ConstUnicode tag,
                         Unicode *presult);

EXTERN int File_MakeTempEx(ConstUnicode dir,
                           ConstUnicode fileName,
                           Unicode *presult);

EXTERN int File_MakeTempEx2(ConstUnicode dir,
                            Bool createTempFile,
                            File_MakeTempCreateNameFunc *createNameFunc,
                            void *createFuncData,
                            Unicode *presult);

EXTERN int64 File_GetModTime(ConstUnicode pathName);

EXTERN char *File_GetModTimeString(ConstUnicode pathName);

EXTERN char *File_GetUniqueFileSystemID(const char *fileName);

EXTERN Bool File_GetTimes(ConstUnicode pathName,
                          VmTimeType *createTime,
                          VmTimeType *accessTime,
                          VmTimeType *writeTime,
                          VmTimeType *attrChangeTime);

EXTERN Bool File_SetTimes(ConstUnicode pathName,
                          VmTimeType createTime,
                          VmTimeType accessTime,
                          VmTimeType writeTime,
                          VmTimeType attrChangeTime);

EXTERN Bool File_GetFilePermissions(ConstUnicode pathName,
                                   int *mode);

EXTERN Bool File_SetFilePermissions(ConstUnicode pathName,
                                    int mode);

EXTERN Bool File_SupportsFileSize(ConstUnicode pathName,
                                  uint64 fileSize);

EXTERN Bool File_SupportsLargeFiles(ConstUnicode pathName);

EXTERN char *File_MapPathPrefix(const char *oldPath,
                                const char **oldPrefixes,
                                const char **newPrefixes,
                                size_t numPrefixes);

EXTERN Bool File_CopyFromFdToFd(FileIODescriptor src, 
                                FileIODescriptor dst);

EXTERN FileIOResult File_CreatePrompt(FileIODescriptor *file, 
                                      ConstUnicode pathName, 
                                      int access, 
                                      int prompt);

EXTERN Bool File_CopyFromFd(FileIODescriptor src, 
                            ConstUnicode dstName, 
                            Bool overwriteExisting);

EXTERN Bool File_Copy(ConstUnicode srcName, 
                      ConstUnicode dstName, 
                      Bool overwriteExisting);

EXTERN Bool File_CopyFromFdToName(FileIODescriptor src, 
                                  ConstUnicode dstName, 
                                  int dstDispose);

EXTERN Bool File_CopyFromNameToName(ConstUnicode srcName, 
                                    ConstUnicode dstName, 
                                    int dstDispose);

EXTERN Bool File_Replace(ConstUnicode oldFile, 
                         ConstUnicode newFile);

EXTERN Bool File_Rename(ConstUnicode oldFile, 
                        ConstUnicode newFile);

EXTERN int64 File_GetSize(ConstUnicode pathName);

EXTERN int64 File_GetSizeByPath(ConstUnicode pathName);

EXTERN int64 File_GetSizeAlternate(ConstUnicode pathName);

/* file change notification module */
typedef void (*CbFunction)(void *clientData);

typedef void (*NotifyCallback)(ConstUnicode pathName, 
                               int err, 
                               void *data);

typedef void (*PollTimeout) (CbFunction f,
                             void *clientData,
                             int delay);

typedef void (*PollRemoveTimeout) (CbFunction f,
                                   void *clientData);

EXTERN void File_PollInit(PollTimeout pt, 
                          PollRemoveTimeout prt);

EXTERN void File_PollExit(void);

EXTERN void File_PollImpersonateOnCheck(Bool check);

EXTERN Bool File_PollAddFile(ConstUnicode pathName, 
                             uint32 pollPeriod, 
                             NotifyCallback callback, 
                             void *data, 
                             Bool fPeriodic);

EXTERN Bool File_PollAddDirFile(ConstUnicode pathName,
                                uint32 pollPeriod, 
                                NotifyCallback callback,
                                void *data, 
                                Bool fPeriodic);

EXTERN Bool File_PollRemoveFile(ConstUnicode pathName, 
                                uint32 pollPeriod,
                                NotifyCallback callback);

EXTERN Bool File_IsSameFile(ConstUnicode path1,
                            ConstUnicode path2);

EXTERN char *File_PrependToPath(const char *searchPath,
                                const char *elem);

EXTERN Bool File_FindFileInSearchPath(const char *file,
                                      const char *searchPath,
                                      const char *cwd,
                                      char **result);

EXTERN Unicode File_ReplaceExtension(ConstUnicode pathName,
                                     ConstUnicode newExtension,
                                     uint32 numExtensions,
                                     ...);

EXTERN Bool File_MakeCfgFileExecutable(ConstUnicode pathName);

EXTERN char *File_ExpandAndCheckDir(const char *dirName);

#ifdef __cplusplus
} // extern "C" {
#endif

#endif // ifndef _FILE_H_
