
#ifndef	__FILE_UTIL_H
#define	__FILE_UTIL_H	__FILE_UTIL_H

#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <x_types.h>
#include <string.h>
#if defined(HAVE_FNMATCH_H) && defined(HAVE_FNMATCH)
#include <fnmatch.h>
#endif

#ifndef	O_BINARY
#define	O_BINARY	0
#endif

typedef	enum	_x_type	{
  TypeReal64, TypeReal32, TypeInt32, TypeUns32,
  TypeInt16, TypeUns16, TypeUChar, TypeSChar,
  TypeReal64PTR, TypeReal32PTR, TypeInt32PTR, TypeUns32PTR,
  TypeInt16PTR, TypeUns16PTR, TypeUCharPTR, TypeSCharPTR
}	X_Type;

typedef	struct _param_file_entry {
  void		*entry_ptr;
  Uns32		*num_entries;  
  UChar		*pattern;
  X_Type	type;
} ParamFileEntry;

typedef struct _find_params {
  UChar		**excl_dirs;
  UChar		**names;
  UChar		**excl_names;
  Uns32		options;
  time_t	newer_than;
  time_t	older_than;
  Int32		(*errfunc)(UChar *, void *);
  void		*errfunc_param;
  UChar		*excl_filename;
} FindParams;

#define	FIND_NO_DIRS		1
#define	FIND_NO_FILES		(FIND_NO_DIRS << 1)
#define	FIND_NO_SLINKS		(FIND_NO_DIRS << 2)
#define	FIND_NO_CDEVS		(FIND_NO_DIRS << 3)
#define	FIND_NO_BDEVS		(FIND_NO_DIRS << 4)
#define	FIND_NO_FIFOS		(FIND_NO_DIRS << 5)
#define	FIND_NO_SOCKS		(FIND_NO_DIRS << 6)
#define	FIND_FOLLOW_SLINKS	(FIND_NO_DIRS << 7)
#define	FIND_LOCAL_DEV		(FIND_NO_DIRS << 8)

#define	FIND_ONLY_DIRS		(FIND_NO_FILES | FIND_NO_SLINKS	\
				| FIND_NO_CDEVS | FIND_NO_BDEVS \
				| FIND_NO_FIFOS | FIND_NO_SOCKS)

#ifdef	__cplusplus
extern	"C"	{
#endif

extern	Int32	save_insert(UChar *, UChar *,
				Int32 (*)(FILE *, void *), void *);
extern	Int32	read_param_file(UChar *, ParamFileEntry *, Int32,
				UChar *, UChar *);
extern	Int32	sscanXValue(UChar *, void *, X_Type, Int32 *);
extern	Int32	fscanXValue(FILE *, void *, X_Type, Int32 *);
extern	UChar	*find_program(UChar *);
extern	Int32	cleanpath(UChar *);
extern	Int32	cleanpath__(UChar *);
extern	UChar	*mkabspath(UChar *, UChar *);
extern	UChar	*resolvepath(UChar *, UChar *);
extern	UChar	*resolvepath__(UChar *, UChar *);
extern	Int32	find1(UChar *, FindParams *, Int32 (*)(UChar *, void *),
			void *);
extern	Int32	find(UChar **, FindParams *, Int32 (*)(UChar *, void *),
			void *);
extern	UChar	**fnglob1(UChar *);
extern	UChar	**fnglob(UChar *);
extern	Int32	copy_file(UChar *, UChar *);

#ifdef	__cplusplus
}
#endif

#ifdef	unix

#define	FN_DIRSEPCHR		'/'
#define	FN_DIRSEPSTR		"/"
#define	FN_PARENTDIR		".."
#define	FN_ISPATH(s)		(strchr((s), FN_DIRSEPCHR))
#define	FN_ISABSPATH(s)		(*(s) == FN_DIRSEPCHR)
#define	FN_LASTDIRDELIM(s)	(strrchr((s), FN_DIRSEPCHR))
#define	FN_BASENAME(s)		(strrchr((s), FN_DIRSEPCHR) ? 		\
				(UChar *) strrchr((s), FN_DIRSEPCHR) + 1 : (s))
#define	FN_STRDBLDIRSEP(s)	(strstr((s), "//"))
#define	FN_STREMPTYDIRSEP(s)	(strstr((s), "/./"))
#define	FN_ISDIRSEP(c)		((c) == FN_DIRSEPCHR)
#define	FN_ISROOTDIR(s)		(FN_ISDIRSEP(*(s)) && ! *((s) + 1))
#define	FN_LEADINGDUMMY(s)	(*(s) == '.' && FN_ISDIRSEP(*((s) + 1)))
#define	FN_TRAILINGDUMMY(s)	(strlen(s) >= 2 &&	\
				*((s) + strlen(s) - 1) == '.' &&	\
				FN_ISDIRSEP(*((s) + strlen(s) - 2)))
