//  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$
//  ------------------------------------------------------------------

// header file converted from Pascal to C by damWARE, 08.06.98.

// WaterGate Developers Kit for release 0.93
// database structures

// include this file from one of your source files with $I structs.pas

// this file describes the structures of WaterGate's database. There is
// no code in header, but just the declarations of the structures. There
// _is_ a whealth of explanation in this file though!

/* History:

  950903 0.19     - Initial release.
  950918 0.19.p2  - The config structure in the original release was a
                    complete mess and unusable.
  951030 0.20     - Added administrator fields.
  951203 0.21     - New list server user type, longer time zone string,
                    export AKA in user record.
  960214 0.90     - Config: Log9->LogAreaFix and Log10->LogMapApply.
                    UUCPForwardRecord: reduced path length by 1 and
                    added Group letter.
  960530 0.91     - AreaBase: Added fields for decoding files.
                    Config: Log11..Log14 are now used.
                    New fields for config: CopyHeaders_FU, MailGrade,
                    NewsGrade, TimeSlicing, NetmailDecode,
                    NetmailDecodePath, PrivateDecode, PrivateDecodPath.
  961014 0.92     - Config: Log15 and Log16 are now used, Added RAR
                    support, more system node numbers, more copy header
                    entries, more areafix/newsfix forward entries,
                    remove unused fields.
                    ListServer: Added Access and DefaultAccess.
                    UserBase: Added BAG and SMTP variant record entry.
                    AreaBase: Seen-BY akas now support 100 bits.
  960706 0.93     - New groups format and lots of other changes.
                    AreaBase 04->07: Changed IsInGroups, Added Hidden.
                    Updated groups explanation.
                    UserBase 05->08: Removed unused longint. Changed
                    groups, added envelope header.
                    ListServer 03->05: Added re-confirmation fields,
                    added MLAddress, added confirm interval.
                    Config 14->22: Changed Default_F and Default_U,
                    removed ConversionTable, Added SmtpForward,
                    MaxXPostNewsGroups, WildCatMSGLockDir, OpusDateFormat,
                    MaxWildCatMsgLen, KillAreafixMsgs, Color set.
*/

// I have reduced all the types and constants we use, to make it easier
// for you to read the structures. The names used end with _F if it is
// Fidonet related, and with _U if it is UUCP/Usenet related. _B is BAG,
// _S is SMTP and _P is POP3.

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

/*
**==========================================================================
**                  ABOUT THE DATABASES
**==========================================================================
*/

// WaterGate uses six binary database files and one ascii configuration
// file. This source file only covers the six binary databases. Each of
// the database files starts of with a 26 byte long header, which is
// basically a string that is written to disk, including the length byte
// at the first position. The string is thus declared as a STRING[25].
// Each database has its own header, as defined below. The last two
// digits are a modification counter, which is increased by one very
// time the database structures change. You have to check this header
// and it has to match exactly, or else you should not access the
// databases with the structures in this file!

const char AreaBaseHeader[26]     = "WtrGate AreaBase 07";
//const char UserBaseHeader[26]     = "WtrGate UserBase 08";
//const char SubscrBaseHeader[26]   = "WtrGate SubscrBase 01";
//const char GrpDescrBaseHeader[26] = "WtrGate GroupDescr 03";
//const char ListServerHeader[26]   = "WtrGate ListServer 05";
const char ConfigHeader[26]       = "WtrGate Config 22";

// Directly after this string, the first record starts. All record
// numbering is 1..n, with the special value 65535 meaning a NIL pointer
// record, mostly used to indicate free positions or the end of a list
// of record numbers.

const word NILRecordNr = 0xFFFF;

// to find out how many records are present in a database, you use the
// following formule:
//
// RecCount = ((FileSize (Database)-26) DIV SizeOf (Record));
//
// This formula can be used for each of the databases. Simply substitute
// "Record" with the correct structure name and "Database" with the
// actual file variable. It is best to declare the file variable as a
// FILE and to open the database with a Reset (Database,1), as below:
//
// VAR AreaFile : FILE;
//     RecCount : WORD;
//
// BEGIN
//      Assign (AreaFile,'AREABASE.TDB');
//      Reset (AreaFile,1);
//      BlockRead (AreaFile,Header,26);
//      RecCount:=(FileSize (AreaFile)-26) DIV SizeOf (AreaBaseRecord));
//      Close (AreaFile);
// END
//
// To read and write a record, you substract 1 from the record number,
// multiply it with the record size and add 26, then seek to that
// position in the file and read or write the record, like this:
//
// VAR AreaRec   : AreaBaseRecord;
//     AreaRecNr : WORD;
//     Position  : LONGINT;
//
// BEGIN
//      Position:=26+(AreaRecNr-1)*SizeOf (AreaRecord);
//      Seek (AreaFile,Position);
//      BlockRead (AreaFile,AreaRec,SizeOf (AreaBaseRecord));
// END;

