/*
 * Configurable ps-like program.
 * Global definitions.
 *
 * Copyright (c) 2014 David I. Bell
 * Permission is granted to use, distribute, or modify this source,
 * provided that this copyright notice remains intact.
 */

#ifndef	IPS_H
#define	IPS_H

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/types.h>


#ifndef	SYSTEM_INIT_FILE
#define	SYSTEM_INIT_FILE	"/usr/local/lib/ips.init"
#endif

#ifndef	USER_INIT_FILE
#define	USER_INIT_FILE		".ipsrc"
#endif

#ifndef	SYSTEM_INIT_MACRO
#define	SYSTEM_INIT_MACRO	"SysInit"
#endif

#ifndef	USER_INIT_MACRO
#define	USER_INIT_MACRO		"UserInit"
#endif

#define	FIRST_LINE		"#ips#"		/* first line of init files */


/*
 * Some constants related to the system.
 */
#define	CPU_SCALE	10000		/* scaling factor for cpu usage */
#define	MEMORY_SCALE	1000		/* scaling factor for memory usage */
#define	BASE_USER_UID	100		/* first "user" uid */


/*
 * Constants for calculating CPU percentages.
 */
#define	PERCENT_RESOLUTION	5	/* max number of CPU samples per second */
#define	PERCENT_MAX_SECONDS	20	/* max seconds for collecting CPU samples */
#define	PERCENT_DEFAULT_SECONDS	10	/* default seconds for cpu percentage */
#define	PERCENT_SAMPLES	((PERCENT_RESOLUTION) * (PERCENT_MAX_SECONDS) + 2)	/* total samples */


/*
 * Define widths of numbers which depend on the size of a long.
 */
#if	2147483647 + 1 > 0
#define	LONG_HEX_DIGITS		16
#define	LONG_DIGITS		21
#define	LONG_HEX_FORMAT		"%016lx"
#else
#define	LONG_HEX_DIGITS		8
#define	LONG_DIGITS		11
#define	LONG_HEX_FORMAT		"%08lx"
#endif


/*
 * Some default values.
 */
#define	DEFAULT_INIT_SEC	1	/* default initialization time */
#define	DEFAULT_SLEEP_SEC	10	/* default sleep between loops */
#define	DEFAULT_SCROLL_SEC	30	/* default time between autoscrolls */
#define	DEFAULT_OVERLAP_LINES	1	/* default overlapping lines */
#define	DEFAULT_SYNC_SEC	300	/* default time to force data sync */
#define	DEFAULT_ACTIVE_SEC	60	/* default time to consider active */
#define	DEFAULT_DEATH_SEC	30	/* default time to preserve death */
#define	DEFAULT_WIDTH		80	/* default width if not known */
#define	DEFAULT_GEOMETRY	"150x50"	/* geometry for X11 */
#define	DEFAULT_GEOMETRY_ROWS	50	/* row part of geometry */
#define	DEFAULT_GEOMETRY_COLS	150	/* col part of geometry */
#define	DEFAULT_FONT		"fixed"	/* font name for X11 */
#define	DEFAULT_FOREGROUND	"black"	/* foreground color for X11 */
#define	DEFAULT_BACKGROUND	"white"	/* background color for X11 */


/*
 * Some limits on the program.
 */
#define	MAX_PIDS	100
#define	MAX_USERS	100
#define	MAX_GROUPS	100
#define	MAX_PROGRAMS	20
#define	MAX_WORDS	1000
#define	MAX_COLUMNS	50
#define	MAX_SEPARATION	20
#define	MAX_MACRO_LEN	16
#define	MAX_OPTION_DEPTH 20
#define	MAX_EXPR_DEPTH	20
#define	MAX_WIDTH	(1024 * 31)
#define	MAX_COMMAND_LEN	(1024 * 10)
#define	MAX_ENVIRON_LEN	(1024 * 20)
#define	MAX_INFO_LEN	256
#define	MAX_PATH_LEN	1024
#define	BUF_COMMAND_LEN	128
#define	MAX_PROGRAM_LEN	32
#define	MAX_WCHAN_LEN	32
#define	MAX_STATES_LEN	16
#define	MAX_COLORS	20
#define	MAX_ROW_COLORS	50


