//  This may look like C code, but it is really -*- C++ -*-

//  ------------------------------------------------------------------
//  The Goldware Library
//  Copyright (C) 1990-1999 Odinn Sorensen
//  ------------------------------------------------------------------
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Library General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Library General Public License for more details.
//
//  You should have received a copy of the GNU Library General Public
//  License along with this program; if not, write to the Free
//  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
//  MA 02111-1307, USA
//  ------------------------------------------------------------------
//  $Id$
//  ------------------------------------------------------------------

#ifndef __gs_max3_h
#define __gs_max3_h


//  ------------------------------------------------------------------

#include <gtimall.h>


//  ------------------------------------------------------------------

#if defined(GOLD_CANPACK)
    #pragma pack(1)
#endif


//  ------------------------------------------------------------------

typedef FTime SCOMBO;         // DOS-style bitmapped datestamp

typedef struct _netaddr
{
    word zone;
    word net;
    word node;
    word point;
} NETADDR;

typedef word zstr;            // Offset of string within area heap


//  ------------------------------------------------------------------

#define MSGTYPE_SDM     0x01
#define MSGTYPE_SQUISH  0x02

#ifdef PATHLEN
    #undef PATHLEN
#endif

#define PATHLEN           120 // Max. length of a path


//  ------------------------------------------------------------------
//  Menu server enumerations and structures

//  Enumeration `option' -- All possible values for menu.option[x].type

typedef enum
{
    nothing,

    MISC_BLOCK=100, display_menu, display_file, message, file, other,
    o_press_enter, key_poke, clear_stacked, o_if,
    o_menupath, o_cls, mex, link_menu, o_return,


    XTERN_BLOCK=200, xtern_erlvl, xtern_dos, xtern_run, xtern_chain,
    xtern_concur,

    MAIN_BLOCK=300, goodbye, statistics, o_yell, userlist, o_version,
    user_editor, leave_comment, climax,

    MSG_BLOCK=400, same_direction, read_next, read_previous,
    enter_message, msg_reply, read_nonstop,
    read_original, read_reply, msg_list, msg_scan,
    msg_inquir, msg_kill, msg_hurl, forward, msg_upload,
    xport, read_individual, msg_checkmail, msg_change,
    msg_tag, msg_browse, msg_current, msg_edit_user,
    msg_upload_qwk, msg_toggle_kludges, msg_unreceive,
    msg_restrict, msg_area, msg_track, msg_dload_attach,
    msg_reply_area,

    FILE_BLOCK=500, locate, file_titles, file_type, upload, download, raw,
    file_kill, contents, file_hurl, override_path,
    newfiles, file_tag, file_area,

    // Options generally found on the Change Setup menu

    CHANGE_BLOCK=600, chg_city, chg_password, chg_help, chg_nulls,
    chg_width, chg_length, chg_tabs, chg_more,
    chg_video, chg_editor, chg_clear, chg_ibm,
    chg_phone, chg_realname, chg_hotkeys,
    chg_language, chg_userlist, chg_protocol,
    chg_fsr, chg_archiver, chg_rip,

    EDIT_BLOCK=700, edit_save, edit_abort, edit_list, edit_edit,
    edit_insert, edit_delete, edit_continue, edit_to,
    edit_from, edit_subj, edit_handling, read_diskfile,
    edit_quote,

    // Stuff that was hacked on after the original implementation

    CHAT_BLOCK=800, who_is_on, o_page, o_chat_cb, chat_toggle, o_chat_pvt,

    END_BLOCK,


    // Everything below here is RESERVED by Maximus for future uses!
    // Also, everything ABOVE is fairly stable.  If changes have to be made,
    // the old options above will not be re-used.  For example, if the
    // `edit_insert' command should become obsoleted for some reason, that
    // slot would either get retired and do nothing, or perform the NEW
    // edit_insert function.

    rsvd=32766  // This was stuck in to make sure that the `option'
         // enumeration uses a word, instead of a byte, in case we
         // really expand this structure sometime soon.

} max_option __attribute__((packed));


