home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / PASCAL / FCOMM240.ZIP / FCOMM.DOC next >
Text File  |  1991-03-07  |  27KB  |  740 lines

  1. { The following is the INTERFACE section of FCOMM.PAS (FCOMM.TPU).
  2.   It has all of the functions and code you will need, so please don't
  3.   hesitate and give me a ring via the Doorware FidoNet Echomail Conference. }
  4.  
  5.  
  6. UNIT FCOMM;
  7.  
  8. {
  9.  --------------------------------------------------------------------------
  10.  FComm - A FOSSIL driven I/O Library for Doors w/lots-of-goodies :)
  11.  
  12.   - for use with Turbo Pascal 6.0
  13.   - for use with Remote Access v1.0
  14.   - works with RA's *.BBS files, DOOR.SYS and DORINFO?.SYS
  15.   - SysOp "hot-keys" (see documentation or source code)
  16.   - Code supporting Interactive EMSI
  17.   - Emulated "windowed" ANSI & AVATAR graphics
  18.   - Status line on caller
  19.   - Checks for carrier drop, keyhit timeout and time-limit timeout.
  20.   - semi-intelligent code
  21.   - nice programmer who takes suggestions.. (yuck)
  22.   - and FREE.
  23.  
  24.  Copyright (c) 1991 by Michael Paine
  25.  
  26.   - I hope this gets improved by a few programmers out there..  all I ask
  27.     for is to only have one "valid" copy floating around, or chaos will
  28.     definately occur, so please send improvements to:
  29.  
  30.                    FidoNet NETMAIL @ 1:363/111
  31.                or  Data (407)862-4724 (The SCSI Resource BBS)
  32.  
  33.  A "TRUST-ME" NOTE: THE BEST WAY TO LEARN THIS LIBRARY IS TO KEEP USING IT
  34.                     UNTIL IT WORKS.  THAT SOUNDS BACKWARDS, BUT IT IS THE
  35.                     BEST WAY TO LEARN OTHER PEOPLE'S WORK...
  36.  --------------------------------------------------------------------------
  37. }
  38.  
  39. INTERFACE
  40.  
  41. USES Crt, DOS;
  42.  
  43. {$I STRUCT.100}
  44.  
  45. CONST
  46.  
  47.   { ---[ Control Characters ]-------------- }
  48.  
  49.   NUL   = #0;    SOH   = #1;    STX   = #2;
  50.   ETX   = #3;    EOT   = #4;    ENQ   = #5;
  51.   ACK   = #6;    BELL  = #7;    BS    = #8;
  52.   HT    = #9;    LF    = #10;   VT    = #11;
  53.   FF    = #12;   CR    = #13;   SO    = #14;
  54.   SI    = #15;   DLE   = #16;   DC1   = #17;
  55.   DC2   = #18;   DC3   = #19;   DC4   = #20;
  56.   NAK   = #21;   SYN   = #22;   EOB   = #23;
  57.   CAN   = #24;   EOM   = #25;   SUB   = #26;
  58.   ESC   = #27;   FS    = #28;   GS    = #29;
  59.   RS    = #30;   US    = #31;   SP    = #32;
  60.   DEL   = #127;  BLANK = #255;
  61.  
  62.   { --------------------------------------- }
  63.  
  64.   FCommVer : STRING[11] = 'FComm v2.40';
  65.  
  66.   DeadTime : BOOLEAN = False; { if true, will not reset time limits from
  67.                                 EXITINFO.BBS to current time in FcommInit. }
  68.   ForceLocal      : BOOLEAN    = False;  {Make system Local no matter what!}
  69.   Chat            : BOOLEAN    = False;
  70.   HiRes           : BOOLEAN    = False;
  71.   UseBBS          : BOOLEAN    = False;       { for FPAD only }
  72.   QuitHOT         : BOOLEAN    = False;
  73.   WaitCall        : BOOLEAN    = False;       { for FPAD only }
  74.   AsyncCancelled  : BOOLEAN    = False;
  75.   DoorType        : (RA,
  76.                      DoorInfo,
  77.                      DoorSYS1,
  78.                      DoorSYS2) = RA;
  79.   DefBoolean      : BOOLEAN    = True;   { for InputBoolean }
  80.   DefYes          : STRING[5]  = 'Yes';
  81.   DefNo           : STRING[5]  = 'No';
  82.   DefPause        : STRING     = 'Press ENTER to continue.';
  83.   DefEcho         : BOOLEAN    = TRUE;
  84.   DefIns          : BOOLEAN    = FALSE;
  85.   DefMaxLine      : BYTE       = 255;
  86.   DefIndex        : BYTE       = 0;
  87.   DefReadForm     : BOOLEAN    = FALSE;
  88.   DefFormBack     : BOOLEAN    = FALSE;
  89.   DefAVTattr      : BYTE       = Cyan + Black;  { cyan on black }
  90.   DefMISCchar     : CHAR       = '|';
  91.  
  92.   Echo   = TRUE;
  93.   NoEcho = FALSE;
  94.  
  95. TYPE
  96.    DorInfoRec = Record
  97.                    SystemName : String;
  98.                    SysopFirst : String;
  99.                    SysopLast  : String;
  100.                    CommPort   : Integer;
  101.                    BaudRate   : WORD;
  102.                    Parity     : Char;
  103.                    DataBits   : Integer;
  104.                    StopBits   : Integer;
  105.                    Blank      : Integer;
  106.                    UserFirst  : String;
  107.                    UserLast   : String;
  108.                    City       : String;
  109.                    Graphics   : Integer;
  110.                    SecLvl     : Integer;
  111.                    MinLeft    : Integer;
  112.                  End;
  113.  
  114.    DoorSYS1Rec = RECORD
  115.                 Name        : MSGTOIDXrecord;
  116.                 CommPort    : INTEGER;               { 1..8=Active ComPort,
  117.                                                        0=Local }
  118.                 BaudRate    : WORD;                  { 300 to 38400 }
  119.                 MinLeft     : INTEGER;               { Mins under 32767 }
  120.                 Graphics    : CHAR;                  { 'G'=Graphics,
  121.                                                        'M'=Mono }
  122.                 Alarm       : CHAR;                  { 'A'=AlarmOn,
  123.                                                        'S'=SilentOn }
  124.               END;
  125.  
  126.    DoorSYS2Rec = RECORD
  127.                 CommPort          : STRING[5];  { COM0: = Local }
  128.                 BaudRate          : WORD;       { 300 to 38400 }
  129.                 Parity            : CHAR;       { 7 or 8 }
  130.                 Node              : BYTE;       { 1 to 99 (default=1) }
  131.                 DTERate           : WORD;       { Actual BPS rate to use }
  132.                 ScreenOn          : CHAR;       { 'Y', 'N' (Default=Y) }
  133.                 PrinterOn         : CHAR;       { 'Y', 'N' (Default=Y) }
  134.                 PageBellOn        : CHAR;       { 'Y', 'N' (Default=Y) }
  135.                 CallerAlarmOn     : CHAR;       { 'Y', 'N' (Default=Y) }
  136.                 Name              : MSGTOIDXrecord;
  137.                 Location          : STRING[25]; { City, State }
  138.                 VoicePhone        : STRING[12]; { ### ###-#### }
  139.                 DataPhone         : STRING[12]; { ### ###-#### }
  140.                 Password          : STRING[15]; { CAUTION! }
  141.                 Security          : INTEGER;
  142.                 NoCalls           : WORD;       { Total Times On }
  143.                 LastDate          : STRING[8];  { DD/MM/YY }
  144.                 SecLeft           : LONGINT;    { Seconds remaining online }
  145.                 MinLeft           : WORD;       { Minutes remaining online }
  146.                 Graphics          : STRING[2];  { 'GR' = Graphics,
  147.                                                   'NG' = NO Graphics,
  148.                                                   '7E' = 7 bit, even parity
  149.                                                          Graphics }
  150.                 ScreenLength      : BYTE;       { RA recommends 24 }
  151.                 ExpertModeON      : CHAR;       { 'Y', 'N' (Default=N) }
  152.                 Conferences       : STRING[80]; { Confs Registered in
  153.                                                   ie. 1,2,3,4,5,6,7
  154.                                                    or ABCDEFG }
  155.                 InConference      : CHAR;       { Current conference }
  156.                 ExpireDate        : STRING[8];  { Access ends on DD/MM/YY }
  157.                 UserRecord        : WORD;       { User File's Record Number }
  158.                 DefaultProtocol   : CHAR;       { ie. X,C,Y,G,I,N,Z, etc. }
  159.                 Uploads           : WORD;       { Total Uploads }
  160.                 Downloads         : WORD;       { Total Downloads }
  161.                 TodayK            : LONGINT;    { KB downloaded today }
  162.                 MaxTodayK         : LONGINT;    { Max KB allowed today }
  163.               END;
  164.  
  165. VAR
  166.   Local        : BOOLEAN;
  167.   Str_1        : STRING;
  168.   Ch_1         : CHAR;
  169.   ErrorLvl,
  170.   ErrorLvl0,
  171.   ErrorLvl1    : BYTE;
  172.  
  173.   LogFile      : TEXT;
  174.  
  175.   DorInfo      : DorInfoRec;
  176.   DorInfoFile  : TEXT;
  177.  
  178.   DorSYS1      : DoorSYS1Rec;
  179.   DorSYS2      : DoorSYS2Rec;
  180.   DorSYSFile   : TEXT;
  181.  
  182.   User         : UsersRecord;
  183.   UserFile     : FILE of UsersRecord;
  184.  
  185.   CFG          : ConfigRecord;
  186.   CFGFile      : FILE of ConfigRecord;
  187.  
  188.   ExitInfo     : ExitInfoRecord;
  189.   ExitInfoFile : FILE of ExitInfoRecord;
  190.  
  191.   UserOn       : UserOnRecord;
  192.   UserOnFile   : FILE of UserOnRecord;
  193.   
  194.  
  195.              { -----======[ Low-level Modem Area ]======----- }
  196. { ---  These were designed using X00 ver 1.24 FOSSIL Device Driver --- }
  197.  
  198. Procedure AsyncSend(var C: char);
  199.           { Send a Character ONLY to the ComPort }
  200.  
  201. Function AsyncReceive: CHAR;
  202.           { Receive a Character ONLY from the COM Port.  Returns a NUL char.
  203.             if one is not present. }
  204.  
  205. Procedure AsyncResetPort(BR: word; P: char;
  206.                            D, S: integer);
  207.           { Reset the ComPort to many different modem/line settings }
  208.  
  209. Function  AsyncInitPort: boolean;
  210.           { INITIALIZIES THE PORT. USE THIS BEFORE ANYTHING ELSE! }
  211.  
  212. Procedure AsyncDeInitPort;
  213.           { De-Initializes the port, including all Modem/Line Registers }
  214.  
  215. Procedure AsyncStats;
  216.           { Sends message on Local/Modem connection and Baud, etc. }
  217.  
  218. Procedure AsyncSendString(S: string);
  219.           { Send a whole string ONLY to the ComPort }
  220.  
  221. Procedure AsyncSendStringWithDelays(S: string; CharDelay,
  222.                                             EOSDelay: integer); 
  223.           { Send a whole string ONLY to the ComPort with delays between
  224.             each character, and a delay when at the end of the string. }
  225.  
  226. Procedure AsyncReadString(VAR S: String);
  227.           { Read a whole string ONLY from the ComPort }
  228.  
  229. Function  AsyncCarrierDetect: boolean; 
  230.           { Is there a modem connection present? }
  231.  
  232. Procedure AsyncReInitPort; 
  233.           { Re-Initialize the port/screen after caller. }
  234.  
  235. Function  AsyncIBufferCheck: boolean; 
  236.           { Is there anything inside the input buffer besides NUL's? }
  237.  
  238. Function  AsyncOBufferCheck: boolean; 
  239.           { Check to see if something is in the output buffer }
  240.  
  241. Procedure FlushTypeAheadBuffer;
  242.           { Get rid of anything inside the host keyboard buffer }
  243.  
  244. Procedure AsyncPurgeInputBuffer;
  245.           { Get rid of anything inside the input buffer }
  246.  
  247. Procedure AsyncPurgeOutputBuffer;
  248.           { Get rid of anything inside the output buffer }
  249.  
  250. Procedure AsyncFlushOutputBuffer;
  251.           { Wait and wait until Output buffer has emptied itself. CAUTION:
  252.             Highly-Possible to "crash" the computer with this option. }
  253.  
  254. Procedure AsyncLowerDTR;
  255.           { Drop the carrier signal quickly. "Turn off the modem" }
  256.  
  257. Procedure AsyncRaiseDTR;
  258.           { Enable the modem for a carrier. "Turns on the modem" }
  259.  
  260. Procedure AsyncHangUp;
  261.           { Hangs up the modem. Fast and simple }
  262.  
  263. Function  AsyncResultCode(Secs: integer): string;
  264.     { Responds with a Number Modem Result Code ONLY. Secs = Timeout }
  265.  
  266. Function  FossilWhereX: byte;
  267.           { Replaces WhereX Function.  Fossil controlled. }
  268.  
  269. Function  FossilWhereY: byte;
  270.           { Replaces WhereY Function.  Fossil controlled. }
  271.  
  272. Function  FossilKeyPressed: boolean;
  273.           { Replaces the KeyPressed command.  CAUTION: Do not mix the
  274.             standard KeyPressed/ReadKey with the Fossil versions. Use
  275.             one or the other! }
  276.  
  277. Function  FossilReadKey: char;
  278.           { Replaces TP's ReadKey Function }
  279.  
  280. Procedure FossilWatchdogOn;
  281.           { Turns on a internal WatchDog.  Reboots if carrier is dropped. }
  282.  
  283. Procedure FossilWatchdogOff;
  284.           { Turns OFF a internal WatchDog.  CAUTION: Use WatchDog ONLY if
  285.             necessary! }
  286.  
  287. Procedure FossilWarmBoot;
  288.           { Re-boot the system with a warm-bootstrap (just boot). }
  289.  
  290. Procedure FossilColdBoot;
  291.           { Re-boot the system with a cold-bootstrap (power-up, self-test and
  292.             boot) }
  293.  
  294. { -----=====[ Low Maintainance Modem Processing Area ]=====----- }
  295.  
  296. Function  TestBit(Num: INTEGER; Bit: INTEGER): BOOLEAN;
  297.           { TEST a Bit of a Number whether it is ON or OFF }
  298.  
  299. Procedure SetBit(var Target; Bit : INTEGER);
  300.           { 1 - Make a bit of a number (ON) }
  301.  
  302. Procedure ClearBit(var Target; Bit : INTEGER);
  303.           { 0 - Make a bit of a number (OFF }
  304.  
  305. function ShowBit(TmpINT: INTEGER): STRING;
  306.          { Show the contents of a integer from Lo-order to Hi-order bits.
  307.            'X' = ON, and '-' = OFF }
  308.  
  309. function Timeout(Secs: BYTE): BOOLEAN;
  310.          { Waits for a reply from COM Port in specified amount of time }
  311.  
  312. function  FKeyPressed: BOOLEAN;
  313.           { Has a character been pressed (either side)? }
  314.  
  315. function  FReadKey: CHAR;
  316.           { If FKeyPressed is true, then take that character }
  317.  
  318. function  Carrier: BOOLEAN;
  319.           { Is a carrier detected? }
  320.  
  321. procedure SetBaud(BaudNum: BYTE);
  322.           { Set the bps rate from 1 (300) to 5 (19.2K) w/o checks }
  323.  
  324. procedure SyncBaud;
  325.           { Syncronize this modem's BPS to other side }
  326.  
  327. { -----======[ Mid-level Modem/Screen OUTPUT Area ]======----- }
  328.  
  329. procedure WriteA(var C: CHAR);
  330.           { Character is written w/emulated ANSI and AVATAR writes.
  331.             Direct or BIOS writes are available. }
  332.  
  333. procedure WriteL(L: STRING);
  334.           { A whole line of WriteA }
  335.  
  336. procedure PrintR(C: CHAR);
  337.           { RAW, unformatted, one-character output w/echo to comm }
  338.  
  339. procedure PrintD(Out: STRING);
  340.           { DIRECTLY writes a line to COM port and local }
  341.  
  342. Procedure StatusLine;
  343.           { Display/Update status line }
  344.  
  345. procedure CheckTimeout;
  346.           { Checks every SECMOD seconds for a timeout. Note, you must do a
  347.             "Timer1 := TimerSet;"  prior to this call! }
  348.  
  349. procedure PrintO(C: CHAR);
  350.           { OPTION version of the 'PrintR'.
  351.             Checks for Pause, Stop and ScrnPause features }
  352.  
  353. procedure Print(Out: STRING);
  354.           { Prints a whole line using the above method }
  355.  
  356. procedure PrintLn(Out: STRING);
  357.           { Same as Print procedure, but w/CRLF }
  358.  
  359. procedure CRLF;
  360.           { Down to new line. scrolls text }
  361.  
  362. { -----======[ Mid-level Modem/Screen INPUT Area ]======----- }
  363.  
  364. procedure FRead(VAR TmpCH: CHAR);
  365.           { Take a character.  Uses WithEcho, but sets it true
  366.             when done. }
  367.  
  368. procedure FReadLn( VAR S1 );
  369.           { Inputs a whole line of text as a type string }
  370.  
  371. function  InputBoolean: BOOLEAN;
  372.           { Single Y or N input, and converts into a boolean response.
  373.             Uses DEFAULTBOOLEAN global boolean if CR pressed }
  374.  
  375. function  ReadBoolean: BOOLEAN;
  376.           { Same as InputBoolean, but works only locally }
  377.  
  378. Procedure AsyncPause;
  379.           { Show DefaultPause to screen, then wait for a keypress. }
  380.  
  381. Procedure PauseOn;
  382.           { Turn screen pausing on. }
  383.  
  384. Procedure PauseOff;
  385.           { Turn screen pausing off. }
  386.  
  387.  { -----======[ Misc. String and Screen Utility Area ]======----- }
  388.  
  389. procedure LogEcho(S: STRING);
  390.           { Echo RA formatted string to log file }
  391.  
  392. function  Misc(S: STRING): STRING;
  393.           { Miscellanous ANSI & other special codes:
  394.  
  395.     EMULATED:
  396.     00 = black,         01 = blue,          02 = green,
  397.     03 = cyan,          04 = red,           05 = magenta,
  398.     06 = brown,         07 = light gray,    08 = dark gray,
  399.     09 = light blue,    10 = light green,   11 = light cyan,
  400.     12 = light red,     13 = light magenta, 14 = yellow,
  401.     15 = white
  402.  
  403.     20 = black BC,      21 = blue BC,       22 = green BC,
  404.     23 = cyan BC,       24 = red BC,        25 = magenta BC,
  405.     26 = brown BC,      27 = light gray BC  28 = Set TextAttr to N
  406.  
  407.     30 = Attr RESET,    31 = Blink ON,      32 = ClrScr,
  408.     33 = ClrEol,        34 = Home,          35 = GotoXY(X,Y),
  409.     36 = Up 1 line,     37 = Down 1 line,   38 = Right 1 line,
  410.     39 = Left 1 line
  411.  
  412.     ANSI:
  413.     40 = Bold ON,       41 = Faint ON,      42 = Italic ON,
  414.     43 = Fast Blink ON, 44 = Rev. Video ON, 45 = Concealed ON,
  415.     46 = Subscript ON,  47 = Superscript ON,
  416.     48 = ClrScr ≤,      49 = ClrScr ≥,      50 = ClrEol ≤,
  417.     51 = BlankLine,     52 = InsLine,       53 = DelLine,
  418.     54 = Device Status Report (for auto-ANSI detecting),
  419.     55 = Save pos,      56 = Restore pos,
  420.     57 = Wrap at EOL,   58 = No wrap at EOL
  421.  
  422.     INTERNAL:
  423.     70 = ANSI Toggle,   71 = AVATAR Toggle, 72 = MinsLeft Str,
  424.     73 = SecsLeft Str,  74 = Hang-up User,  75 = SetBaud(N)
  425.  
  426.     AVT/0:
  427.     80 = Fill_Char (Repeat sending Chr(X) Y times)
  428.  
  429.     NOTES:  ■ X = FHInfo.X, Y = FHInfo.Y and N = FHInfo.N
  430.              (these have to be preset before execution!)
  431.             ■ AVATAR is given highest priority,
  432.               ANSI is second,
  433.               NONE is last
  434.  
  435.   }
  436.  
  437. procedure Error(Job: BYTE);
  438.           { Built-in time-programming saving for simply programming. }
  439.  
  440. Function PosNext(SubS: STRING; S: STRING): STRING;
  441.          { Locates a next sub-string within a string seperated by
  442.            commas.  If no more, then it returns '' }
  443.  
  444. function  StrToVal(S: STRING): WORD;
  445.           { Convert a String to a Ordinal number }
  446.  
  447. function  LoCase(Ch: CHAR): CHAR;
  448.           { Converts a character to Lower Case.  Supplement to the UpCase
  449.             Function }
  450.  
  451. function  UpperCase(Letters: STRING): STRING;
  452.           { Converts a line of text into Upper Case }
  453.  
  454. function  LowerCase(Letters: STRING): STRING;
  455.           { Converts a line of text into Lower Case }
  456.  
  457. function  FirstCase(Letters: STRING): STRING;
  458.           { Makes first character of line Upper Case, and rest Lower Case }
  459.  
  460. function  FirstName(Letters: STRING): STRING;
  461.           { Returns the first name (or first word) within the Letters string }
  462.  
  463. function  RealName(Letters: STRING): STRING;
  464.           { Returns first name in a two/more-word name or
  465.             last name in a one-word name. }
  466.  
  467. function  LastName(Letters: STRING): STRING;
  468.           { Returns the last name (or last word) within the Letters string }
  469.  
  470. function  PadStrL(Letters: STRING; Pad: BYTE): STRING;
  471.           { Pad a string to a certain size.  Justified left side }
  472.  
  473. function  PadStrR(Letters: STRING; Pad: BYTE): STRING;
  474.           { Same as PadStrL, but justifies to the right side }
  475.  
  476. function  FJustify( S: STRING; LeftBorder, RightBorder: BYTE ) : STRING;
  477.           { Justify a string within these boundarys.
  478.             Implants CRLF's and Spaces(s). WARNING: Truncates
  479.             the orginal string at 255 characters (string)! }
  480.  
  481. Function  FExist(FName: STRING) : BOOLEAN;
  482.           { See if "FName" can be found.  Should be in DOS unit :) }
  483.  
  484. function  FileExist(Fil: STRING; var Extension: STRING): BOOLEAN;
  485.           { Checks for a existing file. If so, the extension is returned. }
  486.  
  487. procedure TypeFile(Fil: STRING; ShowHeader: BOOLEAN);
  488.           { Types out a text file if exists and right graphics mode.
  489.             ShowHeader is if Hot-Key List will be shown. }
  490.  
  491. procedure STDIO;
  492.           { Lets redirrection of Input & Output }
  493.  
  494. procedure CLS;
  495.           { Clears COM and local screens. }
  496.  
  497. procedure FINDLOCATE(var R,C: BYTE);
  498.           { Finds Rows and Column of the cursor on the screen }
  499.  
  500. function  LOCATE(R,C: BYTE): STRING;
  501.           { if ANSI toggled, locates cursor to new position. If R or C
  502.             is = to 0, then it assumes the current position to substitute. }
  503.  
  504. procedure GotoRC(R1 , C1 : BYTE);
  505.           { Uses LOCATE command within a nifty procedure. }
  506.  
  507. function  TAB(place: byte): string;
  508.           { Place the cursor onto a tab position. !! Needs work. }
  509.  
  510. procedure Message(Msg: STRING);
  511.           { write out a fast message for a local reader }
  512.  
  513. { -----======[ Misc. Time and DOS File Utility Area ]======----- }
  514.  
  515. Procedure DumbTerminal(SmartMode: BOOLEAN);
  516.           { A dumb terminal w/ANSI w/option of word-wrapping (SmartMode) }
  517.  
  518. Procedure DMYtoDate(Day,Month,Year: integer;var Julian: Word);
  519.           { Convert from day,month,year to a date }
  520.           { Stored as number of days since January 1, 1990 }
  521.           { Note that no error checking takes place in this routine -- use ValidDate }
  522.  
  523. procedure DateToDMY(Julian: Word;var Day,Month,Year: integer);
  524.           { Convert from a date to day,month,year }
  525.  
  526. function  TellTime: STRING;
  527.           { Returns a string format of the current TIME }
  528.  
  529. function  TellAllTime: STRING;
  530.           { Returns Hour:Minute:Seconds of the current time }
  531.  
  532. function  StrToMin(InTime: STRING): WORD;
  533.           { 'TellTimeInMinutes' a word containing the time in minutes }
  534.  
  535. function  StrToSec(InTime: STRING): LONGINT;
  536.           { Convert the "InTime" String to a longint number.
  537.             24 hours = 86400 }
  538.  
  539. function  TimerSet: LONGINT;
  540.           { Sets an internal variable with the current time in seconds }
  541.  
  542. function  TimeLeftSec: LONGINT;
  543.           { Return the total seconds left for call.  Checks for midnight law.
  544.             Returns a negative is no time left. }
  545.  
  546. function  MinsLeft: INTEGER;
  547.           { Number of minutes left for call }
  548.  
  549. function  MinsUsed: INTEGER;
  550.           { Number of minutes used for the caller so far }
  551.  
  552. function  MinsTimer(InTime: STRING): INTEGER;
  553.           { If you use timers for some purpose, this will return the
  554.             absolute difference of the present time and InTime }
  555.  
  556. function  SecsTimer(Timer: LONGINT): LONGINT;
  557.           { Same as MinsTimer, though seconds returned. }
  558.  
  559. function  TellDate: STRING;
  560.           { Returns a string format of the current DATE }
  561.  
  562. function  ANSI: boolean;
  563.           { Does the user have ANSI graphics turned on? bitmapped }
  564.  
  565. function  AVATAR: boolean;
  566.           { Does the user have AVATAR graphics turned on? bitmapped }
  567.  
  568. function  SoundOn: boolean;
  569.           { Does the system have sound on?  Checks "WANT CHAT" config. }
  570.  
  571. procedure AssignFiles(S: STRING);
  572.           { Initializes data files for use. S lists which files to Assign }
  573.  
  574. procedure CloseFiles(S: STRING);
  575.           { Closes all data files. S lists which files to Close }
  576.  
  577. procedure SaveDorInfo;
  578.           { Save infomation to DORINFO1.DEF }
  579.  
  580. procedure LoadDorInfo;
  581.           { Load information from DORINFO1.DEF }
  582.  
  583. procedure SaveDoorSYS;
  584.           { Save information to DOOR.SYS.  Checks DoorType for method }
  585.  
  586. procedure LoadDoorSYS;
  587.           { Load information from DOOR.SYS.  Checks DoorType for method }
  588.  
  589. function  GetRAEnv: STRING;
  590.           { Find location of RA directory from DOS enviroment }
  591.  
  592. Procedure SaveExitInfo;
  593.           { Save current exit info record data file. }
  594.  
  595. procedure LoadExitInfo;
  596.           { Load the EXITINFO.BBS per user. }
  597.  
  598. procedure LoadUser;
  599.           { Load specific user information.  Information pre-included
  600.             inside the exitinfo record. }
  601.  
  602. procedure SaveUser;
  603.           { Save current user record data. }
  604.  
  605. function  FindUser(S: STRING): BOOLEAN;
  606.           { Searchs for S (the full user name) inside USERS.BBS, true if
  607.             found and USER/EXITINFO.USERINFO records are ready to be used. }
  608.  
  609. Procedure LoadConfig;
  610.           { Load CONFIG.BBS data into record. }
  611.  
  612. { ****************************************** }
  613.  
  614. PROCEDURE FCOMMINIT;
  615.           { INITIALIZES FCOMM.  MUST BE USED BEFORE ANY I/O PROCEDURES! }
  616.  
  617. { ****************************************** }
  618.  
  619. { The following is VERY useful for Print and PrintLn (since everything
  620.   has to be strings).  I just want to credit the person whom wrote them,
  621.   but I found them somewhere long ago, and can't find the original
  622.   author..  If anyone knows, please contact me!  Thank you }
  623.  
  624. function StrL   (L: longint):                       string;
  625.          { Converts a Longint into a String }
  626.  
  627. function StrLF  (L: longint; Field: integer):       string;
  628.          { Converts a Longint into a String w/Field parameter }
  629.  
  630. function StrR   (R: real):                          string;
  631.          { Converts a Real into a String }
  632.  
  633. function StrRF  (R: real; Field: integer):          string;
  634.          { Converts a Real into a String w/Field parameter }
  635.  
  636. function StrRFD (R: real; Field,Decimals: integer): string;
  637.          { Converts a Real into a String w/Field width and Decimal Places }
  638.  
  639. { -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- }
  640.  
  641. IMPLEMENTATION
  642.  
  643. { -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- }
  644.  
  645. CONST
  646.   UsersBBS       = 'USERS.BBS';
  647.   ExitInfoBBS    = 'EXITINFO.BBS';
  648.   ConfigRA       = 'CONFIG.RA';
  649.   RaLOG          = 'RA.LOG';
  650.   DorInfo1DEF    = 'DORINFO1.DEF';
  651.   DoorSYS        = 'DOOR.SYS';
  652.   CommandCOM     = 'COMMAND.COM';
  653.   ChatOnLine     = 'is breaking in...';
  654.   ChatOffLine    = 'is now gone.';
  655.  
  656.   UsersBBSopened    : BOOLEAN = FALSE;
  657.   ExitInfoBBSopened : BOOLEAN = FALSE;
  658.   ConfigRAopened    : BOOLEAN = FALSE;
  659.   RaLOGopened       : BOOLEAN = FALSE;
  660.   DorInfo1DEFopened : BOOLEAN = FALSE;
  661.   DoorSYSopened     : BOOLEAN = FALSE;
  662.   TripEndOfDay      : BOOLEAN = FALSE;
  663.   ErrorJob          : BYTE = 1;
  664.   ScrnPos           : BYTE = 1;
  665.   SecMod            = 2;  { Check for Carrier drop, Keyhit timeout }
  666.                           { and Timelimit every SecMod seconds }
  667. TYPE
  668.    Str4        = STRING[4];
  669.  
  670.    EMSIrec     = RECORD               { Reserved for Interactive EMSI }
  671.                    InsertMode   : BOOLEAN;
  672.                    GraphicsMode : BYTE;
  673.                    ULX,
  674.                    ULY,
  675.                    LRX,
  676.                    LRY          : BYTE;
  677.                  END;
  678.  
  679.    StatLineRec = RECORD
  680.                    Mode         : BYTE;
  681.                    TextAttr     : BYTE;
  682.                    ULX          : BYTE;
  683.                    ULY          : BYTE;
  684.                    LRX          : BYTE;
  685.                    LRY          : BYTE;
  686.                  END;
  687.  
  688.    ReadRec     = RECORD
  689.                    FormMode     : BOOLEAN;
  690.                    ReadIndex    : BYTE;
  691.                    MaxIndex     : BYTE;
  692.                    SplitLine    : BOOLEAN;
  693.                    ContractLine : BOOLEAN;
  694.                    Up           : BOOLEAN;
  695.                    Down         : BOOLEAN;
  696.                    OnL          : BOOLEAN;
  697.                    OnR          : BOOLEAN;
  698.                    ListHead     : POINTER;
  699.                    ListTail     : POINTER;
  700.                    WordWrap     : BOOLEAN;
  701.                    StringMode   : BOOLEAN;
  702.                    AttrBold     : BYTE;
  703.                    SaveX        : BYTE;
  704.                    SaveY        : BYTE;
  705.                    SaveTextAttr : BYTE;
  706.                  END;
  707.  
  708.    InterFHInfo = RECORD
  709.      ReadInfo     : ReadRec; { Input (line, form) information }
  710.      EMSI         : EMSIrec; { Interactive EMSI information }
  711.      StatLine     : StatLineRec; { Status Line information }
  712.      X            : BYTE;    { General purpose variable }
  713.      Y            : BYTE;    {    "       "        "    }
  714.      N            : BYTE;    {    "       "        "    }
  715.    END;
  716.  
  717. VAR
  718.   FHInfo       : InterFHInfo;
  719.   Regs         : Registers;
  720.   SaveExitProc : POINTER;
  721.   StartTime,
  722.   Timer1       : LONGINT;
  723.   Hour,
  724.   Minute,
  725.   Second,
  726.   Sec100,
  727.   Year,
  728.   Month,
  729.   Day,
  730.   DayOfWeek    : WORD;
  731.   L1,
  732.   L2           : INTEGER;
  733.   FosInit      : BOOLEAN;
  734.   SecCheck     : BYTE;
  735.   AVTcmd       : STRING[10];
  736.   ANSIcmd      : STRING[40];
  737.  
  738. { ------------------------------------------------------------------------ }
  739.  
  740.