/*
 * Macros to help parse strings.
 */
#define	isBlank(ch)	(((ch) == ' ') || ((ch) == '\t'))
#define	isDigit(ch)	(((ch) >= '0') && ((ch) <= '9'))
#define	isUpper(ch)	(((ch) >= 'A') && ((ch) <= 'Z'))
#define	isLower(ch)	(((ch) >= 'a') && ((ch) <= 'z'))
#define	isMacro(ch)	isUpper(ch)


/*
 * Boolean values.
 */
typedef	int	BOOL;

#define	FALSE	((BOOL) 0)
#define	TRUE	((BOOL) 1)


/*
 * Some other typedefs.
 */
typedef	unsigned long	ULONG;
typedef	struct	COLUMN	COLUMN;


/*
 * Special values for unknown user, group, or device ids.
 */
#define	BAD_UID		((uid_t) -1)
#define	BAD_GID		((gid_t) -1)
#define	BAD_DEVID	((dev_t) -1)


/*
 * Argument structure.
 * This is for parsing command line arguments.
 */
typedef	struct
{
	int	count;			/* number of arguments */
	char **	table;			/* table of arguments */
} ARGS;


/*
 * Structure which holds information about a process.
 * This is used for main process information and also for threads
 * making up the main process.  The main process entry is a summary
 * of all the threads for a process and has a tid of NO_THREAD_ID.
 * For a multi-threaded process each thread has its own entry,
 * including the main starting thread.  Threads are linked together
 * and know their main process owner entry.
 */
typedef	struct	PROC	PROC;