//  ------------------------------------------------------------------
//  .prm file structure and definitions

typedef word OFS;

#ifndef MAX_DRIVES
    #define MAX_DRIVES           26   // Maximum number of drives on system
#endif

#ifndef CHAR_BITS
    #define CHAR_BITS             8   // Number of bits in a 'char'
#endif

#define CTL_VER               9   // Version number of bbs.prm

// This macro is ONLY used for accessing *pointers* in the `prm' structure.
// This is required, due to the way Wynn has made OPUS_CTL write the strings
// out (which uses a lot less memory than some other ways).  If you want
// to access an INT, or a non-pointer in the structure, then you can use
// a `prm.var_name'-style reference.

#define PRM(s) (offsets+(prm.s))

#define MAX_LANG             8       // Max. number of possible languages
#define MAX_YELL            10       // Max number of yell slots
#define MAX_EXTERNP         16       // max. number of external programs
#define ALIAS_CNT           15       // number of matrix addresses
#define MAXCLASS            12       // OBSOLETE!  Only used for
// compatibility with Max 2.x.

// OBSOLETE!  Only used for compatibility purposes

struct   cl_rec
{
    int16_t  priv;
    word     max_time;      // max cume time per day
    word     max_call;      // max time for one call
    word     max_dl;        // max dl kbytes per day
    word     ratio;         // ul:dl ratio
    word     min_baud;      // speed needed for logon
    word     min_file_baud; // speed needed for file xfer
};


// Note: To read in the *.PRM structure, first read in the m_pointers
// structure, which is always contained at the beginning of the file.
// Then, seek to the offset prm.heap_offset, and read in everything
// from there to EOF into heap[].  All of the 'OFS' type variables
// are simply offsets into the variable-length heap which started at
// heap_offset. To obtain a string from the .PRM heap, simply
// add the offset in the m_pointers structure to the address of the
// heap[] variable that the heap was read into.  For example, to access
// the string for 'system_name', you'd use '(heap+prm.system_name)'.
// Alternatively, you can declare a macro to do this, such as the
// PRM() macro shown above.  (Maximus itself uses the variable
// 'strings' instead of 'heap' to hold the varible-length strings,
// but the concept is the same.)  When using the PRM() macro to
// access the string for 'system_name', you'd simply write:
// 'PRM(system_name)', which is a lot clearer.  Also, please note that
// NON-OFS variables should be accessed normally!  That means that
// 'task_num', 'auto_kill', can be access with 'prm.task_num',
// 'prm.auto_kill', etc.  The special heap manipulation is only needed
// for strings.

struct m_pointers
{

// DATA

    byte    id;           /* Always equal to 'M'               STABLE  */
    byte    version;      /* for safety                        STABLE  */
    word    heap_offset;  /* OFFSET OF BEGINNING OF HEAP!      STABLE  */
    byte    task_num;     /* for multi-tasking systems         STABLE  */
    int16_t com_port;     /* Com1=0, Com2=1, etc               STABLE  */
    byte    noise_ok;     /* If yell noise is currently on     STABLE  */

    /* Miscellanious system information */

    byte    video;        /* Mode for local video display              */
    byte    log_mode;     /* What style of logging to use              */
    word    max_baud;     /* fastest speed we can use                  */
    int8_t  multitasker;  /* flag for DoubleDos (see below)            */
    byte    nlver;        /* Which nodelist version we use (NLVER_XXX) */

    int16_t min_ulist;    /* OBSOLETE!  Only used for compatibility    */
    int16_t max_ulist;    /* with Maximus 2.x!                         */

    /* Information about errorlevels */

    byte  exit_val;       /* Erl to use after caller if none of below  */
    byte  edit_exit;      /* erl to use after matrix mail written      */
    byte  echo_exit;      /* ERRORLEVEL for after inbound echomail     */
    byte  local_exit;     /* Errorlevel after entering local msgs      */

    /* Modem information */

    int16_t carrier_mask;
    int16_t handshake_mask;

