/*
** mh.h -- main header file for all of nmh
*/

#include <config.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <stdarg.h>


/*
** Well-used constants
*/
#define NOTOK       (-1)    /* syscall()s return this on error */
#define OK             0    /*  ditto on success               */
#define DONE           1    /* trinary logic                   */
#define ALL           ""
#define Nbby           8    /* number of bits/byte */

#define MAXARGS     1000    /* max arguments to exec                */
#define NFOLDERS    1000    /* max folder arguments on command line */
#define DMAXFOLDER     4    /* typical number of digits             */
#define MAXFOLDER   1000    /* message increment                    */

#ifndef FALSE
# define FALSE 0
#endif
#ifndef TRUE
# define TRUE 1
#endif
typedef unsigned char  boolean;  /* not int so we can pack in a structure */

/* If we're using gcc then give it some information about
** functions that abort.
*/
#if __GNUC__ > 2
# define NORETURN __attribute__((__noreturn__))
#else
# define NORETURN
#endif

/*
** we should be getting this value from pathconf(_PC_PATH_MAX)
*/
#ifndef PATH_MAX
# ifdef MAXPATHLEN
#  define PATH_MAX MAXPATHLEN
# else
   /* so we will just pick something */
#  define PATH_MAX 1024
# endif
#endif

/*
** we should be getting this value from sysconf(_SC_OPEN_MAX)
*/
#ifndef OPEN_MAX
# ifdef NOFILE
#  define OPEN_MAX NOFILE
# else
   /* so we will just pick something */
#  define OPEN_MAX 64
# endif
#endif

/*
** user context/profile structure
*/
struct node {
	char *n_name;         /* key                  */
	char *n_field;        /* value                */
	char n_context;       /* context, not profile */
	struct node *n_next;  /* next entry           */
};

/*
** switches structure
*/
#define AMBIGSW  (-2)    /* from smatch() on ambiguous switch */
#define UNKWNSW  (-1)    /* from smatch() on unknown switch   */

struct swit {
	char *sw;
	/*
	** The minchars field is apparently used like this:
	**
	** -# : Switch can be abbreviated to # chars; switch hidden in -help.
	** 0  : Switch can't be abbreviated;          switch shown in -help.
	** #  : Switch can be abbreviated to # chars; switch shown in -help.
	*/
	int minchars;
};

extern struct swit anoyes[];   /* standard yes/no switches */

/*
** general folder attributes
*/
#define READONLY      (1<<0)    /* No write access to folder    */
#define SEQMOD        (1<<1)    /* folder's sequences modifed   */
#define ALLOW_BEYOND  (1<<2)    /* allow the beyond sequence    */
#define OTHERS        (1<<3)    /* folder has other files       */

#define FBITS  "\020\01READONLY\02SEQMOD\03ALLOW_BEYOND\04OTHERS"

/*
** type for holding the sequence set of a message
*/
typedef unsigned int seqset_t;

/*
** internal messages attributes (sequences)
*/
#define EXISTS        (1<<0)    /* exists            */
#define SELECTED      (1<<1)    /* selected for use  */
#define SELECT_UNSEEN (1<<2)    /* inc/show "unseen" */

#define MBITS "\020\01EXISTS\02SELECTED\03UNSEEN"

/*
** first free slot for user-defined sequences
*/
#define FFATTRSLOT  3

/*
** Determine the number of user defined sequences we
** can have.  The first few sequence flags are for
** internal nmh message flags.
*/
#define NUMATTRS  ((sizeof(seqset_t) * Nbby) - FFATTRSLOT)

/*
** Primary structure of folder/message information
*/
struct msgs {
	int lowmsg;        /* Lowest msg number                 */
	int hghmsg;        /* Highest msg number                */
	int nummsg;        /* Actual Number of msgs             */

	int lowsel;        /* Lowest selected msg number        */
	int hghsel;        /* Highest selected msg number       */
	int numsel;        /* Number of msgs selected           */

	int curmsg;        /* Number of current msg if any      */

	int msgflags;      /* Folder attributes (READONLY, etc) */
	char *foldpath;    /* Pathname of folder                */

	/*
	** Name of sequences in this folder.  We add an
	** extra slot, so we can NULL terminate the list.
	*/
	char *msgattrs[NUMATTRS + 1];