/*
**==========================================================================
**                  GLOBAL STRUCTURES
**==========================================================================
*/

// this structure is used to hold an AKA, whereever required

typedef struct
{
    word   zone;
    word   net;
    word   node;
    word   point;
    char   domain[26];
} FidoAddrType;


/*
**==========================================================================
**                  GROUP DESCRIPTIONS DATABASE
**==========================================================================
*/

// this database contains 128 records, one for each of the groups. Each
// record hold the description of the group, the system AKA to use,
// which is an index number from 1 to 100 in the array of system AKAs
// in the Configuration Record. And finally it contains the ReadOnly
// boolean, which is set to TRUE to disable posting to any area in this
// group, unless the user and the area are both in read/write group as
// well.

struct
{
    char   groupdesc[31];
    byte   originaka;                                         // 1..100
    bool   readonly;
} GroupDescRecord;

// [...]

// new groups storage (0.93):
//
// there are 128 groups, numbered 1 to 128. The AreaBase.IsInGroups
// and UserBase.Groups are 16 byte arrays, where each byte represents
// subscription to one group. Bit 0 in the first byte is group 1, etc.

const word MaxGroups    = 128;                 // A1-5,B1-5,..,Y1-5,Z1-3
const word GroupFlagLen = MaxGroups / 8;

typedef byte GroupFlagType[GroupFlagLen];      // bit mask

// to access to groups, use the GroupFlagType and the following code
// sequence to access the group list.
//
// VAR I,O : BYTE;
//
// I:=1+((NewGroupNr-1) DIV 8);
// O:=(NewGroupNr-1) MOD 8;
// Group[I]:=Group[I] OR (1 SHL O);
//
// The above example adds NewGroupNr (1..128) by settings the correct
// bit in the array. I is an index into the array and O is the bit
// number ("offset", 0..7).
//
// You can use constructions with AND to reset a bit. I have created
// abstract functions to access a GroupFlagType for resetting it,
// adding a single group, removing a single group, testing for
// membership, set overlap tests, etc.


/*
**==========================================================================
**                  AREABASE
**==========================================================================
*/

typedef struct
{
    bool   deleted;
    byte   areatype;              // 0=Echo, 1=Netmail, 2=Local, 3=Email
    char   areaname_U[61];        // the two names of this area
    char   areaname_F[61];
    char   comment[61];           // the comment / description
    byte   isingroups[16];        // the groups this area is in. See the group
    // descriptions database for an explanation.

    word   userlist;              // points to the first subscription base
    // record. See explanation there.

    byte   originaka;             // the system AKA to use for the origin line,
    // is an index 1..20 into the array in the
    // configuration record.

    byte   addseenbyakas[13];     // The system AKAs 1..100 to add to the SEEN-BY
    // If the bit is set, it is added. [0]bit0 is
    // AKA 1, [0]bit1 2, etc.

    bool   passive;               // TRUE if this area is passive
    bool   alwpassive;            // TRUE if this area is allowed to be passive
    byte   originnr;              // origin number to use: 0=custon, 1/2=system
    char   origin[62];            // the custom origin line
    byte   fidomsgstyle;          // the style of this area's message base
    // 0=None, 1=Msg, 2=Squish, 3=Jam, 4=WildCat

    char   fidomsgpath[80];       // the path to the database
    word   fidomsgage;            // the maximum age of a message, when cleaning
    word   fidomsglimit;          // the max. num of msgs in allowed
    byte   moderated;             // is this area moderated? 0=No, 1=Usenet
    char   moderator[51];         // the e-mail address of the moderator
    bool   decode;                // XX/UU/MIME decode?
    char   decodepath[80];        // path where to store decoded files
    bool   hidden;                // if TRUE then doesn't show up in AreaFix/newsfix
} AreaBaseRecord;

/*
**==========================================================================
**                  USERBASE
**==========================================================================
*/

// the userbase holds all the users that are configured in WtrConf. There
// is one record for each user. The maximum number of records is 65534.