#define	FN_FIRSTDIRSEP(s)	(strchr((s), FN_DIRSEPCHR))

#define	ENV_PATHSEPCHR		':'

#define	NULLFILE		"/dev/null"

#endif	/* defined(unix) */

#ifdef	WINDOWS_LIKE

#define	FN_DIRSEPCHR		'\\'
#define	FN_DIRSEPSTR		"\\"
#define	FN_PARENTDIR		".."
#define	FN_ISDIRSEP(c)	((c) == '/' || (c) == '\\')
#define	FN_ISPATH(s)	(strchr((s), '\\') || strchr((s), '/') ||	\
				(isalpha(*(s)) && *((s) + 1) == ':'))
#define	FN_ISABSPATH(s)	(FN_ISDIRSEP(*(s)) ||				\
				(isalpha(*(s)) && *((s) + 1) == ':' &&	\
				FN_ISDIRSEP(*((s) + 2))))
#define	FN_LASTDIRDELIM(s)	(strrchr(s, '/') ? strrchr(s, '/') :	\
				(strrchr(s, '\\') ? strrchr(s, '\\') :	\
				(isalpha(*(s)) && *((s) + 1) == ':') ?	\
				s + 2 : NULL))
#define	FN_BASENAME(s)	(strrchr(s, '/') ? strrchr(s, '/') + 1 :	\
			(strrchr(s, '\\') ? strrchr(s, '\\') + 1 :	\
			(isalpha(*(s)) && *((s) + 1) == ':') ? s + 2 : (s)))
#define	FN_STRDBLDIRSEP(s)						\
		(strstr((s), "//") ? strstr((s), "//") : strstr((s), "\\\\"))
#define	FN_STREMPTYDIRSEP(s)	(strstr((s), "/./") ? strstr((s), "/./") : \
				(strstr((s), "/.\\") ? strstr((s), "/.\\") : \
				(strstr((s), "\\./") ? strstr((s), "\\./") : \
				strstr((s), "\\.\\"))))
#define	FN_ISROOTDIR(s)	((FN_ISDIRSEP(*(s)) && ! *((s) + 1)) ||		\
				(isalpha(*(s)) && *((s) + 1) == ':'	\
				&& FN_ISDIRSEP(*((s) + 2)) && ! *((s) + 3)))
#define	FN_LEADINGDUMMY(s)	(*(s) == '.' && FN_ISDIRSEP(*((s) + 1)))
#define	FN_TRAILINGDUMMY(s)	(strlen(s) >= 2 &&	\
				*((s) + strlen(s) - 1) == '.' &&	\
				FN_ISDIRSEP(*((s) + strlen(s) - 2)))
#define	FN_FIRSTDIRSEP(s)	(strchr((s), '/') ? strchr((s), '/') :	\
					strchr((s), '\\'))

#define	ENV_PATHSEPCHR		';'

#define	NULLFILE		"nul"

#endif	/* defined(WINDOWS_LIKE) */

#endif	/* ! __FILE_UTIL_H */

/* THE FOLLOWING IS: fnmatch stuff */
#if !defined(HAVE_FNMATCH_H) || !defined(HAVE_FNMATCH)
#ifndef	_FNMATCH_H

#define	_FNMATCH_H	_FNMATCH_H

/* Bits set in the FLAGS argument to `fnmatch'.  */
#define	FNM_PATHNAME	(1 << 0) /* No wildcard can ever match `/'.  */
#define	FNM_NOESCAPE	(1 << 1) /* Backslashes don't quote special chars.  */
#define	FNM_PERIOD	(1 << 2) /* Leading `.' is matched only explicitly.  */

#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE)
#define	FNM_FILE_NAME	FNM_PATHNAME /* Preferred GNU name.  */
#define	FNM_LEADING_DIR	(1 << 3) /* Ignore `/...' after a match.  */
#define	FNM_CASEFOLD	(1 << 4) /* Compare without regard to case.  */
#endif

/* Value returned by `fnmatch' if STRING does not match PATTERN.  */
#define	FNM_NOMATCH	1

#ifdef	__cplusplus
extern "C" {
#endif

/* Match STRING against the filename pattern PATTERN,
   returning zero if it matches, FNM_NOMATCH if not.  */
extern Int32 fnmatch(UChar *, UChar *, Int32);

#ifdef	__cplusplus
}
#endif

#endif	/* !defined(HAVE_FNMATCH) || !defined(HAVE_FNMATCH_H) */

#if !defined(FNM_CASEFOLD) && defined(FNM_IGNORECASE)
#define FNM_CASEFOLD    FNM_IGNORECASE
#endif

#endif /* fnmatch.h */

/************ end of $RCSfile$ ******************/
