#ifndef CCMDLIB_H_
#define CCMDLIB_H_

/*
 * Copyright (c) 1986, 2014 by The Trustees of Columbia University in
 * the City of New York.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  + Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *  + Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 *  + Neither the name of Columbia University nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.

*/

/*
 * First look for files which can be included unconditionally on any
 * UNIX variant.
 */

#include "args.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <errno.h>

#if defined(__osf1__)
/* Error in <sys/ioctl.h> results in loss of prototype of DEC Alpha OSF/1 3.2c */
extern int 	ioctl ARGS((int, int, ...));
#endif

#if HAVE_STDC
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif

#if defined(__sun__) && !defined(__solaris__)
/* Sun SunOS 4.1.x header files are missing a few functions that we need */
extern void	bcopy ARGS((char *,char *, int));
extern void	bzero ARGS((char *,int));
extern void	endgrent(VOID);
extern void	endpwent(VOID);
extern void	gettimeofday ARGS((struct timeval *, struct timezone *));
extern char	*index ARGS((const char *,int));
extern int 	ioctl ARGS((int, int, ...));
extern char	*mktemp ARGS((char *));
extern char	*rindex ARGS((const char *,int));
extern int	select ARGS((int, fd_set *, fd_set *, fd_set *, struct timeval *));
extern void	setgrent(VOID);
extern void	setpwent(VOID);
#if defined(__cplusplus) || defined(c_plusplus)
/* Change two functions to macros so that we can coerce argument types */
#define bcopy(a,b,c) (bcopy)((char*)(a),(char*)(b),(int)(c))
#define bzero(a,b) (bzero)((char*)(a),(int)(b))
#endif
#endif

#if defined(__cplusplus) || defined(c_plusplus)
}
#endif

#else
extern int mkstemp ARGS((char *));
extern char *mktemp ARGS((char *));
extern char *calloc ARGS((size_t, size_t));
extern char *getcwd ARGS((char *, size_t));
extern char *getenv ARGS((const char *));
extern char *getlogin ARGS((void));
extern char *getwd ARGS((void));
extern char *index ARGS((const char *,int));
extern char *malloc ARGS((size_t));
extern char *realloc ARGS((void *, size_t));
extern char *rindex ARGS((const char *,int));
extern char *strcpy ARGS((char *,const char *));
extern char *strchr ARGS((const char *,int));
extern char *strrchr ARGS((const char *,int));
extern int bcmp ARGS((char *,char *, int));
extern int dup ARGS((int));
extern void bcopy ARGS((char *,char *, int));
extern void bzero ARGS((char *,int));
extern void free ARGS((void *));
#endif

#define QSORT_FUN_TYPE int (*) ARGS((const void *, const void *))

/*
 * Make some initial assumptions.
 *
 * We should be able to configure ourself correctly if running under
 * SunOS, 4.3BSD, HP-UX (s300 or s800), or on a Celerity (?).
 *
 * On 4.2bsd systems, compile with -DBSD
 * On System V Release 3 systems, compile with -DSVR3
 * On System V Release 2 systems, compile with -DSVR2
 * On other System V systems, compile with -DSYSV
 *
 * On 4.1bsd, 32/V, System III, etc, some additional work
 * will probably be necessary.
 */

#if !defined(SYSV) && (SVR3 || SVR2)
#define SYSV 1
#endif

#if unix && !defined(BSD) && !defined(SYSV)
#   if hpux || u3b || u3b2 || u3b5 || u3b15 || u3b20
#	define SYSV 1
#   else
#   if defined(TIOCNOTTY) || sun || ultrix || accel
#	define BSD 1
#   endif
#   endif /* !SYSV */
#endif /* unix && ... */

/*
 * Make a guess as to some os-dependent include files we'll need.
 * These #define's can be overridden in site.h.
 */

#if BSD
#define needSYSTIME
#define needFCNTL
#undef  needUNISTD
#define needSYSFILE
#define STRINGS				/* index, rindex, etc */
#define BSTRING				/* bzero, bcopy, etc */
#endif /* BSD */

#if SYSV
#define needTERMIO
#define needFCNTL
#define needUNISTD			/* you may need to override */
#undef  needSYSFILE			/*  these two in site.h */
#undef  STRINGS
#undef  BSTRING
#endif /* SYSV */

#if defined(_POSIX_SOURCE)
#define needTERMIOS
#define needFCNTL
#define needUNISTD			/* you may need to override */
#undef  needSYSFILE			/*  these two in site.h */
#undef  STRINGS
#undef  BSTRING
#endif /* SYSV */

