Developer information
=====================

(please note that this document is not valid anymore. Development of tcRA32 is
 terminated, and the author of RA failed to implement this in the latest
 release. EleBBS still implements this feature).

Introduction
------------

There are a number of RemoteAccess compatible BBS programs, which are fully
RemoteAccess structure file compatible. In general this would mean that it
is impossible for an utility authors to determine wether an SysOp is running
RemoteAccess, tcRA32 or perhaps EleBBS. Fortunately, all three authors have
agreed on following the hereafter explained system, which solves this problem.

Please note however, that currently only EleBBS fully supports the system,
RemoteAccess will fully support it together with a new release and tcRA32
will fully support is as soon as there is an configuration utility available
for it.


Implementation
--------------
In the CONFIG.RA file, there were some old fields left from RA version 1.11
and before that. One of those fields was the old xCommport field. This field
was replaced by MODEM.RA a few versions back. We re-assigned the value of
this field with the following fields:

  251  = RemoteAccess
  252  = tcRA32
  253  = EleBBS


Examples
--------
The examples below in VisualBasic and QuickBasic are written by
Niels Schoot (author of tcRA32), TurboPascal example is written by
Maarten Bekers (author of EleBBS) and the C++ example is written by
Vertigo/Dementia


'===========================
'BBSTEST
'Visual Basic (Any version)
'===========================
'
Dim CfgH As Integer         ' Configfile handle
Dim Version As Integer      ' Product version
Dim ProdID As Integer       ' Procuct ID code
Dim ConfigFile As String    ' Path and filename to Configfile

'Sample:
ConfigFile = "C:\RA\CONFIG.RA"

CfgH = Freefile

Open ConfigFile For Binary Shared As CfgH

    'Get Version Number
    Get #CfgH, , Version
    Version = Val(Hex$(Version))

    'Get Product ID
    Get #CfgH, , ProdID
    '251 = Bruce Morse's (Wantree) RemoteAccess
    '252 = Niels Schoot's tcRemoteAccess32
    '253 = Maarten Bekers' EleBBS

Close CfgH

'===========================
'BBSTEST
'Quick Basic (Any version)
'===========================
'
'Sample
ConfigFile$ = "C:\RA\CONFIG.RA"

CfgH% = FREEFILE

OPEN ConfigFile$ FOR BINARY SHARED AS CfgH%

    'Get Version Number
    GET #CfgH%, , Version%
    Version% = VAL(HEX$(Version%))

    'Get Product ID
    GET #CfgH%, , ProdID%
    '251 = Bruce Morse's (Wantree) RemoteAccess
    '252 = Niels Schoot's tcRemoteAccess32
    '253 = Maarten Bekers' EleBBS

CLOSE CfgH%

------------------------------------------------------------------------------

program BBSTest(Input, Output);
(*
**
** Test routines for which BBS package running
** (part of EleBBS)
**
** Created : 22-Feb-1998
** Last update : 22-Feb-1998
**
** Note: Word is a 2 byte type.
*)
Uses Crt,
      Dos;

type
     ProductRecord = record
        VersionID           : Word;
        ProductID           : Byte;                      { $01 = RemoteAccess }
                                                               { $02 = tcRA32 }
                                                               { $03 = EleBBS }
     end; { productRecord }

var Config_F: File;
    Config  : ProductRecord;
    Path    : String;
begin
  Path := GetEnv('RA');
  if Path <> '' then
    if Path[Length(Path)] <> '\' then Path := Path + '\';

  Assign(Config_F, Path + 'CONFIG.RA');
  {$i-} Reset(Config_F, 1); {$i+}
  if IOResult>00 then
    begin
      WriteLn(#254, #32, 'Unable to open CONFIG.RA, program aborted.');
      HALT;
    end;

  {$i-}
    BlockRead(Config_F, Config, SizeOf(ProductRecord));
    Close(Config_F);
  {$i+}
  if IOResult>00 then HALT;

  Case Config.ProductID of
     $251 : Write('RemoteAccess v');
     $252 : Write('tcRA32 v');
     $253 : Write('EleBBS v');
      else Write('Unknown BBS package (', Config.ProductID,'), v');
  end; { case }

  Case Config.VersionID of
     $200 : WriteLn('2.xx');
     $250 : WriteLn('2.5x');
      else WriteLn('ersion undetermined.');
  end; { case }

end. { BBSTEST }


------------------------------------------------------------------------------

/***********************************************************************
*                                                                      *
*  Example how to determine which RA flavour is running in c++.        *
*  Translated from Maarten Bekers' sourcecode in pascal.               *
*  Done by Vertigo/Dementia at 23 March 1999, released                 *
*  into the public domain.                                             *
*                                                                      *
*  Deficiencies: Environment string is not dynamically allocated,      *
*  watch out for buffer overflows. Probably some bugs left.            *
*                                                                      *
************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>

typedef unsigned short int word;  // 16 bits unsigned integer
typedef unsigned char      byte;  // 8  bits unsigned integer

const char cfgfile[] = "config.ra";

typedef struct {
	word version_id;
	byte product_id;
} tProductRecord;

void print_version(word ver)
{
	switch(ver) {
		case 0x0200 	   : printf("v2.xx\n"); break;
		case 0x0201 	   : printf("v2.xx\n"); break;
		case 0x0250 	   : printf("v2.5x\n"); break;
		default     	   : printf("v.Unknown\n"); break;
	}
}

void print_product(byte prd)
{
	printf(" Product: ");
	switch(prd) {
		case 0x01  : printf("Proboard ");     break;
		case 251,0 : printf("RemoteAccess "); break;
		case 252   : printf("tcRA32 ");       break;
		case 253   : printf("EleBBS ");       break;
		default    : printf("Unknown ");      break;
	}
}

int main(void)
{
	tProductRecord product;
        char cfgloc[100]; 
	FILE* fd;

        if (strlen(getenv("RA"))>0) {
		strcpy(cfgloc, getenv("RA"));
                if (cfgloc[strlen(cfgloc)]!='\\') strcat(cfgloc,"\\");
		strcat(cfgloc,cfgfile);
	} else {
		printf("Error: %s\n","Please set your RA environment variable!");
		exit(1);
	}

        if ((fd = fopen(cfgloc,"r"))!=NULL) {
		printf("\n Reading %s ..\n",cfgloc);
		fseek(fd, SEEK_SET, 0);
		fread(&product, sizeof(product), 1, fd);
		fclose(fd);
	} else {
		printf(" Failed to open config.ra\n");
		exit(1);
	}

	print_product(product.product_id);
	print_version(product.version_id);
	return(1);
}

// eof.
