/***************************************************************************\
*             MSGBASE.H - Message base header file                          *
*****************************************************************************
*                                                                           *
*                     MB_lib (MsgBase library) V1.00                        *
*            (Hudson message base access / manipulation routines)           *
*                                                                           *
*      This C version (c) F.W. van Wensveen 1993. All rights reserved.      *
*  Original Pascal source code (c) Richard Faasen and In Fase productions,  *
*                             The Netherlands.                              *
*                                                                           *
*                       First revision: 17/08/1992                          *
*                                                                           *
\***************************************************************************/


/* First, a C++ fixup ******************************************************/

#ifndef __MB_LIB_H
#define __MB_LIB_H

#ifdef __cplusplus
extern "C" {
#endif


/* Includes and defines ****************************************************/

#include <dir.h>

#define HCR    0x0D                    /* Hard carriage return             */
#define SCR    0x8D                    /* Soft carriage return             */
#define LF     0x0A                    /* Line feed                        */
#define KLUDGE 0x01                    /* Kludge denominator               */
#define BELL   0x07                    /* Bell character / ring a ding     */

#define NOKLUDGES 0x00                 /* txt_dump shouldn't dump kludges  */
#define KLUDGES   0x01                 /* txt_dump should dump kludges     */

/* Critical errors */
#define NOT_ERR 0x00                   /* No error                         */
#define MEM_ERR 0x01                   /* Memory error - out of memory     */
#define FRD_ERR 0x02                   /* File read error                  */
#define FWR_ERR 0x03                   /* File write error                 */
#define FCR_ERR 0x04                   /* File create error                */
#define MNO_ERR 0x05                   /* Message base not open error      */
#define IRN_ERR 0x06                   /* Invalid record no., out of bound */
#define MBC_ERR 0x07                   /* Msg base corrupt                 */

#define MA_DELETED      0x01           /* Message attributes               */
#define MA_UNSENT       0X02
#define MA_NETMAIL      0X04
#define MA_PRIVATE      0X08
#define MA_RECEIVED     0X10
#define MA_UNMOVED      0X20
#define MA_LOCAL        0X40

#define NA_KILL         0X01           /* Hudson netmail attributes        */
#define NA_SENT         0X02
#define NA_FILE         0X04
#define NA_CRASH        0X08
#define NA_RECEIPT      0X10
#define NA_AUDIT        0X20
#define NA_RETURN       0X40

#define NM_PRIVATE      0X0001         /* Opus (*.MSG) Netmail attributes   */
#define NM_CRASH        0x0002
#define NM_RECEIVED     0x0004
#define NM_SENT         0x0008
#define NM_FILE         0x0010
#define NM_TRANSIT      0x0020
#define NM_ORPHAN       0x0040
#define NM_KILL         0x0080
#define NM_LOCAL        0x0100
#define NM_HOLD         0x0200
#define NM_UNUSED       0x4000
#define NM_REQUEST      0x0800
#define NM_RECEIPT      0x1000
#define NM_ISRECEIPT    0x2000
#define NM_AUDIT        0x4000
#define NM_UPDATEREQ    0x8000


/**************************** C A U T I O N ********************************/
/* The strings in the Hudson message base files are all Pascal convention  */
/* strings - a length byte followed by the actual characters.              */
/* I have attempted to maintain this format by defining the strings as a   */
/* structure containing a length byte and a character array, but this      */
/* lead to too much trouble from the programmers point of view. So the     */
/* strings in the following structure are just defined as arrays of chars. */
/* They may only be read from and written to disk using the read and write */
/* functions in this library, which convert the string formats from Pascal */
/* to C format and vice versa. THEY MAY NOT BE READ AND WRITTEN DIRECTLY!! */
/* Writing structures to the message base by any other means than the      */
/* functions provided therefore will cause corruption of the message base. */
/***************************************************************************/

typedef struct {                       /* MSGINFO.BBS structure definition */
  unsigned int low_msg;                /* Lowest msg # in message base     */
  unsigned int high_msg;               /* Highest msg # in message base    */
  unsigned int total_msgs;             /* Total # of messages in base      */
  unsigned int total_on_board [200];   /* Number of messages / board       */
} MSGINFO_RECORD;

typedef struct {                       /* MSGIDX.BBS structure definiton   */
  int msg_num;                         /* Message #                        */
  unsigned char board;                 /* Board # where msg is stored      */
} MSGIDX_RECORD;

typedef char MSGTOIDX_RECORD [36];     /* MSGTOIDX.BBS structure def.      */

typedef struct {                       /* MSGHDR.BBS structure definition  */
  int msgnum;                          /* Message number                   */
  unsigned int prev_reply;             /* Msg # of previous reply, 0 if no */
  unsigned int next_reply;             /* Msg # of next reply, 0 if none   */
  unsigned int times_read;             /* # of times msg was read, UNUSED  */
  unsigned int start_block;            /* Record # of msg in MSGTXT.BBS    */
  unsigned int num_blocks;             /* # of records in MSGTXT.BBS       */
  unsigned int dest_net;               /* Destination net                  */
  unsigned int dest_node;              /* Destination node                 */
  unsigned int orig_net;               /* Origin net                       */
  unsigned int orig_node;              /* Origin node                      */
  unsigned char dest_zone;             /* Destination zone                 */
  unsigned char orig_zone;             /* Origin zone                      */
  unsigned int cost;                   /* Cost (Netmail)                   */
  unsigned char msg_attr;              /* Msg attributes. Bits as follows: */
                                       /* 0 : Deleted                      */
                                       /* 1 : Unsent                       */
                                       /* 2 : Netmail                      */
                                       /* 3 : Private                      */
                                       /* 4 : Received                     */
                                       /* 5 : Unmoved outgoing echo        */
                                       /* 6 : Local                        */
                                       /* 7 : RESERVED                     */
  unsigned char net_attr;              /* Netmail attributes. Bits follow: */
                                       /* 0 : Kill/Sent                    */
                                       /* 1 : Sent                         */
                                       /* 2 : File attach                  */
                                       /* 3 : Crash                        */
                                       /* 4 : Receipt request              */
                                       /* 5 : Audit request                */
                                       /* 6 : Is a return receipt          */
                                       /* 7 : RESERVED                     */
  unsigned char board;                 /* Message board #                  */
  char post_time [6];                  /* Time message was posted          */
  char post_date [9];                  /* Date message was posted          */
  char who_to [36];                    /* Recipient to whom msg is sent    */
  char who_from [36];                  /* Sender who posted message        */
  char subject [73];                   /* Subject line of message          */
} MSGHDR_RECORD;

typedef struct {                       /* MSGTXT.BBS structure definition  */
  unsigned char str_len;               /* This string is stored in memory  */
  char str_txt [255];                  /*  in Pascal format to reduce      */
} MSGTXT_RECORD;                       /*  overhead, so take care!         */


/* The strings in the *.MSG file header (Opus style) aren't Pascal type    */
/* strings but have the 'normal' ASCIIZ  format.                           */

typedef struct {                       /* OPUS-style (*.MSG) msg format    */
  char who_from [36];                  /* Sender who posted message        */
  char who_to [36];                    /* Recipient  to whom msg is sent   */
  char subject [72];                   /* Subject line of message          */
  char datetime [20];                  /* Date/time msg was last edited    */
  unsigned int times_read;             /* # of times message was read      */
  unsigned int dest_node;              /* Destination node                 */
  unsigned int orig_node;              /* Origin node                      */
  unsigned int cost;                   /* Cost to send netmail msg         */
  unsigned int orig_net;               /* Origin net                       */
  unsigned int dest_net;               /* Destination net                  */
  unsigned int dest_zone;              /* Destination zone  (These fields) */
  unsigned int orig_zone;              /* Origin zone       (were padded ) */
  unsigned int dest_point;             /* Destination point (with 8 0's  ) */
  unsigned int orig_point;             /* Origin point      (in FSC-0001 ) */
  unsigned int reply_to;               /* Msg # to which this one replies  */
  unsigned int attribute;              /* Msg attributes. Bits as follows: */
                                       /* 0  : Private                     */
                                       /* 1  : Crash                       */
                                       /* 2  : Received                    */
                                       /* 3  : Sent                        */
                                       /* 4  : File attached               */
                                       /* 5  : In transit                  */
                                       /* 6  : Orphan                      */
                                       /* 7  : Kill when sent              */
                                       /* 8  : Locak                       */
                                       /* 9  : Hold for pickup             */
                                       /* 10 : UNUSED                      */
                                       /* 11 : File request                */
                                       /* 12 : Return receipt request      */
                                       /* 13 : Is a return receipt         */
                                       /* 14 : Audit request               */
                                       /* 15 : File update request         */
  unsigned int next_reply;             /* Next msg in reply chain          */
} NET_RECORD;

/* Message text is stored as follows: a linked list of records contains    */
/* pointers to a MSGTXT record. This record contains 255 bytes of message  */
/* text. This Message Text Block List (MTBL) can be changed at will.       */
/* Because the programmer won't work with the 'raw' message text in RAM    */
/* directly, the string format of the message text is *not* converted. The */
/* text blocks contain the strings in Pascal format.                       */

typedef struct __mtbl__ {              /* Element of Msg Text Block List   */
  MSGTXT_RECORD * txt;                 /* Pointer to text block            */
  struct __mtbl__ * next;              /* Pointer to next struct in list   */
} MTBL;

typedef MTBL * M_TEXT;                 /* Text handle - ptr to MTBL start  */


/* Public data *************************************************************/

extern MSGINFO_RECORD msginfo;         /* Global MSGINFO record            */
extern int _Cdecl errortype;           /* Indicate type of error occurred  */
extern char _Cdecl errorstring [];     /* Printable string with error msg. */


/* Macro's and prototypes **************************************************/

/* Manipulating message text in memory */
M_TEXT        txt_new (char *);                  /* Create new text        */
int           txt_add (M_TEXT, char *);          /* Add a line of text     */
void          txt_dispose (M_TEXT);              /* Dispose of text        */
int           txt_dump (M_TEXT, int (*) (char *), unsigned char,
                        unsigned char);          /* Dump message text      */

/* Message base file access */
int           msg_open (char *);                 /* Open message base      */
void          msg_close (void);                  /* Close message base     */

/* Message base file locking */
int           msg_lock (char *);                 /* Lock message base      */
void          msg_unlock (void);                 /* Unlock message base    */

/* Reading message base */
int           msg_read_info (void);                   /* Read MSGINFO.BBS  */
int           msg_read_hdr (long, MSGHDR_RECORD *);   /* Read MSGHDR.BBS   */
int           msg_read_idx (long, MSGIDX_RECORD *);   /* Read MSGIDX.BBS   */
int           msg_read_toidx (long, MSGTOIDX_RECORD *);   /* The same with */
M_TEXT        msg_read_text (MSGHDR_RECORD *);   /* Read text 4 spec'd msg */

/* Writing message base */
int           msg_write_info (void);                  /* Write MSGINFO.BBS */
int           msg_write_hdr (long, MSGHDR_RECORD *);  /* Write MSGHDR.BBS  */
int           msg_write_idx (long, MSGIDX_RECORD *);  /* Write MSGIDX.BBS  */
int           msg_write_toidx (long, MSGTOIDX_RECORD *);  /* MSGTOIDX.BBS  */
int           msg_write_text (MSGHDR_RECORD *, M_TEXT);  /* New/change txt */
int           msg_write_new (MSGHDR_RECORD *, M_TEXT);    /* Write new msg */
int           msg_kill (long);                            /* Kill message  */

/* Message manipulation support routines */
long          msg_msgnr2recnr (unsigned int);    /* Convert msg # to rec # */
unsigned int  msg_recnr2msgnr (long);            /* Convert rec # to msg # */
void          msg_hdr_clear (MSGHDR_RECORD *);   /* Clear header record    */
int           msg_fixup4d (MSGHDR_RECORD *, M_TEXT);  /* hdr -> @INTL      */

/* Message base search routines */
long          msg_firstinboard (unsigned char); /* Get # of 1st msg in brd */
long          msg_lastinboard (unsigned char);   /* Get # of last msg in b.*/
long          msg_nextinboard (long);            /* Get # of next msg in b.*/
long          msg_previnboard (long);            /* Get # of prev msg in b.*/
long          msg_firstto (MSGTOIDX_RECORD *);   /* Get # of 1st msg to..  */
long          msg_lastto (MSGTOIDX_RECORD *);    /* Get # of last msg to.. */
long          msg_nextto (long);                 /* Get # of next msg to.. */
long          msg_prevto (long);                 /* Get # of prev msg to.. */

/* Netmail search and manipulation support routines */
int           net_first (char *);                /* Get # of first net msg */
int           net_last (char *);                 /* Get # of last net msg  */
int           net_next (char *, int);            /* Get # of next net msg  */
int           net_prev (char *, int);            /* Get # of prev net msg  */
void          net_hdr_clear (NET_RECORD *);      /* Clear a netmail header */
int           net_fixup4d (NET_RECORD *, M_TEXT);     /* INTL/FMPT/TOPT    */
int           net_getlastread (char *);          /* Get *.MSG lastread ptr */
int           net_setlastread (char *, int);     /* Set *.MSG lastread ptr */

/* Reading and writing netmail */
int           net_read_hdr (char *, int, NET_RECORD *);   /* Read net. hdr */
M_TEXT        net_read_text (char *, int);       /* Read netmail text      */
int           net_write (char *, int, NET_RECORD *, M_TEXT); /* Write net. */
int           net_kill (char *, int);            /* Kill *.MSG netmail msg */


/* Wrap up the C++ fixup ***************************************************/

#ifdef __cplusplus
}
#endif
#endif   /* __MB_LIB_H */


/* EOF */
