/******************************************************************************
  els.h -- els functions and defines
  
  Author: Mark Baranowski
  Email:  requestXXX@els-software.org (remove XXX)
  Download: http://els-software.org

  Last significant change: August 9, 2000
  
  These functions are provided "as is" in the hopes that they might serve some
  higher purpose.  If you want these functions to serve some lower purpose,
  then that too is all right.  So as to keep these hopes alive you may
  freely distribute these functions so long as this header remains intact.
  You may also freely distribute modified versions of these functions so long
  as you indicate that such versions are modified and so long as you
  provide access to the unmodified original copy.
  
  Note: The most recent version of these functions may be obtained from
        http://els-software.org

  ****************************************************************************/

#ifndef ELS__ELS_H
#define ELS__ELS_H

/* Add /usr/include/sys/stat.h defs if necessary: */
#if !defined(S_ISLNK)
#  define S_ISLNK(m)  (((m) & S_IFMT) == S_IFLNK)
#endif
#if !defined(S_ISDIR)
#  define S_ISDIR(m)  (((m) & S_IFMT) == S_IFDIR)
#endif
#if !defined(S_ISBLK)
#  define S_ISBLK(m)  (((m) & S_IFMT) == S_IFBLK)
#endif
#if !defined(S_ISCHR)
#  define S_ISCHR(m)  (((m) & S_IFMT) == S_IFCHR)
#endif
#if !defined(S_ISFIFO)
#  define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#endif
#if defined(SUNOS) && !defined(S_IFDOOR)
/* This definition will not upset SUNOS4: */
#  define S_IFDOOR  0xd000
#endif

/* Determine maximum size of file name and path name based on information
   found in /usr/include/dirent.h and /usr/include/sys/param.h: */

#include <dirent.h>
#include <sys/param.h>

#if defined(MAXNAMLEN)
#  define MAX_FNAME MAXNAMLEN	/* SunOS4&5, Ultrix, ICS */
#elif defined(_MAXNAMLEN)
#  define MAX_FNAME _MAXNAMLEN	/* HPUX */
#elif defined(NAME_MAX)
#  define MAX_FNAME NAME_MAX	/* Linux2 */
#else
#  define MAX_FNAME 255		/* Default: AIX */
#endif

/* Maximum size of directory name: */
#if defined(MAXPATHLEN)
#  define MAX_DNAME MAXPATHLEN	/* SunOS4&5, Ultrix, HPUX */
#elif defined(_D_NAME_MAX)
#  define MAX_DNAME _D_NAME_MAX	/* AIX */
#elif defined(PATH_MAX)
#  define MAX_DNAME PATH_MAX	/* Linux2 */
#else
#  define MAX_DNAME 511		/* Default: ICS */
#endif

/* Maximum size of full name (+4 for quotes, +1 for CNULL): */
#define  MAX_FULL_NAME  (MAX_DNAME+MAX_FNAME+4+1)

/* Maximum amount of info (besides the full file name) per line: */
#define  MAX_INFO  128

/* Maximum amount of output generated per line (sizeof(info) +
   sizeof(file name) + sizeof(optional symlink name) + sizeof(" -> ")): */
#define  MAX_OUTPUT  (MAX_INFO+2*MAX_FULL_NAME+4)

/* Maximum amount of output generated by a message: */
#define  MAX_MSG  (MAX_INFO+MAX_FULL_NAME)

/* Manually define maximum User/Group name to some reasonable length.
   I've yet to find these in any include file although at least one OS
   (i.e. SunOS4.x) allows more than 70 chars!?: */
#define  MAX_USER_GROUP_NAME  32
#if  MAX_USER_GROUP_NAME < 11    /* strlen("-2147483648") */
/* Minimum of 11 characters in case UID/GID has no passwd/group entry: */
#  error: Minimum of 11 characters required for UID/GID name
#endif


typedef struct Dir_Item
{
  char *mem;
  char *fname;

  Boole islink;
  Boole isdir;
  Boole isdev;

  Boole dotdir;
  Boole hidden;
  Boole listable;
  Boole searchable;

  int readdir_errno;		/* errno value set by readdir() */
  int stat_errno;		/* errno value set by stat() */
  struct stat info;		/* info structure from stat() */

  struct Dir_Item *next;
} Dir_Item;

typedef struct Dir_List
{
  Dir_Item *head;
  Dir_Item *tail;
} Dir_List;

/********** Global Routines Defined **********/

#include <time.h> /* Needed for T_print() prototype */