	/*
	** bit flags for whether sequence
	** is public (0), or private (1)
	*/
	seqset_t attrstats;

	/*
	** These represent the lowest and highest possible
	** message numbers we can put in the message status
	** area, without calling folder_realloc().
	*/
	int    lowoff;
	int    hghoff;

	/*
	** This is an array of seqset_t which we allocate dynamically.
	** Each seqset_t is a set of bits flags for a particular message.
	** These bit flags represent general attributes such as
	** EXISTS, SELECTED, etc. as well as track if message is
	** in a particular sequence.
	*/
	seqset_t *msgstats;        /* msg status */
};

/*
** Amount of space to allocate for msgstats.  Allocate
** the array to have space for messages numbers lo to hi.
*/
#define MSGSTATSIZE(mp,lo,hi) ((size_t) (((hi) - (lo) + 1) * sizeof(*(mp)->msgstats)))

#define NULLMP  ((struct msgs *) 0)

/*
** m_getfld() message parsing
*/

#define NAMESZ  999        /*
                           ** Limit on component name size.
                           ** RFC 2822 limits line lengths to
                           ** 998 characters, so a header name
                           ** can be at most that long.
                           ** m_getfld limits header names to 2
                           ** less than NAMESZ, which is fine,
                           ** because header names must be
                           ** followed by a colon. Add one for
                           ** terminating NULL.
                           */

/* m_getfld2() returned data */
struct field {
	char name[NAMESZ];
	size_t namelen;
	char *value;
	size_t valuelen;
	size_t alloclen;
	boolean crlf;
};

/* m_getfld2() states */
enum state {
	LENERR2 = -2,      /* Line too long */
	FMTERR2 = -3,      /* Format error in message */
	IOERR2 = -1,       /* Read error */
	FLD2 = 0,          /* Header field returned */
	BODY2,             /* Body line returned */
	FILEEOF2           /* Reached end of input file */
};

#define NOUSE    0        /* draft being re-used */

#define OUTPUTLINELEN  72    /* default line length for headers */

/*
** miscellaneous macros
*/

#ifndef max
# define max(a,b) ((a) > (b) ? (a) : (b))
#endif

#ifndef min
# define min(a,b) ((a) < (b) ? (a) : (b))
#endif

/*
** GLOBAL VARIABLES
*/
#define CTXMOD  0x01        /* context information modified */
#define DBITS  "\020\01CTXMOD"
extern char ctxflags;

extern char *invo_name;      /* command invocation name         */
extern char *mypath;         /* user's $HOME                    */
extern char *mmhdir;
extern char *mmhpath;
extern char *defpath;        /* pathname of user's profile      */
extern char *ctxpath;        /* pathname of user's context      */
extern struct node *m_defs;  /* list of profile/context entries */
extern char *mailstore;      /* name of mail storage directory  */

/*
** These standard strings are defined in config.c.  They are the
** only system-dependent parameters in nmh, and thus by redefining
** their values and reloading the various modules, nmh will run
** on any system.
*/
extern char *attach_hdr;
extern char *sign_hdr;
extern char *enc_hdr;
extern char *components;
extern char *context;
extern char *curfolder;
extern char *defaulteditor;
extern char *defaultpager;
extern char *defaultfolder;
extern char *digestcomps;
extern char *distcomps;
extern char *draftfolder;
extern char *foldprot;
extern char *forwcomps;
extern char *inbox;
extern char *listproc;
extern char *mhetcdir;
extern char *mailspool;
extern char *mh_seq;
extern char *mhlformat;
extern char *mhlreply;
extern char *mimetypequery;
extern char *mimetypequeryproc;
extern char *msgprot;
extern char *nmhstorage;
extern char *nsequence;
extern char *profile;
extern char *psequence;
extern char *rcvdistcomps;
extern char *replcomps;
extern char *replgroupcomps;
extern char *scanformat;
extern char *sendmail;
extern char *seq_all;
extern char *seq_beyond;
extern char *seq_cur;
extern char *seq_first;
extern char *seq_last;
extern char *seq_next;
extern char *seq_prev;
extern char *seq_unseen;
extern char *seq_neg;
extern char *trashfolder;
extern char *usequence;
extern char *version;
extern char *lib_version;
extern char *whatnowproc;

#include <h/prototypes.h>