    /* Log-on information */

    word logon_priv;      /* Access level for new users                */
    word  logon_time;     /* time to give for logons                   */
    word  min_baud;       /* minimum baud to get on-line               */
    word  speed_graphics; /* min baud for graphics                     */

    /* Information about message areas */

    byte  auto_kill;      /* RECD PVT msgs. 0=no 1=ask 2=yes           */

    word ctla_priv;       /* Priv to see CONTROL-A lines in messages   */
    word seenby_priv;     /* Min priv to see SEEN-BY line              */
    word pvt_priv;        /* Min priv to read pvt msgs                 */

    word msg_ask[16];     /* Array of privs. for message attr ask's    */
    word msg_assume[16];  /* Array of privs. for message attr assume's */
    word  msg_fromfile;   /* Priv. for doing message from file         */
    word  speed_rip;      /* min baud for rip graphics                 */
    byte  rsvd1[2];       /* used to be high_msgarea, begin_msgarea    */
    word unlisted_priv;   /* Priv needed to send to unlisted node      */
    int16_t unlisted_cost;  /* Charge to send to unlisted node           */

    word mc_reply_priv;   /* Priv to reply to msg with mailchecker     */
    word mc_kill_priv;    /* Priv to kill msg with mailchecker         */


    /* Information about file areas */

    int16_t date_style;   /* Used for FILES.BBS display                */
    word rsvd20;          /* Reserved (used to be dlall_priv)          */
    word rsvd21;          /* Reserved (used to be ulbbs_priv)          */
    dword k_free;         /* The number of disk space (in K) which     *
                         * must be available before we let a user    *
                         * upload.                                   */
    word  rsvd7;          /* reserved - used to be upload reward       */
    word  ratio_threshold;/* OBSOLETE!  Only used for Max 2.x compat.  */
    byte  rsvd2[4];       /* used to be high_filearea, begin_filearea  */

    /* Our matrix address(es) */

    NETADDR address[ALIAS_CNT];

    byte rsvd3[60]; /* Reserved by Maximus for future use */

    /* About the users */
    struct cl_rec cls[MAXCLASS];  /* OBSOLETE!  Only used for compatibility */
    /* with Maximus 2.x.                      */

    /* Flags for external protocols */

    int16_t protoexit;            /* Errorlevel for protocol exit      */
    char  protoflag[MAX_EXTERNP];

    /* General-purpose bit-flags  (See FLAGx_xxx definitions above.) */

    word  flags;
    word  flags2;
    word  flags3;
    word  flags4;

    /* Bit field containing drive letters to save when going outside */
    char  drives_to_save[(MAX_DRIVES/CHAR_BITS)+1];

    byte  fbbs_margin;      /* Margin to use for wrapping FILES.BBS comments */
    byte  kill_attach;      /* Kill file attaches 0=no 1=ask 2=yes           */

    word  max_ptrs;         /* Maximum size of pointers of ALL *.LTFs */
    word  max_heap;         /* Maximus heap size of all *.LTFs */
    byte  max_lang;         /* Current number of languages */
    byte  rsvd_lang;

    word  max_glh_ptrs;
    word  max_glh_len;

    word  max_syh_ptrs;
    word  max_syh_len;

    byte  input_timeout;   /* # of mins until Max hangs up due to no input    */

    byte  charset;         /* Character set support - see CHARSET_XXXX, above */
    word  max_pack;        /* Maximum # of msgs to pack into a .QWK packet    */
    word  msg_localattach; /* Priv. for doing local file attaches             */
    word  kill_attach_priv;/* Priv. for killing local file attaches           */
    word  mcp_sessions;    /* Max number of MCP sessions                      */
    dword max_msgsize;     /* Truncate uploaded messages to this size         */

    byte  rsvd65[2];       /* Reserved by Maximus for future use              */

// OFFSETS

    /* About your system */

#define PRM_HEAP_START sysop

    OFS   sysop;          /* sysop's name. MUST be first offset in prm file */
    OFS   system_name;    /* board's name                              */