/* extern void finishExit(void); */
/* extern void do_options(char *options); */
/* extern void do_options_minus(char *options); */
/* extern void do_options_plus(char *options); */
/* extern void stamp_setup(int pass); */
/* extern void untouch_setup(int pass); */
/* extern void give_usage_or_help(char U_or_H); */
/* extern void analyze_options(void); */
/* extern void append_dir(Dir_List *dlist, char *fname, int fname_size); */
/* extern void copy_info(Dir_Item *dest, Dir_Item *src); */
/* extern int  read_dir(Dir_List *dlist, char *dname, DIR *dir); */
/* extern void stat_dir(Dir_List *dlist, char *dname); */
/* extern void name_dir(Dir_List *dlist, char *dname); */
/* extern void sort_dir(Dir_List *dlist, char *dname, int n); */
/* extern void list_dir(Dir_List *dlist, char *dname); */
/* extern void free_dir(Dir_List *dlist); */
/* extern Boole list_item(Dir_Item *file, char *dname); */
/* extern char *find_first_directive(char *list, char *fmt); */
/* extern char *G_print(char *buff, char *fmt, char *dname, Dir_Item *file); */
/* extern char *N_print(char *buff, char *fmt, char *dname, Dir_Item *file); */
extern char *T_print(char *buff, char *fmt, time_t ftime,
		     struct tm *fdate, Boole gmt, Boole meridian);
/* extern char *T_print_width(char *buff, char *fmt, time_t ftime,
		    struct tm *fdate, Boole gmt, Boole meridian, int width);  */
/* extern char *separate(char *bp, char icase); */
/* extern char *finish(char *bp); */
/* extern char *full_name(char *dname, char *fname); */
/* extern Dir_Item *dirItemAlloc(void); */
/* extern void dirItemFree(Dir_Item *file); */
/* extern void dirItemShow(FILE *out); */
/* extern void watchSigHandler(int sig); */
extern int sigSafe_stat(char *path, struct stat *buf);
extern int sigSafe_lstat(char *path, struct stat *buf);
/* extern void spin_wheel(void); */

/********** Global Variables Defined **********/

/* extern int  Iarg; */
extern int  Argc;
extern char **Argv;
/* extern char *Progname; */
extern uid_t Whoami;
extern time_t The_Time;
extern time_t The_Time_in_an_hour;
extern char *Time_Zone;
extern int Debug;
extern int VersionLevel;
/* extern int MaxVersionLevel; */
extern Boole VersionLevelArg;
/* extern Boole ArgOrder; */
/* extern Boole TruncateName; */
extern Boole MaskId;
/* extern Boole QuitOnError; */
/* extern Boole SortCI; */
/* extern Boole SortDICT; */
/* extern Boole First_listing; */
extern char *Current_Opt;
/* extern char *Current_Arg; */
extern Dir_Item *CwdItem;
extern int CwdBlocksize;
/* extern char *CwdPath; */

#define EXEC_ERROR      3
#define LISTING_ERROR   2
#define USAGE_ERROR     1
#define GENERAL_ERROR   1
#define NORMAL_EXIT     0
extern Boole listingError;

/* extern Boole zero_file_args; */
/* extern Boole multiple_file_args; */
extern Boole using_full_names;
/* extern Boole avoid_trimmings; */
Boole list_topdir;
/* extern char first_mac; */
extern int recursion_level;

#define SEM_ELS  0x01
#define SEM_LS   0x02
#define SEM_BSD  0x04
#define SEM_SYS5 0x08
#define SEM_GNU  0x10
extern Uint Sem;

extern Boole list_hidden;
extern Boole list_dotdir;
/* extern Boole list_long; */
/* extern Boole list_long_numeric; */
/* extern Boole list_long_omit_gid; */
/* extern Boole list_atime; */
/* extern Boole list_ctime; */
/* extern Boole list_inode; */
/* extern Boole list_size_in_blocks; */
/* extern Boole list_size_human_10; */
/* extern Boole list_size_human_2; */
extern Boole expand_symlink;
extern Boole expand_directories;
/* extern Boole mark_files; */
/* extern Boole mark_dirs; */
/* extern Boole dash_b; */
/* extern Boole dash_Q; */
/* extern Boole recursive; */
/* extern Boole reverse_sort; */
/* extern Boole time_sort; */
/* extern Boole unsort; */
/* extern Boole g_flag; */
/* extern Boole G_flag; */
/* extern Boole plus_c; */
/* extern cksumType cksum_type; */
/* extern int cksum_size; */
/* extern Boole cksum_unaccess; */
extern Boole list_directories;
/* extern Boole plus_q; */
/* extern Boole traverse_mp; */
/* extern Boole traverse_expanded_symlink; */
/* extern Boole traverse_specified; */
extern Boole useLcCollate;
extern Boole useLcTime;
/* extern Boole warning_suppress; */
/* extern Boole watch_progress; */
/* extern FILE *ttyin, *ttyout; */
/* extern Boole zero_st_info; */
/* extern Ulong zero_st_mask; */

/* extern Boole CCaseMode; */
/* extern Boole GTarStyle; */
/* extern Boole Tar5Style; */
/* extern Boole FirstFound; */
/* extern Boole OncePerDir; */
/* extern int DirDepth; */

#define type_REG	'r'
#define type_DIR	'd'
#define type_CHR	'c'
#define type_BLK	'b'
#define type_FIFO	'p'
#define type_LNK	'l'
#define type_SOCK	's'
#define type_DOOR	'D'
#define type_SPECIAL	'S'	/* c:b */
#define symtype_REG	'-'
#define symtype_DIR	'/'
#define symtype_FIFO	'|'
#define symtype_LNK	'@'
#define symtype_SOCK	'='
#define symtype_DOOR	'>'

#endif /*ELS__ELS_H*/