/*
 * Next, include site-specific configuration information.
 *
 */

#include "machdep.h"

/*
 * Now include the rest of the header files and add any other appropriate
 * definitions, based on what we know from the header files included so far.
 */

#ifdef needSYSTIME
#include <sys/time.h>
#else
#include <time.h>
#endif

#if defined(_IBMR2)
#include <time.h>		/* need both <time.h> and <sys/time.h> */
#endif

/*
 * We need one or more of unistd.h, fcntl.h, and sys/file.h.
 */

#ifdef needFCNTL
#include <fcntl.h>
#endif
#ifdef needUNISTD
#if defined(__NeXT__)
#include <libc.h>
#else
#include <unistd.h>
#endif
#endif
#if !defined(O_RDONLY) || !defined(R_OK)
#define needSYSFILE
#endif
#if !defined(SEEK_SET) && !defined(L_SET)
#define needSYSFILE
#endif
#ifdef needSYSFILE
#include <sys/file.h>
#endif

#if HAVE_UNISTD_H
#include <unistd.h>
#endif

/*
 * tty driver definitions
 */

#ifdef needTERMIOS
#  include <termios.h>			/* POSIX.1 standard */
#else
#  ifdef needTERMIO
#    include <sys/termio.h>		/* AT&T System V */
#  else
#    include <sgtty.h>			/* BSD */
#    ifdef needCURSES
#      include <curses.h>
#    endif
#    ifdef needTERM
#      include <term.h>
#    endif
#  endif
#endif

#if !defined(needCURSES) && !defined(needTERM)
/* On Sun Solaris systems, curses.h assumes sgtty.h, which we cannot use */
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
extern	int	tgetent ARGS((char *, const char *));
extern	int	tgetflag ARGS((const char *));
extern	int	tgetnum ARGS((const char *));
extern	int	tputs ARGS((const char *, int, int (*)(int)));
extern	char	*tgetstr ARGS((const char *, char **));
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
#endif

/*
 * CCMD routines generally assume the presence of
 * the Berkeley strings(3) and bstring(3) routines.
 */
#if !defined(STRINGS)
#undef index
#define index strchr
#undef rindex
#define rindex strrchr
#endif

#if !defined(BSTRING)
#undef bzero
#define bzero(a,b)	memset((a),0,b)
#undef bcopy
/* Using memmove here because memcpy doesn't usually handle overlapping
   memory copies */
/* #define bcopy(a,b,c)	memcpy((b),(a),c) */
#define bcopy(a,b,c)	memmove((b),(a),c)
#undef bcmp
#define bcmp(a,b,c)	memcmp((a),(b),c)
#endif

/*
 * We need to define exactly one of DIRLIB, NDIRLIB, DIRENTLIB, or NODIRLIB.
 */

#if !defined(DIRLIB) && !defined(NDIRLIB) && !defined(DIRENTLIB)
#if !defined(NODIRLIB)
#   if u3b || u3b2 || u3b5 || u3b15 || u3b20 || SVR3 || __osf__
#	define DIRENTLIB
#   else
#   if hpux
#	define NDIRLIB
#   else
#   if BSD
#	define DIRLIB
#   else
#	define NODIRLIB
#   endif /* !bsd */
#   endif /* !hpux */
#   endif /* !posix */
#endif
#endif

#ifdef DIRENTLIB
#   include <dirent.h>
#   define direct dirent
#endif
#ifdef NDIRLIB
#   include <ndir.h>
#endif
#ifdef DIRLIB
#   include <sys/dir.h>
#endif

#if defined(_IBMR2)
#define direct dirent
#endif

#ifdef NODIRLIB
#   if MSDOS
#	include <dos.h>
#	include <direct.h>
#   endif
#endif

/*
 * Miscellaneous other files we need.
 */

#if HAVE_STDC
#include <stdarg.h>
#else /* K&R style */
#include <varargs.h>
#endif /* HAVE_STDC */

#include <signal.h>
#include <ctype.h>
#if unix
#include <utmp.h>
#endif

/*
 * On some systems, signal handlers are defined as returning (void).
 */

#ifndef SIGNALHANDLERTYPE
#define SIGNALHANDLERTYPE int
#endif
typedef SIGNALHANDLERTYPE (*signal_handler_t) ();

/*
 * Finally, include ccmd.h, which includes stdio.h and setjmp.h.
 */

#include "ccmd.h"

#endif /* CCMDLIB_H_ */