struct
{
    bool   deleted;               // TRUE means deleted
    byte   system;                // 0=Fido, 1=Usenet, 2=Bag supplier
    char   organization[61];      // description of this user
    byte   groups[16];            // the groups this user is allowed in
    // see the group description database
    // for an explanation of the storage.

    bool   passive;               // is this user passive?
    char   areafixpwd[21];        // its AreaFix/newsfix password
    bool   allowfrom;             // TRUE = allow special AreaFix commands
    bool   allowcreate;           // TRUE = allow new area creation
    bool   allowsubdomains;       // TRUE if this user is allowed to have sub-domains
    word   arealist;              // pointer to the first subscription base
    // record, holding the areas this user is
    // subscribed to. See the subscription
    // base for an explanation.

    char   uucpname[11];          // the user's UUCP name
    bool   worldreg;              // World Registered UUCP name?
    char   domains[51][6];        // domain names

    word   type;

    union
    {
        // 0 = FidoNet style user
        struct
        {
            FidoAddrType  Address;      // AKA
            char   sysop[51];           // full name of the sysop
            char   packetpwd[9];        // password for *.PKT files
            byte   compression;
            dword  maxpktlength;        // max  length of an .PKT files
            // before it is cut off and packed

            byte  sendformat;           // the send condition: 0=Normal,
            // 1=Hold, 2=Crash, 3=Direct.

            byte  lastarchdow;          // day-of-week used on the last sent
            // archive. 0=first, 1..7 = dow.

            byte  lastarchnr;           // last archive number used
            byte  exportaka;            // Export AKA. 0=Auto, 1..100=System AKA
            bool  decodefiles;          // TRUE = decode files for this user?
        } fidostyle;
        // 1 = UUCP style user
        struct
        {
            byte compress;              // 0=None, 1=Compress, 2=Zip
            bool cunbatch;              // TRUE= add CunBatch to compressed archive
            char mailgrade;
            char newsgrade;
            bool gigot;                 // TRUE = create GIGOT compatible .XQT files
        } uucpstyle;
        // 2 = BAG style user
        struct
        {
            char bagbacklink[11];       // uucp name of the bag return system
            char bagpath[80];           // Search path for the bag files
        } bagstyle;
        // 3 = SMTP mailer link
        struct
        {
            char smtpinpath[80];        // where to process .WRK/.TXT files from
            char smtpoutpath[80];       // where to create .WRK/.TXT files
        } smtpstyle;
        // 4 = POP3 mailbox link
        struct
        {
            char pop3file[80];          // where is the POP3 file stored? }
            char recipient[51];         // single recipient address
            char separator[16];         // separator searched for
            char envelopehdr[26];       // envelope header searched for
        } pop3style;
        // 5 = BBS
        struct
        {
            char inbound[80];           // search for .PKT files from BBS tosser here
            char outbound[80];          // create .PKT files for BBS tosser here
            byte systemaka;             // 1..100
            word fakezone;              // fake AKA
            word fakenet;
            word fakenode;

            char inboundext[3];         // extension for inbound packets (PKT/OUT)
            bool keepsbp;               // TRUE = keep SEEN-BY and PATH?
            byte reserved1;             // unused
        } bbsstyle;
    };

} UserBaseRecord;


/*
**==========================================================================
**                  SUBSCRIPTIONS DATABASE
**==========================================================================
*/

// [...]

/*
**==========================================================================
**                  CONFIGURATION DATABASE
**==========================================================================
*/

// structures for the system configuration database. There is only one
// record in this database. The structures below start with the areafix
// and newsfix forwarding records, which are used in the configuration
// record. I have removed all other references and put them straigt in.

// Since AreaFix and newsfix forwarding have not been re-implemented
// yet, I have not described the structures, until they become certain.

typedef struct
{
    FidoAddrType  uplinkaddress;  // uplink AKA
    bool   unconditional;         // allow all new names, or check against file?
    char   arealistpath[51];      // path to the forwarding file
    byte   arealist;              // type of the file. 0=areas.bbs, 1=names list
    char   areamanager[11];       // name of uplink's AreaFix
    char   password[11];          // password for uplink's areafix
    byte   group;                 // group to put new areas in. 0 = Group A1
    bool   addplus;               // Add "+" to connect in front of areaname
} AreafixForwardRecord;

typedef struct
{
    char   uucpname[11];          // UUCPname of uplink
    char   arealistpath[50];      // path to the newsgroups listing
    byte   group;                 // group to put new areas in. 0 = Group A1
} UUCPForwardRecord;