struct	PROC
{
	PROC *	next;			/* next process or thread in list */
	PROC *	nextThread;		/* first or next thread belonging to owner */
	PROC *	owner;			/* main process owning this thread */
	BOOL	isValid;		/* the process is existent */
	BOOL	isAncient;		/* the process is before we started */
	BOOL	isNew;			/* the process is just created */
	BOOL	isActive;		/* the process is active */
	BOOL	isChanged;		/* the process state has changed */
	BOOL	isShown;		/* the process is to be shown */
	BOOL	hasCommand;		/* there is a real command line */
	BOOL	isThread;		/* this is a thread process entry */
	ULONG	liveCounter;		/* counter to mark existant procs */
	ULONG	runOrder;		/* counter value when last active */
	time_t	lastSavedTime;		/* time status was copied to old */
	time_t	lastActiveTime;		/* time process last was active */
	time_t	lastSyncTime;		/* time status was last synchonized */
	time_t	deathTime;		/* time process was seen to be dead */
	uid_t	uid;			/* effective user id */
	gid_t	gid;			/* effective group id */
	pid_t	pid;			/* process id */
	pthread_t	tid;		/* thread id (or NO_THREAD_ID) */
	pid_t	parentPid;		/* parent pid */
	pid_t	processGroup;		/* process group */
	pid_t	sessionId;		/* session id */
	dev_t	ttyDevice;		/* controlling terminal's device */
	pid_t	ttyProcessGroup;	/* process group of terminal */
	int	state;			/* process state character */
	int	processor;		/* processor process is on */
	int	exitSignal;		/* signal causing exit */
	ULONG	flags;			/* kernel flags */
	long	minorFaults;		/* minor page faults */
	long	majorFaults;		/* major page faults */
	long	childMinorFaults;	/* child minor page faults */
	long	childMajorFaults;	/* child major page faults */
	long	userRunTime;		/* user runtime in jiffies */
	long	systemRunTime;		/* system runtime in jiffies */
	long	childUserRunTime;	/* child user runtime */
	long	childSystemRunTime;	/* child system runtime */
	long	nice;			/* nice value */
	long	priority;		/* scheduling priority */
	long	realTimePriority;	/* real time priority */
	long	timeout;		/* timeout */
	long	itRealValue;		/* jiffies sleeping for */
	long	virtualSize;		/* virtual size of process in bytes */
	long	rss;			/* resident size in clicks */
	long	rssLimit;		/* resident size limit */
	long	policy;			/* policy */
	time_t	startTimeClock;		/* clock time when started */
	ULONG	startTimeTicks;		/* jiffies uptime when started */
	ULONG	firstCpuTime;		/* cpu runtime when first examined */
	ULONG	startCode;		/* beginning address of code */
	ULONG	endCode;		/* ending address of code */
	ULONG	startStack;		/* starting address of stack */
	ULONG	esp;			/* stack pointer */
	ULONG	eip;			/* instruction pointer */
	ULONG	waitChan;		/* wait channel address */
	ULONG	signal;			/* current signal */
	ULONG	sigBlock;		/* signals to block */
	ULONG	sigIgnore;		/* signals to ignore */
	ULONG	sigCatch;		/* signals to catch */
	ULONG	pagesSwapped;		/* pages swapped out */
	ULONG	childPagesSwapped;	/* child pages swapped out */
	int	percentCpu;		/* percentage of cpu used */
	int	percentMemory;		/* percentage of memory used */
	int	openFiles;		/* number of open files */
	int	threadCount;		/* number of threads */
	int	commandLength;		/* length of command line */
	int	environmentLength;	/* length of environment */
	int	cwdPathLength;		/* length of current working dir path */
	int	rootPathLength;		/* length of root directory path */
	int	execPathLength;		/* length of executable path */
	char *	command;		/* command line */
	char *	environment;		/* environment */
	char *	cwdPath;		/* path of current working directory */
	char *	rootPath;		/* path of root directory */
	char *	execPath;		/* path of executable */
	char *	stdioPaths[3];		/* paths of stdin, stdout, stderr */
	char	program[MAX_PROGRAM_LEN + 2];	/* program name */
	char	commandBuffer[BUF_COMMAND_LEN + 2];	/* command buffer */
	char	waitChanSymbol[MAX_WCHAN_LEN + 2];	/* wait channel */
	char	states[MAX_STATES_LEN + 2];	/* thread states */
	long	cpuTable[PERCENT_SAMPLES];	/* cpu runtime sample table */

	/*
	 * Status which is saved in order to determine active processes
	 * even if they are currently sleeping for this snapshot.
	 * A process is active if any of this differs from the current
	 * value.
	 */
	int	oldState;
	long	oldMinorFaults;
	long	oldMajorFaults;
	long	oldUserRunTime;
	long	oldSystemRunTime;
	ULONG	oldFlags;
	ULONG	oldStartTimeTicks;
	ULONG	oldEndCode;	
	ULONG	oldEsp;
	ULONG	oldEip;
	ULONG	oldWaitChan;
};

#define	NULL_PROC	((PROC *) 0)


/*
 * The thread id for the main process entry.
 */
#define	NO_THREAD_ID	((pthread_t) -1)


/*
 * Column justification definitions.
 */
typedef	int	JUSTIFY;

#define	LEFT	((JUSTIFY) 0)
#define	RIGHT	((JUSTIFY) 1)
#define	CENTER	((JUSTIFY) 2)


/*
 * Values returned by expressions.
 */
typedef	struct
{
	int		type;		/* type of value */
	long		intVal;		/* integer value */
	const char *	strVal;		/* string value */
	COLUMN *	column;		/* column value */
} VALUE;


#define	VALUE_BAD	0
#define	VALUE_NONE	1
#define	VALUE_NUMBER	2
#define	VALUE_STRING	3
#define	VALUE_COLUMN	4
#define	VALUE_BOOLEAN	5

#define	TWOVAL(first, second)	(((first) * 10) + (second))


/*
 * Flags for what a column requires to be collected.
 * These flags are OR'd together.
 */