    /* Modem commands */

    OFS   m_busy;         /* mdm cmd to take modem off hook            */

    /* Paths to various places */

    OFS   sys_path;       /* path to SYSTEM?.BBS files                 */
    OFS   misc_path;      /* path to `F-key files'                     */
    OFS   net_info;       /* path to NODELIST files                    */
    OFS   temppath;       /* place to put temporary files              */
    OFS   ipc_path;       /* path for inter-process communications     */

    /* General files needed by the system */

    OFS   user_file;      /* path/filename of User.Bbs                 */
    OFS   log_name;       /* name of the log file                      */
    OFS   chat_prog;      /* External chat program, if any             */
    OFS   chat_fbegin;    /* File to display instead of "CHAT: begin"  */
    OFS   chat_fend;      /* File to display instead of "END CHAT"     */
    OFS   local_editor;   /* Command for local editor, if any          */
    OFS   notfound;       /* User name not found in user file          */
    OFS   junk;           /* Don't use this for anything!              */

    /* General *.?BS files needed everywhere */

    OFS   logo;           /* first file shown to a caller              */
    OFS   bad_logon;      /* if user's last logon attempt was bad      */
    OFS   welcome;        /* shown after logon                         */
    OFS   quote;          /* For displaying "random" quotes from       */
    OFS   newuser1;       /* Asks user to type in password             */
    OFS   newuser2;       /* Replaces `welcome' for a new user         */
    OFS   rookie;         /* Replaces `welcome' for rookies            */
    OFS   application;    /* new user questionnaire                    */
    OFS   byebye;         /* file displayed at logoff                  */
    OFS   out_leaving;    /* Bon Voyage                                */
    OFS   out_return;     /* Welcome back from O)utside                */
    OFS   daylimit;       /* Sorry, you've been on too long...         */
    OFS   timewarn;       /* warning about forced hangup               */
    OFS   tooslow;        /* explains minimum logon baud rate          */
    OFS   barricade;      /* Displayed before prompt for access code   */
    OFS   shelltodos;     /* Displayed when Sysop hits Alt-J           */
    OFS   backfromdos;    /* Displayed when Sysop returns from Alt-J   */
    OFS   areanotexist;   /* File to display instead of "That area     *
                         * doesn't exist!"                           */

    /* User priv levels database */

    OFS   access;         /* Database of user privilege levels         */

    /* File-area items */

    OFS   xferbaud;       /* explains minimum file transfer baud rate  */
    OFS   file_area_list; /* dump file... used instead of Dir.Bbs      */
    OFS   no_space;       /* File to display if trying to UL with      *
                         * less than k_free space left on drive.     */
    OFS   fname_format;   /* Essay on MS-DOS filenames for U)ploads    */
    OFS   ul_log;         /* Log file for uploads                      */

    OFS   file_header;    /* Format for file area's A)rea command      */
    OFS   file_format;    /* Format for A)rea command entries          */
    OFS   file_footer;    /* Format for footer for file.area menu      */

    OFS   proto_dump;      /* Dump file for protocol screen            */

    /* Message-area items */

    OFS   msgarea_list;   /* dump file... used instead of Dir.Bbs      */
    OFS   echotoss_name;  /* Name of your echomail tosslog             */
    OFS   nomail;         /* Display by mailchecker if no mail wtng.   */

    OFS   msg_header;     /* Format for msg.area's A)rea command       */
    OFS   msg_format;     /* Format for A)reas command entries         */
    OFS   msg_footer;     /* Format for footer for msg.area menu       */

    /* Help files:  Used to explain various things */

    OFS   hlp_editor;     /* intro to msg editor for novices.          */
    OFS   hlp_replace;    /* Explain the Msg.Editor E)dit command      */
    OFS   msg_inquire;    /* Explain the Msg. I)nquire command         */
    OFS   hlp_locate;     /* Explain the Files L)ocate command         */
    OFS   hlp_contents;   /* Explain the Files C)ontents command       */
    OFS   oped_help;      /* help file for the full-screen editor      */
    OFS   hlp_scan;       /* help file for S)can                       */
    OFS   hlp_list;       /* help file for L)ist                       */