typedef struct
{
    char   systemdir[80];         // path to the other databases
    char   sysop[51];             // full name of the sysop
    word   dupechecks;            // max. number of dupes to remember (16000 max.)
    bool   dodupechk;             // TRUE = Check for dupes
    byte   maxhandles;            // max. number of outbound files to keep open
    bool   cachetdbs;             // TRUE cache the databases in XMS
    char   toolargepath[80];      // path to the too-large directory for oversized msgs
    char   logfilepath[80];       // path and filename of the logfile and stats file
    FidoAddrType nodenrs[100];    // system AKAs
    word   pointnets[100];        // pointnet for each of the system AKAs
    byte   security_F[2];         // Secure the inbound paths: 0=Yes, 1=No
    char   inbound_F[80][2];      // paths to the inbound directories
    char   outbound_F[80];        // path to the outbound directory
    char   comprprgs_F[80][18];   // Fido compress/decompression programs
    dword  maxfidomsglen;
    dword  maxfidoarclen;
    byte   defgroups_F[16];       // default groups for a new Fido user
    byte   fidosystem;            // 0=Binkley, 1=Frontdoor, 2=dBridge
    bool   fidoacceptto;          // scan the To: field for a e-mail address?
    byte   fidonetmailtype;       // Netmail msgbase type: 0=None, 1=Msg, 2=Squish, 3=Jam
    char   fidonetmailpath[80];   // path to the database
    byte   fidobadareatype;       // Bad msgbase type: 0=None, 1=Msg, 2=Squish, 3=Jam
    char   fidobadpath[80];       // path to the database
    byte   fidodupeareatype;      // Dupe msgbase type: 0=None, 1=Msg, 2=Squish, 3=Jam
    char   fidodupepath[80];      // path to the database
    byte   fidoautocreatetype;    // New created areas type: 0=None, 1=Msg, 2=Squish, 3=Jam
    char   defaultfidomsgpath[80];// default path to use (no filename)
    bool   stripseenby;           // TRUE = strip seen-bys when importing
    bool   autolink;              // TRUE = link after import
    bool   replacetear;           // replace the tearline when exporting?
    word   defnumbtokeep_F;       // default number of msgs to keep for an new area
    word   defdaystokeep_F;       // default number of days to keep msgs for a new area
    byte   fidoarcmailextension;  // 0=Arc(0..9), 1=Hex(0..9,A..F), 2=All(0..9,A..Z)
    byte   uucpgateway;           // Gateway AKA nr: 1..10, as index in system AKAs array
    char   nameseparator;         // character to replace spaces with in user names
    // when building an e-mail address.

    char   origins[2][62];        // the two system origin lines
    bool   worldwide;             // TRUE = system UUCPname is world-reg
    byte   defgroups_U[16];       // default groups to use for UUCP
    char   spoolbasedir[80];      // path to the spool directories
    dword  maxdatlength;          // Max. length of .DAT files, before compression
    char   smarthost[11];         // UUCPname of your smarthost
    char   uucpname[11];          // system UUCP name
    char   backbone[51];          // domain name of the backbone
    char   organization[60];      // system organization line
    char   domains[6][51];        // system domain names
    char   comprprg_U[4][80];     // installed compression/decompression programs
    byte   privmailtype;          // type of private mail message base:
    // 0=None, 1=*.MSG, 2=Squish, 3=JAM
    char   privmailpath[80];      // path to the message base
    char   privmailoption[10][73];
    byte   privmailselect[10];    // where to search: 0=From, 1=To, 2=Subj
    byte   reserved1;
    AreafixForwardRecord  areafixforward[50];
    UUCPForwardRecord  uucpforward[50];
    dword  maxsquishmsglen;       // max msg length when importing into Squish base
    dword  maxjammsglen;          // max msg length when importing into JAM base
    byte   defaultcompressor;     // default compression to set in new user records:
    // 0=ARC, 1=ARJ, 2=LZH, 3=PAK, 4=ZIP, 5=ZOO, 6=RAR
    // 7=OP1, 8=GUS, 9=PKT.
    bool   packedaddresses;       // TRUE = build small e-mail addresses
    char   rescanflagfile[80];    // path to the rescan flag file
    char   dbridgequeuepath[80];  // path to the d'Bridge dir where to store the queueing files }
    char   areafixname[11];       // name of the fido areafix
    bool   killgatednetmail;      // TRUE = automatically kill gated netmail
    char   newsfixname[11];       // name of the UUCP areafix (newsfix)
    bool   useswapfile;           // TRUE = use swapfile
    char   swapfilepath[80];      // path to the swapfile
    byte   swapfilesize;          // max length of the swapfile in megabytes
    bool   replyfsc35;            // TRUE = create FSC35 reply kludges
    bool   headerfullname;        // TRUE put the full name in the From: field?
    bool   logdebug;              // TRUE = enable all other options
    bool   logspooltossed;        // TRUE = log tossed spool files
    bool   logfidoextract;        // TRUE = log extracted fidonet archives
    bool   logfidotossed;         // TRUE = log tossed fido .PKT files
    bool   logtranslationFU;      // TRUE = log built e-mail addressed
    bool   logcheckfilter;        // TRUE = log accepted / denied new newsgroup names
    bool   logxfix;               // TRUE = log fixed to-address from .X files
    bool   logcopyheaders;        // TRUE = Log headers that were copied from fido netmail/echomail messages
    bool   logillegalheaders;     // TRUE = Log found headers that are not allowed
    bool   logareafix;            // TRUE = Log commands to / replyies from areafix / newsfix
    bool   logmapapply;           // TRUE = Log applied mapping statements
    bool   lognetmailimport;      // TRUE = log all imported netmails
    bool   logrodeny;             // TRUE = log all read-only denied postings in areas
    bool   logpkteachecho;        // TRUE = log each echomail plus length
    bool   loguucpoutbound;       // TRUE = log all created UUCP files
    bool   logsmtpoutbound;       // TRUE = log all created SMTP jobs
    bool   logexportednetmail;    // TRUE =
    bool   log17, log18, log19, log20, log21;
    char   copyheadernames[16][30];// names of the e-mail Headers to search for
    // without the trailing space!

    byte   copyheaderhow[30];     //  How to store the copied header:
    // 0=Not, 1=Kludge, 2=Text

    char   gatewayuser[37];       // user name of the gateway user
    bool   bounceunknown;         // TRUE=bounce undeliverable mail
    // FALSE=Write to netmail

    bool   bouncesmall;           // TRUE=Send only the first approximate 20 lines
    byte   adminaddrtype;         // 0=None, 1=Fido, 2=Usenet
    char   adminfidoname[37];     // Full name of the administrator, for the Fidonet address
    FidoAddrType adminfidoaddr;   // Fidonet address of the administrator
    char   adminuucpaddr[256];    // E-mail address of the administrator
    bool   adminsendlog;          // Send the logfile to the administrator?
    bool   adminsend2, adminsend3, adminsend4, adminsend5, adminsend6, adminsend7,
           adminsend8, adminsend9, adminsend10,adminsend11, adminsend12, adminsend13,
           adminsend14,adminsend15,adminsend16;
    char   timezone[26];          // time zone description
    bool   copyheaders_FU;        // TRUE = Scan and copy headers Fido->Usenet
    char   mailgrade;             // grade letter to use in mail job UUCP filenames
    char   newsgrade;             // grade letter to use in news batch job UUCP filenames
    bool   timeslicing;           // FALSE = Do not detect multitasker
    bool   netmaildecode;         // TRUE = scan and decode files from imported netmail
    char   netmaildecodepath[80]; // where to store the files
    bool   privatedecode;         // TRUE = scan and decode files from imported private scanned messages
    char   privatedecodepath[80]; // where to store the files
    word   maxrmaillinelen;       // max len for rmail line in .X file
    byte   minimumdiskfree;       // min MB's free for disk check
    char   diskfreedrives[27];    // drives to check for disk check
    byte   old;
    byte   rmailcorrect;          // rmail correction to use
    bool   gatemsgid;             // TRUE = gate Message-ID -> MSGID
    bool   forcenobitmask;        // TRUE = don't put "0" in front of UUCP jobs
    char   rescanflagfile2[80];   // editor rescan flag file
    byte   organizationinorigin;  // Gate organization -> origin: no, yes, override
    bool   alwaysmimequoteprint;  // TRUE = always use quoted-printable
    char   smtpforward[51];       // address for dumping mail at ISP
    byte   maxxpostnewsgroups;    // cross-post limit. 255 = allow all
    char   wildcatmsglockdir[80]; // path to MSGLOCK directory for WildCat conference lock
    bool   opusdateformat;        // TRUE = create *.MSG with Opus date fields
    dword  maxwildcatmsglen;      // max len of a single WildCat message
    bool   killareafixmsgs;       // kill *.MSG with areafix after processing?
    byte   colors[21];            // color codes for each of the elements
}  ConfigRecord;

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

//==== END OF FILE ==========================================================