typedef	unsigned int	USEFLAG;

#define	USE_NONE	((USEFLAG) 0x0000)
#define	USE_INIT	((USEFLAG) 0x0001)
#define	USE_DEV_NAME	((USEFLAG) 0x0002)
#define	USE_OPEN_FILE	((USEFLAG) 0x0004)
#define	USE_CURR_DIR	((USEFLAG) 0x0008)
#define	USE_COMMAND	((USEFLAG) 0x0010)
#define	USE_SELF	((USEFLAG) 0x0020)
#define	USE_STDIN	((USEFLAG) 0x0040)
#define	USE_STDOUT	((USEFLAG) 0x0080)
#define	USE_STDERR	((USEFLAG) 0x0100)
#define	USE_ENVIRON	((USEFLAG) 0x0200)
#define	USE_ROOT_DIR	((USEFLAG) 0x0400)
#define	USE_EXEC_INODE	((USEFLAG) 0x0800)
#define	USE_USER_NAME	((USEFLAG) 0x1000)
#define	USE_GROUP_NAME	((USEFLAG) 0x2000)
#define	USE_WCHAN	((USEFLAG) 0x4000)
#define	USE_THREADS	((USEFLAG) 0x8000)


/*
 * Structure for one column that can be displayed.
 */
struct	COLUMN
{
	char *		name;		/* column name for commands */
	char *		heading;	/* heading string for column */
	int		minWidth;	/* absolute minimum width of column */
	int		initWidth;	/* initial minimum width of column */
	int		width;		/* actual minimum width of column */
	JUSTIFY		justify;	/* how value is justified in column */
	USEFLAG		useFlag;	/* what data column uses */
	const char *	(*showFunc)(const PROC * proc);
	int		(*sortFunc)(const PROC * proc1, const PROC * proc2);
	void		(*evalFunc)(const PROC * proc, VALUE * retval);
	BOOL		(*testFunc)(const PROC * proc);
};


/*
 * Identifiers for the different types of macros.
 * Some features of these macro types are built-in.
 * These definitions cannot be changed in isolation.
 */
typedef	int	MACRO_TYPE;

#define	MACRO_TYPE_NONE		((MACRO_TYPE) -1)
#define	MACRO_TYPE_OPTION	((MACRO_TYPE) 0)
#define	MACRO_TYPE_COLUMN	((MACRO_TYPE) 1)
#define	MACRO_TYPE_EXPRESSION	((MACRO_TYPE) 2)

      
/*
 * Interface to communicate with an input/output display device.
 * This can be, for example, a dumb terminal, a curses terminal,
 * or an X11 window.
 */
typedef	struct	DISPLAY	DISPLAY;

struct	DISPLAY
{
	BOOL	(*open)(DISPLAY *);		/* open display */
	BOOL	(*defineColor)(DISPLAY *, int, const char *, const char *, int);
	void	(*createWindow)(DISPLAY *);	/* create window on display */
	void	(*close)(DISPLAY *);		/* close display */
	void	(*setColor)(DISPLAY *, int);	/* set color for output */
	void	(*refresh)(DISPLAY *);		/* refresh display */
	void	(*beginPage)(DISPLAY *);	/* begin output of page */
	void	(*putChar)(DISPLAY *, int);	/* output character */
	void	(*putString)(DISPLAY *, const char *);	/* output string */
	void	(*putBuffer)(DISPLAY *, const char *, int);	/* buffer */
	void	(*endPage)(DISPLAY *);		/* end output of page */
	BOOL	(*eventWait)(DISPLAY *, int);	/* handle events and wait */
	BOOL	(*inputReady)(DISPLAY *);	/* check if input is ready */
	int	(*readChar)(DISPLAY *);		/* read input character */
	void	(*ringBell)(DISPLAY *);		/* ring the bell */
	int	(*getRows)(DISPLAY *);		/* get number of rows */
	int	(*getCols)(DISPLAY *);		/* get number of columns */
	BOOL	(*doesScroll)(DISPLAY *);	/* whether display scrolls */
};