    /* External protocols */

    OFS   protocols[MAX_EXTERNP]; /* external file protocol programs   */
    OFS   protoname[MAX_EXTERNP]; /* name of protocol, on menu         */

    /* Date/Time format strings */

    OFS   timeformat;
    OFS   dateformat;

    /* **OBSOLETE** names of the old Max 2.x area.dat/idx files */

    OFS   adat_name;
    OFS   aidx_name;

    /* Menu paths/names */

    OFS   menupath;        /* The default place to look for the menus */
    OFS   first_menu;      /* The name of the first menu to display */
    OFS   edit_menu;       /* Name of the EDIT menu */

    /* Miscellaneous */

    OFS   achg_keys;       /* Characters used to change area -/+ */
    OFS   tune_file;       /* Path to TUNES.MAX */
    OFS   lang_path;       /* Path to *.LTF files */

    OFS   lang_file[MAX_LANG]; /* Array of all *.LTF names */

    OFS   m_init;          /* Modem initialization string */
    OFS   m_ring;          /* Command modem sends when phone ringing */
    OFS   m_answer;        /* Cmd to send to modem when ring detect */
    OFS   m_connect;       /* Connect string, as returned by modem */

    OFS   high_msgarea;
    OFS   begin_msgarea;  /* Msg area to put new users in              */

    OFS   high_filearea;
    OFS   begin_filearea; /* File area to put new users in             */

    OFS   fidouser;       /* Name of FIDOUSER.LST file to use          */
    OFS   cmtarea;        /* Message area to put comments in           */

    OFS   arc_ctl;        /* Control file for archiving programs       */
    OFS   olr_name;       /* OLR: Filename to use for DL packets       */
    OFS   olr_dir;        /* OLR: Directory for off-line stuff         */
    OFS   phone_num;
    OFS   viruschk;       /* Name of batch file to call for virus check*/
    OFS   protocol_max;   /* Name of compiled protocol data file       */
    OFS   track_privview; /* Priv req'd to see tracking info owned by others */
    OFS   track_privmod;  /* Priv req'd to modify track info owned by others */
    OFS   track_base;     /* Base name of the tracking database files  */
    OFS   track_exclude;  /* File containing list of names to exclude  */
    OFS   stagepath;      /* Path for staged CD-ROM transfers          */
    OFS   attach_base;    /* Base name of the local attach database    */
    OFS   attach_path;    /* Default path for local file attaches      */
    OFS   attach_archiver;/* File attach archiver                      */
    OFS   inbound_files;  /* Inbound FTS-1 attaches for users          */
    OFS   rippath;        /* Default icon & RIP screens path           */

    /* More help files */

    OFS   hlp_hdrentry;   /* Help screen for message header entry      */
    OFS   hlp_msgentry;   /* Help screen for start of message entry    */
    OFS   not_configured; /* Displayed if user is not configured       */

    /* MCP stuff */

    OFS   mcp_pipe;       /* Default MCP pipe                          */

    /* Paths to the new marea/farea message/file data files */

    OFS   marea_name;     /* Name of message area data file            */
    OFS   farea_name;     /* Name of file area data file               */

    /* Caller information log */

    OFS   caller_log;     /* Caller information log                    */

#define PRM_HEAP_END caller_log
};


//  ------------------------------------------------------------------
//  General structure of MAREA.DAT and FAREA.DAT:
//  MAREA_ID or FAREA_ID
//  _msgarea
//     _ovride ...
//     zstr heap
//  _msgarea
//     _ovride ...
//     zstr heap
//  eof


// This key is present at the beginning of an area file.  MAREA_ID is
// used for the message data file and FAREA_ID is used for the
// file data file.

#define MAREA_ID      0x1a49023fL
#define FAREA_ID      0x1a01953aL

struct _ovride
{

