proboard.h
=============================================================================

    This header file has the prototypes for all functions specific to the
    ProBoard environment. All functions work in SDK and EXE mode. Note that
    in the EXE mode, all routines depend on the emulator being initialized
    properly. For more information, refer to the section on the emulator.h
    file.


    PB_GETDIR, PB_GETPATH, PB_FOPEN
    -------------------------------------------------------------------------

        Synopsis  Obtain ProBoard config paths, open any file there

        Syntax    char* pb_getdir(pbdir_t where);
                  char* pb_getpath(const char *fname, pbdir_t where);
                  FILE* pb_fopen(const char *fname, const char *mode,
                                 pbdir_t where);

        Remarks   These functions deal with the ProBoard-related paths that
                  are specified in the ProCFG setup program. Note that it
                  is possible to use the global 'Config' variable to obtain
                  the information as well. All functions have a parameter
                  'where' which can be one of the following enumerations:

                       enum pbdir_t
                       {
                           PBDIR_SYS,       // system directory
                           PBDIR_PEX,       // pex directory
                           PBDIR_USER,      // userbase directory
                           PBDIR_TEXT,      // display textfiles directory
                           PBDIR_MENU,      // menu directory
                           PBDIR_MSGBASE,   // same as userbase
                           PBDIR_NODELIST,  // nodelist directory
                           PBDIR_STARTUP,   // startup directory
                           PBDIR_UPLOAD,    // default upload directory
                           PBDIR_PVTUPLOAD, // private upload directory
                           PBDIR_RIPFILES,  // RIP files directory
                           PBDIR_RIPICONS   // RIP icons directory
                       };

                  pb_getdir() returns the path requested with the 'where'
                  argument. The specification will always be terminated
                  with a backslash.

                  pb_getpath() constructs a complete path specification for
                  the file with name 'fname' in the 'where' directory. This
                  is used in conjunction with the fn???? constants in the
                  PBNAMES.H header file.

                  pb_fopen() opens or creates the file 'fname' in 'mode'
                  (the mode is the same as for the fopen() standard function)
                  in the ProBoard directory 'where'. Note that 'fname' can
                  only be a file name (or a relative path specification) as
                  the directory is determined by the 'where' parameter. This
                  routine is a fopen() work-alike.

        Return    pb_getdir and pb_getpath return a path specification
                  On success, pb_fopen returns FILE pointer; NULL otherwise


    PB_MENUKEYS
    -------------------------------------------------------------------------

        Synopsis  Extract a list of hotkeys for a menu

        Syntax    char* pb_menukeys(const char *menu);

        Remarks   This function will extract the list of hotkeys used in a
                  menu. The 'menu' parameter is the name of the menu (for
                  example, "MAIN" or "GLOBAL"). This routine uses a static
                  local buffer which is overwritten with each call. The
                  string returned will have all hotkeys (listed only once
                  even if they may appear more than once in the menu file).
                  The string will be NUL-terminated.

        Return    On success, string with hotkeys; NULL otherwise


    PB2RADATE, PB2RATIME, RA2PBDATE, RA2PBTIME
    -------------------------------------------------------------------------

        Synopsis  Convert between RemoteAccess and ProBoard date/time

        Syntax    void  pb2raDate(DateRaType ra, const DateType pb);
                  void  pb2raTime(TimeRaType ra, const TimeType pb);
                  void  ra2pbDate(DateType pb, const DateRaType ra);
                  void  ra2pbTime(TimeType pb, const TimeRaType ra);

        Remarks   This set of functions is used to convert between the date
                  and time formats used by RemoteAccess and ProBoard. They
                  are very useful if you will be accessing any of the RA
                  compatible data files (such as the userbase files). Here's
                  how the different software stores the date/time data:

                  RemoteAccess
                      date is stored as a Pascal string, MM-DD-YY format
                      time is stored as a Pascal string, HH:MM format

                  ProBoard
                      date is stored as an array of 3 characters, with
                      ordering [0] = day, [1] = month, [2] = year - 1900
                      time is stored as an array of 3 characters, with
                      ordering [0] = hour, [1] = minutes, [2] = seconds

				  Note that the functions will expect that the parameters
				  in RA-compatible format are really Pascal strings!

        Return    Nothing


    PB2RAFLAGS, RA2PBFLAGS
    -------------------------------------------------------------------------

        Synopsis  Convert between RemoteAccess and ProBoard user flags

        Syntax    void  pb2raFlags(uchar *raFlags, ulong pbFlags);
                  ulong ra2pbFlags(const uchar *aFlags);

        Remarks   These functions convert the user flags settings from
                  RemoteAccess to ProBoard format. Note that unlike PB
                  which uses a single long integer to store the flags in
                  a bit-mapped fashion, RA uses an array of characters to
                  do more or less the same thing. While some flags are not
                  directly transferrable, most of them are. You can use the
				  RA_UFLAG1 and RA_UFLAG2 constants to access the RA flags
				  directly; alternatively you can use the PB_UFLAG constants
				  to access the PB user flags directly. Note that these
				  flags are NOT the user access permissions, but, rather,
				  their account configuration.

        Return    ra2pbFlags() returns the ProBoard-compatible flag bitmap


    PB_CURDATE, PB_MKDATE, PB_FMTDATE
    -------------------------------------------------------------------------

        Synopsis  ProBoard-compatible date format manipulation

        Syntax    void  pb_curdate(DateType dest);
                  void  pb_mkdate(DateType dest, time_t timer);
                  char* pb_fmtdate(DateType pbDate);

        Remarks   This set of functions manipulates date specifications in
                  ProBoard-compatible format. This format is as follows:
                  DateType is an array of 3 characters. DateType[0] stores
                  the day of the month (1..31), DateType[1] stores the month
                  (1..12), and DateType[2] stores the year (year - 1900).

                  pb_curdate() sets 'dest' to the current date.

                  pb_mkdate() creates a PB date in 'dest' from the 'timer'
                  information in time_t format (use time() to get that).

                  pb_fmtdate() returns a formatted string from the 'pbDate'
                  argument. If NULL is passed as the argument, this routine
                  will format a string with the current date. The string
                  will always have the format "Month Day Year" (for example,
                  "July 16 1973". This function uses a static local buffer
                  which is overwritten with each call.

        Return    pb_fmtdate() returns the date as a formatted string


    PB_CURTIME, PB_MKTIME, PB_FMTTIME
    -------------------------------------------------------------------------

        Synopsis  ProBoard-compatible time format manipulation

        Syntax    void  pb_curtime(TimeType dest);
                  void  pb_mktime(TimeType dest, time_t timer);
                  char* pb_fmttime(TimeType pbTime);

        Remarks   This set of functions is used to manipulate time records
                  in PB format. The TimeType data structure is an array of
                  3 bytes, where TimeType[0] stores the hour (0..11),
                  TimeType[1] stores the minute (0..59), and TimeType[2]
                  stores the second (0..59).

                  pb_curtime() sets the 'dest' parameter to the system time.

                  pb_mktime() creates a TimeType-compatible representation
                  in 'dest' from the 'timer' parameter in time_t format.

                  pb_fmttime() formats the time in 'pbTime' to a string.
                  If NULL is passed as the parameter, the current system
                  time will be used instead (note that there is a slight
                  difference in this case, the string returned will have
                  "HH:MM" format, without seconds in it). If 'pbTime' is
                  specified, the string will have "HH:MM:SS" format.

        Return    pb_fmttime() returns the time as a formatted string


    PB_GROUP
    -------------------------------------------------------------------------

        Synopsis  Read a file or message group

        Syntax    Boolean pb_group(int n, GROUP_PB *grp, Boolean msg=False);

        Remarks   This function will read group number 'n' (starts numbering
                  from 1, not from 0) into the area pointed to by the 'grp'
                  parameter. Note that file and message group structures
                  have the same format, so you can use this function to read
                  both. If the 'msg' parameter is False (default) this
                  function will read a file group, if it is True, it will
                  read a message group. Note that if an invalid group is
                  requested, the '*grp' area may contain invalid data even
                  though the function will still return True!

        Return    On success, returns True; False otherwise


    PB_FLAGFORMAT
    -------------------------------------------------------------------------

        Synopsis  Formats user flags as a string

        Syntax    char* pb_flagformat(flagformat_t how, ulong flags);

        Remarks   This function is rarely needed, but when you want its
                  functionality, it can make your life a lot easier. This
                  routine will format the user flags in 'flags' as a string
                  in ProBoard-compatible format. Note that the user flags
                  used here are the access flags (A..Z, 1..6). You can choose
                  whether the function should include all flags or just a
                  portion of them (for RA-compatible display). The parameter
                  'flagformat_t' can be one of the following:

                           enum flagformat_t
                           {
                               FLAGFMT_ALL, // all flags used
                               FLAGFMT_A,   // only A to H flags
                               FLAGFMT_B,   // only I to P flags
                               FLAGFMT_C,   // only Q to X flags
                               FLAGFMT_D    // only Y to 6 flags
                           };

                  The string returned will have the letters (in uppercase)
                  of all flags present in the 'flags' parameter, and dashes
                  for all that are turned off (e.g. "A--D-FG-"). Note that
                  this function uses a static local buffer which is modified
                  with each call.

        Return    The string with formatted flags


    PB_LIMIT
    -------------------------------------------------------------------------

        Synopsis  Retrieve LIMIT record for a particular user level

        Syntax    const LIMIT* pb_limit(ushort level);

        Remarks   This function will retrieve the LIMIT record for user with
                  access 'level'. If no exact match can be made, this
                  routine will return the record for the level which is
                  closest to the requested level. This level will always
                  be LESS than the requested one, resumably not to allow
                  any privileges for higher levels. Note that the pointer
                  returned actually points to a record in the global 'Limits'
                  array which cannot be modified.

        Return    Pointer to LIMIT record for the user level


    PB_ACCESS
    -------------------------------------------------------------------------

        Synopsis  Determine if the current user has access permissions

        Syntax    Boolean pb_access(ushort level, ulong flags, ulong fNot);

        Remarks   Unlike ProBoard's CheckAccess() function which only works
                  with the user level and flags, this one fully supports the
                  reversed flags 'fNot' as well. This routine will check if
                  CurUser (current user) has the required access permissions
                  to access a resource with 'level', 'flags', and 'fNot'
                  settings.

        Return    True if the user has access; False otherwise


    PB_PAGESTAT
    -------------------------------------------------------------------------

        Synopsis  Check if paging is eanbled for a time slot

        Syntax    Boolean pb_pagestat(const struct tm *slot = 0);

        Remarks   This function will check the ProBoard paging confguration
                  to see if the time slot where the 'slot' time falls in
                  has the paging enabled. The paging hours are divided into
                  48 half-hour segments, for each day of the week. Therefore,
                  the tm structure 'slot' must have the hour, minute, and
                  day of week fields filled in. All others are ignored by
                  the function. An easy way to calculate tm_wday (the day of
                  the week), is to set all other fields and then call the
                  mktime() function to do it for you. If the 'slot' argument
                  is NULL, the current system time will be used instead.

        Return    True if paging is enabled; False otherwise


    PB_ASKENTER
    -------------------------------------------------------------------------

        Synopsis  Wait until 'Enter' is pressed

        Syntax    void pb_askenter();

        Remarks   This function will display the language prompt for the
                  'Press Enter' function and then wait for 'Enter' to be
                  pressed. Note that in non-SDK (EXE) mode, this routine
                  will NOT run pexen that may be specified with the "@p"
                  mechanism in the language file. In that case, a simple
                  text string will be shown instead. When used in SDK mode,
                  pexen will be executed, though.

        Return    Nothing


    PB_RUNPEX, PB_RUNEXE
    -------------------------------------------------------------------------

        Synopsis  Run a PEX or EXE file

        Syntax    void pb_runpex(const char *command);
                  void pb_runexe(const char *command);

        Remarks   These functions can be used to execute a PEX or EXE command
                  from a program. Note that runpex() will return immediately
                  if used in non-SDK mode as there is no way to run a PEX
                  without ProBoard. These functions support the '*' macros
                  as used in ProBoard's function 7 (Shell). Note that the
                  set interpreted in non-SDK mode is somewhat limited, but
                  should be enough for most uses.

        Return    Nothing


    PB_VER
    -------------------------------------------------------------------------

        Synopsis  Retrieve ProBoard's version number

        Syntax    Boolean pb_ver(int *maxver, int *minver, int *beta);

        Remarks   This function will attempt to determine the version of
                  ProBoard installed on the system. It will fill in the
                  parameters as follows: 'maxver' is the version number,
                  'minver' is the revision (minor) version number, and
                  'beta' will be set to non-xero if the version is a beta.
                  This function actually scans the executable in an attempt
                  to identify the version, so it is not bullet-proof. For
                  example, version 2.15b3 will resturn maxver = 2,
                  minver = 15, and beta = 3. The 'beta' integer will be set
                  to 0 for a full release.

        Return    On success, returns True; False otherwise


    PB_ISGFX
    -------------------------------------------------------------------------

        Synopsis  Checks current user for text-graphics emulation

        Syntax    int pb_isgfx();

        Remarks   This function will check if the user has one of the
                  graphics protocols enabled. It will return 1 if either
                  ANSI, Avatar/0, or Avatar/0+ is enabled in the terminal
                  emulation record. If the user has only ASCII support,
                  this function will return 0. Useful for ANSi-only programs
                  which cannot run unless the proper emulation is available.

        Return    If graphics available, return 1; 0 for ASCII only


    PB_SHOWLANG
    -------------------------------------------------------------------------

        Synopsis  Display a language prompt

        Syntax    void pb_showlang(int promptno, zTerminal * const terminal);

        Remarks   This function displays prompt number 'promptno' from the
                  language file used by the current user (CurUser). Note that
                  it requires a pointer to a zTerminal object. You must
                  provide this object yourself. Also, you should install
                  the "proboard_interp" interpreter as well as the ANSI and
                  maybe Avatar ones as well. Refer to the documenation on
                  zTerminal for more information. Prompts are numbered from
                  1 and their numbering corresponds to the scheme used in
                  the language editor in ProCFG.

        Return    Nothing


    PB_ASKMORE
    -------------------------------------------------------------------------

        Synopsis  Asks the 'More (y/n)' prompt

        Syntax    int pb_askmore(zTerminal * const pTerminal);

        Remarks   This function will display the appropriate language
                  prompt and then wait for user input. Note that it will
                  respect whatever hotkeys are defined in the user record.
                  The non-SDK version does not support "@p" PEX files in
                  the language prompt (in that case, a simple text string
                  will be shown instead). The caller must provide the
                  zTerminal object with at least ProBoard and ANSI (maybe
                  even Avatar) interpreters installed. Regardless of the
                  hotkeys defined, this function will always return a
                  pre-defined set of numbers for each command.

        Return    On 'Yes' response, returns 1;
                  On 'No' response (or 'Stop') returns 0;
                  On 'Continuous' response, returns 2


    PB_SHOWFILE
    -------------------------------------------------------------------------

        Synopsis
        Syntax    int pb_showfile(char *name, char *keys,
                                  zTerminal * const pTerminal);
                  int pb_showfile(char *name, char *keys, char *dir,
                                  zTerminal * const pTerminal);

        Remarks   These functions display text files with hotkeys, much
                  like the function in ProBoard (Show *.A?? File with
                  Hotkeys). The caller must provide the zTerminal object
                  via the 'pTerminal' argument. This terminal must be able
                  to handle ANSi, and Avatar sequences at the minimum. You
                  can also install more handlers, such as the PCBoard and
                  Wildcat! color format to display other text files. For
                  further information, refer to the zTerminal documentation.
                  The 'keys' parameter specifies the list of hotkeys. If any
                  if these keys are detected while the file is being shown,
                  the output is aborted and the function returns immediately
                  (this is what ProBoard does). If this parameter is NULL,
                  the hotkeys check will be disabled. Note that the display
                  functions support the following special textcodes:

                             ^A : wait for 'Enter'
                             ^B : disable stopping with 'S'
                             ^C : enable stopping with 'S'
                             ^D : enable pausing with 'P'
                             ^E : disable pausing with 'P'
                             ^G : ring the bell
                             ^L : clear the screen
                             ^W : pause for 100 milliseconds

                 Also, the following hotkeys can be used. The stop function
                 is enabled by default, while the pausing is determined by
                 the appropriate setting the user record for the current user
                 (both can be changed with the textcodes shown above):

                              S : stop display and return immediately
                              P : pause until 'P' is pressed again

                 Also note that these functions will pause when the screen
                 is full and about to scroll. At this point, they will
                 display the appropriate prompt from the language file and
                 wait for instructions whether to continue, stop or go on
                 and not pause again.

                 The first version of the function is used to display any
                 file specified by the 'name' parameter. In this case, the
                 file name must include the complete path specification,
                 including the file extension. No attempt will be made to
                 locate a file with a different extension.

                 The second version should be used when a *.A?? file must
                 be shown, depending on the terminal emulation available
                 to the current user. In this case, the 'name' parameter
                 should only contain the file name (without directory or
                 extension), and the 'dir' parameter should specify the
                 directory to look in (with a terminating backslash!). The
                 order proceeds as follows (again, depending on the settings
                 in the user record): *.AVP (Avatar/0+), *.AVT (Avt/0+ or
                 Avatar), *.ANS (Avt/0+, Avatar, or ANSI), and finally
                 *.ASC (terminal emulation capabilities ignored).

                 Note that because it is not practical to check for hotkeys
                 every byte while displaying the file, a global constant
                 MAX_CYCLES (set at 2400) defines how many bytes to show
                 before a check is made. Large values speed up the display
                 considerably, but also make the response rate more sluggish.
                 Lower values slow down the display but make the response
                 snappier. The default provides a decent trade-off.

        Return    0 - file displayed entirely, no hotkey pressed
                  1 - 'S' pressed and output was aborted
                  2 - file not found
                 >2 - hotkey pressed (ASCII code of the key returned)