#define	DISPLAY_TYPE_TTY	"tty"
#define	DISPLAY_TYPE_CURSES	"curses"
#define	DISPLAY_TYPE_X11	"x11"


/*
 * Color related definitions.
 */
#define	DEFAULT_COLOR_ID	0
#define	BAD_COLOR_ID		-1

#define	DEFAULT_COLOR_NAME	"default"


/*
 * Flags which can be set in addition to the foreground and background
 * to modify the text slightly.
 */
#define	COLOR_FLAG_NONE		0x00
#define	COLOR_FLAG_BOLD		0x01
#define	COLOR_FLAG_UNDERLINE	0x02


/*
 * List of columns being shown.
 */
extern	int	showCount;
extern	COLUMN *showList[MAX_COLUMNS];


/*
 * Other global variables.
 */
extern	ULONG		startUptime;		/* uptime jiffies at start */
extern	time_t		startTime;		/* clock time at start */
extern	time_t		currentTime;		/* current clock time */
extern	long		totalMemoryClicks;	/* amount of total memory */
extern	long		ticksPerSecond;		/* number of clock ticks per second */
extern	long		pageSize;		/* number of bytes in a page */
extern	ULONG		liveCounter;		/* counter for live procs */
extern	int		newCpuIndex;		/* new CPU sample index */
extern	int		oldCpuIndex;		/* old CPU sample index */
extern	BOOL		ancientFlag;		/* seeing pre-existing procs */
extern	BOOL		showThreads;		/* show threads */
extern	BOOL		noCopy;			/* don't copy data for threads */
extern	BOOL		noSelf;			/* don't show myself */
extern	BOOL		noRoot;			/* don't show root procs */
extern	BOOL		noHeader;		/* don't show column header */
extern	BOOL		isInfoShown;		/* show info line at top */
extern	BOOL		myProcs;		/* only show my procs */
extern	BOOL		activeOnly;		/* only show active procs */
extern	BOOL		clearScreen;		/* clear screen each loop */
extern	BOOL		isLooping;		/* loop showing status */
extern	BOOL		isRunning;		/* we still want to run */
extern	BOOL		isFrozen;		/* data collection is frozen */
extern	BOOL		isUpdateForced;		/* update once even if frozen */
extern	BOOL		isRefreshNeeded;	/* need to refresh display */
extern	BOOL		isVertical;		/* vertical output format */
extern	BOOL		isTopMode;		/* top option was used */
extern	BOOL		isTopAuto;		/* autosize height for top */
extern	BOOL		useOpenFiles;		/* using open file info */
extern	BOOL		useCurrentDirectory;	/* using current dir info */
extern	BOOL		useRootDirectory;	/* using root dir info */
extern	BOOL		useExecInode;		/* using executable info */
extern	BOOL		useDeviceNames;		/* using device name info */
extern	BOOL		useUserNames;		/* using user name info */
extern	BOOL		useGroupNames;		/* using group name info */
extern	BOOL		useInitSleep;		/* using initial sleep */
extern	BOOL		useCommand;		/* using command line info */
extern	BOOL		useSelf;		/* using my own proc info */
extern	BOOL		useEnvironment;		/* using environment info */
extern	BOOL		useWaitChan;		/* using wait channel symbol */
extern	BOOL		useThreads;		/* use thread data */
extern	BOOL		useStdioTable[3];	/* using various stdio info */
extern	pid_t		myPid;			/* my pid */
extern	uid_t		myUid;			/* my real user id */
extern	gid_t		myGid;			/* my real group id */
extern	dev_t		nullDevice;		/* device of /dev/null */
extern	ino_t		nullInode;		/* inode of /dev/null */
extern	int		procAllocCount;		/* allocated proc structures */
extern	int		deathTime;		/* seconds for dead processes */
extern	int		activeTime;		/* seconds for active procs */
extern	int		pidCount;		/* pids in pidList */
extern	int		userCount;		/* users in userList */
extern	int		groupCount;		/* groups in groupList */
extern	int		programCount;		/* programs in programList */
extern	int		outputWidth;		/* width of output */
extern	int		outputHeight;		/* height of output */
extern	int		separation;		/* blanks between columns */
extern	int		sleepTimeMs;		/* milliseconds between loops */
extern	int		syncTime;		/* seconds between syncs */
extern	int		initSleepTime;		/* seconds for initial sleep */
extern	int		topCount;		/* number of procs for top */
extern	int		percentSeconds;		/* seconds for cpu percentages */
extern	int		scrollSeconds;		/* seconds between scrolling */
extern	int		overlapLines;		/* lines of overlap */
extern	int		skipCount;		/* lines to skip in display */
extern	int		procShowCount;		/* processes wanting showing */
extern	int		procTotalCount;		/* count of all processes */
extern	int		threadShowCount;	/* threads wanting showing */
extern	int		threadTotalCount;	/* count of all threads */
extern	int		infoColorId;		/* color id for info line */
extern	int		headerColorId;		/* color id for header line */
extern	PROC *		processList;		/* list of existent procs */
extern	PROC *		freeProcessList;	/* free proc structure list */
extern	char *		geometry;		/* window geometry string */
extern	char *		fontName;		/* font name */
extern	char *		foregroundName;		/* foreground color name */
extern	char *		backgroundName;		/* background color name */
extern	char *		displayName;		/* display name */
extern	const char *	displayType;		/* display type */
extern	char		emptyString[4];		/* empty string */
extern	char		rootString[4];		/* root path string */
extern	pid_t		pidList[MAX_PIDS];	/* pids to be shown */
extern	uid_t		userList[MAX_USERS];	/* user ids to be shown */
extern	gid_t		groupList[MAX_GROUPS];	/* group ids to be shown */
extern	char		programList[MAX_PROGRAMS][MAX_PROGRAM_LEN + 2];


