#ifndef MM_H_
#define MM_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.
 */

#include "args.h"			/* must come first: might define const */

#ifdef RCSID
#ifndef lint
static const char *mm_rcsid = "$Header: /usr/local/src/mm/mm-0.94/mm/RCS/mm.h,v 1.2 2005/05/28 22:27:14 beebe Exp $";
#endif
#endif /* RCSID */

#include <stdio.h>
#include "config.h"			/* site configuration file */
#include "osfiles.h"			/* standard system header files */
#include "compat.h"			/* compatibility macros */
#include "chartype.h"			/* private version of <ctype.h> */
#include "pathnames.h"			/* filename defaults */
#include "address.h"			/* address list definitions */

#define true	1
#define false	0
#define nil	NULL			/* XXX */

#if MDEBUG
#define calloc(n,e)	dcalloc((int)(n),(int)(e))
#define cmrealloc(p,n)	safe_realloc((void*)(p),(int)(n))
#define free(p)		dfree((void*)(p))
#define malloc(n)	dmalloc((int)(n))
#define realloc(p,n)	drealloc((void*)(p),(int)(n))
extern void *dcalloc ARGS((int nelem_, int elsize_));
extern void *dmalloc ARGS((int size_));
extern void *drealloc ARGS((void *bp_, int size_));
extern void dfree ARGS((void *cp_));
#endif

/*
 * Global state flags
 */
#define MM_TOP_LEVEL	0x00		/* in the top-level command parser */
#define MM_READ		0x01		/* in "read mode" */
#define MM_SEND		0x02		/* in "send mode" */
#define MM_REPLY	0x04		/* replying to a sequence */
#define MM_ANSWER	0x08		/* answering a message */
#define MM_BROWSE	0x10		/* browsing a file */

/* NHFB: [02-Apr-1996] These constants were originally set at 64, 256,
and 512.  In mm.c, CMDBUFLEN is set to 10*BUFLEN, and that variable is
the maximum size of a command line, INCLUDING expanded indirect files.
Since the latter may contain rather long lists of mailing addresses,
we enlarge BUFLEN drastically so as to support 1MB command lines,
which is very likely big enough. Making this change increased mm on
Sun SPARC Solaris 2.5 from size 826444 + 112584 + 72760 = 1011788 to
size 831508 + 112584 + 4572728 = 5516820; the difference is marginally
more than the size of the 1MB int array, cmdbuf[], in mm.c.

A project for future work in ccmd might be to dynamically reallocate
buffers, instead of raising a CMxBOVF error.

The command buffer data should have had its own private type, instead
of being declared as int: only 16 bits are used (because of IBM PC
limits), but unfortunately, the int assumption pervades the code in
ccmd.  Also, only 7-bit characters are supported, because the 8th bit
is used for the CC_QUO flag.  It might be feasible to remove that
restriction by moving CC_QUO to bits 14, 15, or 16, but care would
have to be taken to locate all places where bit 8 is cleared.  And we
really should consider a Unicode future... More ideas for possible
later implementation! */

#define KEYLEN	64			/* header keyword size */
#define STRLEN	256			/* string length */
#define BUFLEN	102400			/* size of parse buffers, etc */

typedef char keyword[KEYLEN];		/* XXX this is a bad idea... */
typedef char buffer[BUFLEN];
typedef char string[STRLEN];
typedef char **keylist;

#include "seq.h"

/*
 * variables accessible to the user are defined using the "variable" type.
 */

typedef struct {
    const char *name;			/* variable name */
    int type;				/* variable type */
    char *addr;				/* address of the variable */
    int size;				/* max length for string variables */
    int changed;			/* modified by user? */
} variable;

/*
 * i don't think this structure isn't used right now
 */

typedef struct address {
    char *name;				/* name for a group list, or ";" */
    char *phrase;			/* introductory comment */
    char *route;			/* route */
    char *user;				/* local-part */
    char *host;				/* domain */
    char *comment;			/* comment from parens */
    struct address *next;		/* next addr in list */
    struct address *sublist;		/* sublist if group list */
} address;

#define M_SEEN		0001		/* seen */
#define M_DELETED	0002		/* deleted */
#define M_FLAGGED	0004		/* flagged */
#define M_ANSWERED	0010		/* answered */
#define M_FILED		0020		/* filed */
#define M_RECENT	0040		/* recent */
#define M_MODIFIED	0100		/* message flags modified */
#define M_EDITED	0200		/* edited the message text */
#define M_FORWARDED	0400		/* forwarded the message */
#define M_INTERNAL	~(M_MODIFIED|M_RECENT)	/* flags stored in file */

/*
 * The message struct describes a single message in a mail file
 */
typedef struct {
    long offset;			/* position in file */
    unsigned long size;			/* message size */
    unsigned long flags;		/* message flags */
    unsigned long keybits;		/* funky keyword bits */
    char *from;				/* sender */
    time_t date;			/* date received */
    char *text;				/* address in memory */
    char *hdrsum;			/* cached line for "headers" cmd */
    int next;				/* next message in sequence */
    int prev;				/* previous message in sequence */
    char **keywords;			/* list of keywords */
} message;

#define MF_MAILBOX	0x01		/* user's primary mailbox  */
#define MF_SPOOL	0x02		/* user's spool file */
#define MF_RDONLY	0x04		/* read-only mode */
#define MF_DIRTY	0x08		/* mail file is dirty */
#define MF_MODIFIED	0x10		/* some flags have been changed */
#define MF_WRITERR	0x20		/* write error */
#define MF_SAVEONLY	0x40		/* save even if read-only */

/*
 * msgvec describes a mail file
 */

typedef struct Msgvec {
    string filename;			/* name of the file these came from */
    time_t when_read;			/* when we opened the file */
    time_t mtime;			/* file's mtime when we opened it */
    FILE *filep;			/* pointer to the file */
    int type;				/* what type of mail file is it? */
    unsigned long flags;		/* message flags */
    int current;			/* current message number */
    int last_read;			/* last message read from the file */
    int count;				/* total number of messages in file */
    unsigned long size;			/* length of file (in bytes) */

    sequence_t sequence;		/* current message sequence */
    sequence_t prev_sequence;		/* previous message sequence */
    sequence_t read_sequence;		/* read sequence */

    /* note that we waste the zeroth entry of this array -- it's never used */
    message *msgs;			/* pointer to the message array */
    keylist keywords;			/* keywords for this file */
} msgvec;

/* exit codes for getmsg (send.c and sendcmds.c) */
#define GET_EDIT  1
#define GET_ESC   2
#define GET_CTRLD 3
#define GET_ABORT 4

/* flags for the update() routine */
#define UPD_ALWAYS	0x01
#define UPD_SAVEMOD	0x02
#define UPD_EXPUNGE	0x04
#define UPD_ALTFILE	0x08
#define UPD_QUIET	0x10

/* a few things for yesno and yesnoask variables */
#define SET_ASK -1
#define SET_NO 0
#define SET_NEVER 0
#define SET_YES 1
#define SET_ALWAYS 1

#include "extern.h"			/* external declarations */

#if defined(__STDC__)
/* introduce some forced casts to eliminate many compiler warnings */
#if defined(__solaris)
/* I think that unistd.h has the type of arg 2 wrong.  !!!CHECK THIS!!! */
#define execvp(file,argv) (execvp)((const char *)(file),(char * const *)(argv))
#endif
#endif

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

#endif /* MM_H_ */