    /* Only one of 'opt' or 'name' should be used.  If opt==0, use name.  If  *
     * name==0, use opt.                                                      */

    max_option opt;       /* Type of menu option to override     ...OR...     */
    byte   name;          /* First letter of command to override              */
    byte   rsvd1;         /* Reserved for future use                          */
    zstr   acs;           /* New ACS required to access option                */
    zstr   menuname;      /* Use this access level on the given menu only     */
};


//  ------------------------------------------------------------------
//  Bit masks for the ma.attribs field

#define MA_PVT      0x0001  /* Private msgs allowed */
#define MA_PUB      0x0002  /* Public msgs allowed */
#define MA_HIBIT    0x0004  /* High bit msgs allowed */

#define MA_NET      0x0008  /* Netmail area */
#define MA_ECHO     0x0010  /* Echomail area */
#define MA_CONF     0x0020  /* Conference area */

#define MA_ANON     0x0040  /* Anonymous messages are OK */
#define MA_NORNK    0x0080  /* Don't use the REALNAME kludge for this area */
#define MA_REAL     0x0100  /* Force  use of       real name for this area */
#define MA_ALIAS    0x0200  /* Force  use of alias      name for this area */
#define MA_AUDIT    0x0400  /* Use auditing (msg tracking) controls in area*/
#define MA_READONLY 0x0800  /* Area is read-only */
#define MA_HIDDN    0x1000  /* Area does not display on normal area list   */
#define MA_ATTACH   0x2000  /* Area allows local file attaches             */
#define MA_DIVBEGIN 0x4000  /* A message area division, not a real area    */
#define MA_DIVEND   0x8000  /* End of the message area division            */

#define MA2_NOMCHK  0x0001  /* Don't do personal mail check in this area   */

#define MA_SHARED   (MA_ECHO | MA_CONF)


struct _msgarea
{

    word cbArea;          /* Length of THIS INDIVIDUAL RECORD                0*/
    word num_override;    /* Number of overrides following this record       2*/
    word cbHeap;          /* Length of the zstr heap following the overrides 4*/
    word division;        /* Reserved for future use                         6*/
    zstr name;            /* String format of area's name.                   8*/
    zstr acs;             /* Access control string for this area            10*/
    zstr path;            /* Path to messages (but for MA_DIVBEGIN only,    12*
                         * used instead as name of custom .bbs file).       */
    zstr echo_tag;        /* The 'tag' of the area, for use in ECHOTOSS.LOG 14*/
    zstr descript;        /* The DIR.BBS-like description for msg section   16*/
    zstr origin;          /* The ORIGIN line for this area                  18*/
    zstr menuname;        /* Custom menu name                               20*/
    zstr menureplace;     /* Replace this menu name with menuname from above22*/

    word attribs;         /* Attributes for this area                       24*/

    NETADDR primary;      /* Use as primary address for this area           26*/
    NETADDR seenby;       /* Use as address in seen-bys                     34*/
    word attribs_2;       /* More attributes                                42*/
    word type;            /* Message base type.  MSGTYPE_SDM = *.MSG.       44*
                         * MSGTYPE_SQUISH = SquishMail.  (Constants are     *
                         * in MSGAPI.H)                                     */
    word killbyage;       /* Make sure msgs are less than X days old        46*/
    word killbynum;       /* Make sure there are less than X msgs           48*/
    word killskip;        /* Exempt the first X msgs from this processing   50*/
    zstr barricade;       /* Barricade file                                 52*/
    zstr barricademenu;   /* Apply barricade priv while using this menu     54*/
    int32_t cbPrior;      /* Seek offset from start of this area to get back56*
                         * to prior area.                                   */
    zstr attachpath;      /* Reserved for future use                        58*/
    dword rsvd4;                                                          /*60*/
};                                                                      /*64*/


//  -----------------------------------------------------------------

#if defined(GOLD_CANPACK)
    #pragma pack()
#endif


//  -----------------------------------------------------------------

#endif // __gs_max3_h

//  -----------------------------------------------------------------