/*
 * Global procedures.
 */
extern	BOOL	PatternMatch(const char * text, const char * pattern);
extern	char *	AllocateSharedString(const char * str, int len);
extern	void	FreeSharedString(char * str);
extern	char *	AllocTempString(int len);
extern	char *	CopyTempString(const char * oldcp);
extern	void	FreeTempStrings(void);
extern	void *	AllocMemory(int len);
extern	void *	ReallocMemory(void * oldBuffer, int len);
extern	char *	CopyString(const char *);
extern	void	ReplaceString(char **, const char *);
extern	void	DefaultAllOptions(void);
extern	void	DefaultColumns(void);
extern	void	DefaultColumnWidths(void);
extern	ULONG	GetUptime(void);
extern	BOOL	ParseSystemInitFile(void);
extern	BOOL	ParseUserInitFile(void);
extern	BOOL	ParseFile(const char * name, BOOL isOptional);
extern	BOOL	ParseOptions(ARGS * ap, int depth);
extern	BOOL	ExpandOptionName(const char * name, int depth);
extern	long	GetDecimalNumber(const char ** cpp);
extern	double	GetFloatingNumber(const char ** cpp);
extern	void	ClearCondition(void);
extern	BOOL	ParseCondition(const char * str);
extern	USEFLAG	GetConditionUseFlags(void);
extern	USEFLAG	GetSortingUseFlags(void);
extern	void	ClearSorting(void);
extern	void	SortProcesses(void);
extern	void	UpdateProcessCounts(void);
extern	BOOL	AppendColumnSort(ARGS * ap, BOOL reverse);
extern	BOOL	AppendExpressionSort(ARGS * ap, BOOL reverse);
extern	PROC *	FindProcess(pid_t pid, pthread_t tid);
extern	BOOL	InitializeProcessData(void);
extern	BOOL	InitializeDisplay(void);
extern	void	TopPage(void);
extern	void	BottomPage(void);
extern	void	NextPage(void);
extern	void	PreviousPage(void);
extern	void	ScanProcesses(void);
extern	void	CheckActiveProcess(PROC * proc);
extern	void	RemoveDeadProcesses(void);
extern	void	InitialProcessScan(void);
extern	BOOL	IsShownProcess(const PROC * proc);
extern	void	ShowSelectedProcesses(void);
extern	void	ListMacros(void);
extern	COLUMN *FindColumn(const char * name);
extern	void	ListColumns(void);
extern	void	CollectUserNames(void);
extern	void	CollectGroupNames(void);
extern	void	CollectDeviceNames(void);
extern	void	CollectStaticSystemInfo(void);
extern	void	CollectDynamicSystemInfo(void);
extern	uid_t	FindUserId(const char * name);
extern	gid_t	FindGroupId(const char * name);
extern	const char *	FindUserName(uid_t uid);
extern	const char *	FindGroupName(gid_t gid);
extern	const char *	FindDeviceName(dev_t devid);
extern	const char *	FindDeviceFromInode(dev_t dev, ino_t inode);
extern	void	CalculateCpuPercentage(PROC * proc);
extern	void	UpdateTimes(void);
extern	void	SetCommandLine(PROC * proc, const char * str, int len);
extern	BOOL	SetSharedString(char ** saveStr, int * saveLen, const char * str, int len);
extern	void	ResetScrollTime(void);
extern	void	WaitForCommands(long milliSeconds);
extern	BOOL	ReadCommands(void);
extern	int	ExpandArguments(ARGS * ap, char ** table, int tablelen);
extern	BOOL	MacroExists(MACRO_TYPE id, const char * name);
extern	BOOL	DefineMacro(MACRO_TYPE id, const char * name, const char * str);
extern	BOOL	ExpandMacro(MACRO_TYPE id, const char * name, ARGS * retargs);
extern	void	MakePrintable(char * cp, int len);
extern	void	GetTimeOfDay(struct timeval * retTimeVal);

extern	long	ElapsedMilliSeconds(const struct timeval * oldTime,
			const struct timeval * newTime);

extern	BOOL	CompareValues(const VALUE leftval,
			const VALUE rightval, int * result);

extern	ULONG	GetRunOrder(const PROC * proc);
extern	time_t	GetLastActiveTime(const PROC * proc);
extern	BOOL	GetIsActive(const PROC * proc);
extern	int	GetState(const PROC * proc);
extern	void	BuildStates(PROC * proc);
extern	int	PickBestState(int state1, int state2);

extern	void	InitializeColors(void);
extern	int	AllocateColor(const char * color);
extern	BOOL	DefineColors(void);

extern	void	ClearRowColorConditions(void);
extern	BOOL	ParseRowColorCondition(const char * color, const char * condition);
extern	int	EvaluateRowColor(const PROC * proc);
extern	USEFLAG	GetRowColorUseFlags(void);

extern	BOOL	DpySetDisplay(const char * type);
extern	BOOL	DpyOpen(void);

extern	BOOL	DpyDefineColor(int colorId,
	const char * foreground, const char * background, int flags);

extern	void	DpyCreateWindow(void);
extern	void	DpyClose(void);
extern	void	DpySetColor(int colorId);
extern	void	DpyRefresh(void);
extern	void	DpyBeginPage(void);
extern	void	DpyChar(int ch);
extern	void	DpyString(const char * str);
extern	void	DpyBuffer(const char * buffer, int length);
extern	void	DpyEndPage(void);
extern	BOOL	DpyInputReady(void);
extern	int	DpyReadChar(void);
extern	void	DpyRingBell(void);
extern	int	DpyGetRows(void);
extern	int	DpyGetCols(void);
extern	BOOL	DpyDoesScroll(void);
extern	BOOL	DpyEventWait(int milliSeconds);

extern	DISPLAY *	GetTtyDisplay(void);
extern	DISPLAY *	GetCursesDisplay(void);
extern	DISPLAY *	GetX11Display(void);

#endif
