home *** CD-ROM | disk | FTP | other *** search
/ Between Heaven & Hell 2 / BetweenHeavenHell.cdr / 500 / 433 / pyroto.pas < prev    next >
Pascal/Delphi Source File  |  1986-12-23  |  19KB  |  490 lines

  1. {$C-}
  2. PROGRAM Pyroto;  { Version 3.0 }
  3.  
  4. {
  5.   ┌──────────────────────────────────────────────────────┬──────────────────┐
  6.   │ Pinnacle Software's  Pyroto Mountain BBS/Game System │    PYROTO.PAS    │
  7.   ├──────────────────────────────────────────────────────┴──────────────────┤
  8.   │  C O P Y R I G H T  (C)  1986  BY   P I N N A C L E    S O F T W A R E  │
  9.   │  P.O. Box 163, Cartierville Station, Montreal, Quebec, Canada  H4K 2J5  │
  10.   ├─────────────────────────────────────────────────────────────────────────┤
  11.   │ The Pyroto Mountain product may not be  distributed  except in its com- │
  12.   │ plete and unaltered form.   Products based on this source code  may not │
  13.   │ marketed or placed into public domain,  except by prior written permis- │
  14.   │ sion from Pinnacle Software.                                            │
  15.   └─────────────────────────────────────────────────────────────────────────┘
  16. }
  17.  
  18. TYPE
  19.   TenType   = STRING[10];
  20.   ComLine   = STRING[42];
  21.   UNameType = STRING[20];
  22.   FNType    = STRING[40];
  23.   Line      = STRING[80];
  24.   String100 = STRING[100];
  25.   RegPack   = RECORD
  26.                 ax,bx,cx,dx,bp,di,si,ds,es,flags: INTEGER;
  27.               END;
  28.   SFType    = (OpenError, Okay, Quit);
  29.   LeftRight = (Left, Right);
  30.   MsgTimesType =
  31.   RECORD
  32.     Date_Added : INTEGER;
  33.     Mint_Added : INTEGER;
  34.     MsgBand    : CHAR;
  35.     Poster     : UNameType;
  36.   END;
  37.   QuestType =
  38.   RECORD
  39.     Question : STRING[40];
  40.     Answer   : STRING[30];   { antidisestablishmentarianism }
  41.   END;
  42.   SeismoType =
  43.   RECORD
  44.     Energy : INTEGER;
  45.     Spare1 : INTEGER;
  46.     Spare2 : INTEGER;
  47.   END;
  48.   SysLogType =
  49.   RECORD
  50.     SLDate : INTEGER;    { Date }
  51.     SLMint : INTEGER;    { Time }
  52.     SLType : CHAR;       { Type of user who can read this }
  53.     SLText : Line;       { What it was }
  54.     SLRept : INTEGER;    { Repetitions }
  55.   END;
  56.   UsersType =
  57.     RECORD
  58.       {--- General Info ---}   { ----+----1----+----2----+----3 }
  59.       RealName  : UNameType;   { Harry Q. Smithereens }
  60.       Phone     : STRING[25];  { 1-514-555-1234 EXT. 12345 }
  61.       UserName  : UNameType;   { Johnny Strangechange }
  62.       Password  : STRING[10];  { HOWDYDOODY }
  63.       Level     : INTEGER;
  64.       Points    : INTEGER;
  65.       Date_Last : INTEGER;     { If ZERO, flagged as deleted }
  66.       Mint_Last : INTEGER;
  67.       Width     : INTEGER;
  68.       MsgsSent  : INTEGER;
  69.       MaxLevel  : INTEGER;     { If ZERO, no limit }
  70.       {--- Bulletins-Read Info ---}
  71.       Date_A    : INTEGER;  { Low-Wizards Board }
  72.       Mint_A    : INTEGER;
  73.       Date_B    : INTEGER;  { Middle Wizards Board }
  74.       Mint_B    : INTEGER;
  75.       Date_C    : INTEGER;  { Middle-High Wizards Board }
  76.       Mint_C    : INTEGER;
  77.       Date_D    : INTEGER;  { High Wizards Board }
  78.       Mint_D    : INTEGER;
  79.       Date_P    : INTEGER;  { Beseech Board }
  80.       Mint_P    : INTEGER;
  81.       Date_S    : INTEGER;  { SCROLLS Board }
  82.       Mint_S    : INTEGER;
  83.       Date_X    : INTEGER;  { Crowds 0 board }
  84.       Mint_X    : INTEGER;
  85.     END;                    { PROCLAIM board time is same as "last call" }
  86. CONST
  87.   CoP  : ComLine = 'COPYRIGHT (C) 1986 by Pinnacle Software.';
  88.   Ver  : TenType = '3.01AA';
  89. CONST { Calender Info }
  90.   DaysInMonth : ARRAY[1..12] OF INTEGER =
  91.   (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  92. CONST { Control Characters }
  93.   BEL  : CHAR = ^g;
  94.   BS   : CHAR = ^h;
  95.   CR   : CHAR = ^m;
  96.   ESC  : CHAR = #27;
  97.   LF   : CHAR = ^j;
  98.   NUL  : CHAR = #0;
  99.   XON  : CHAR = ^q;
  100.   XOF  : CHAR = ^s;
  101. CONST  { Serial Control }
  102.   RReady           = 1;
  103.   TReady           = $20;
  104.   BaudConst : real = 115200.0;
  105. CONST { Constraints and Configuration }
  106.   BoardNames   : STRING[10] = '0ABCDGPSX';  { Not used universally }
  107.   File_Article : FNType = 'ARTICLE.TXT';   { Promote-discussion article }
  108.   File_Hints   : FNType = 'HINTS.TXT';     { Hints for Pyroto }
  109.   File_Info    : FNType = 'INFO.TXT';      { Info about Pyroto }
  110.   File_Nature  : FNType = 'NATURE.TXT';    { Nature of TSOTL }
  111.   File_Next    : FNType = 'MSGNEXT.DAT';   { Last msg# added }
  112.   File_Queries : FNType = 'QUERIES.DAT';   { Question files }
  113.   File_Rules   : FNType = 'RULES.TXT';     { Rules }
  114.   File_Straight: FNType = 'STRAIGHT.TXT';  { Straight-talk }
  115.   File_Seismo  : FNType = 'SEISMO.DAT';    { Seismoros }
  116.   File_Specs   : FNType = 'SPELLS.DAT';    { Spell specifications }
  117.   File_SysLog  : FNType = 'OBSERVE.DAT';   { OBSERVE log }
  118.   File_Times   : FNType = 'MSGTIMES.DAT';  { Times of each message }
  119.   File_Users   : FNType = 'USERLIST.DAT';  { List of users }
  120.   MaxMsgLen   = 27;     { Number of lines in a message }
  121.   MaxMsgs     = 225;    { Number of messages }
  122.   MaxSysLog   = 250;    { Filesize for OBSERVE log }
  123.   MaxUsers    = 350;    { In-core index size of 10,000 bytes per 500 }
  124.   NumCmds     = 57;
  125.   CmdWords : ARRAY[1..NumCmds] OF TenType = (
  126.     'ARTICLE',  'ASCEND',   'BANISH',   'BESEECH',  'BESTOW',
  127.     'BOOST',    'BYE',      'CHANGE',   'CHARGE',   'CHECK',
  128.     'CLOAK',    'CLOSE',    'CONTACT',  'CORRECT',  'DEFOCUS',
  129.     'DEMOTE',   'DESCEND',  'DETECT',   'DETUNE',   'DRAIN',
  130.     'FEED',     'FOCUS',    'HELP',     'HINTS',    'HURL',
  131.     'INFO',     'INQUIRE',  'INSCRIBE', 'LISTEN',   'MANNA',
  132.     'NATURE',   'OBSERVE',  'OMNIVIEW', 'PROBE',    'PROCLAIM',
  133.     'PROMOTE',  'READ',     'RECALL',   'REDUCE',   'REVIEW',
  134.     'ROSTER',   'RULES',    'SANCTIFY', 'SCAN',     'SCROLLS',
  135.     'SEND',     'SLOWTIME', 'SPECS',    'SPELLS',   'STARVE',
  136.     'STEAL',    'STOPTIME', 'STRAIGHT', 'SUGGEST ', 'TELEPORT',
  137.     'TIMEWARP', 'TUNE'
  138.     );
  139.   CmdDescs : ARRAY[1..NumCmds] OF ComLine = (
  140.    'An article added to  promote discussion',   { ARTICLE }
  141.    'Attempt to pass into next sorcery level',   { ASCEND }
  142.    'Banish somebody  and destroy  his power',   { BANISH }
  143.    'Send message to  The Spirit of the Land',   { BESEECH }
  144.    'Give some of your MPs to another person',   { BESTOW }
  145.    'Boost  transmission  speed  (baud rate)',   { BOOST }
  146.    'Depart  (disconnect)  from  this  place',   { BYE }
  147.    'Change messages  you''ve sent previously',  { CHANGE }
  148.    'Attempt ascent - disconnect if you fail',   { CHARGE }
  149.    'Display pertinent  data  about yourself',   { CHECK }
  150.    'A protected form of CHARGE -- very safe',   { CLOAK }
  151.    'Terminate  system  and  return  to  DOS',   { CLOSE }
  152.    'Speak to The Spirit Of The Land (TSOTL)',   { CONTACT }
  153.    'Rewrite one of the Guardians'' questions',  { CORRECT }
  154.    'Reset the "display" spells  after FOCUS',   { DEFOCUS }
  155.    'Demote  somebody to lower sorcery level',   { DEMOTE }
  156.    'Go downwards to visit the less powerful',   { DESCEND }
  157.    'Display  info  about  previous messages',   { DETECT }
  158.    'Reset the "reading" spells after a TUNE',   { DETUNE }
  159.    'Subtract 100 Manna-points from somebody',   { DRAIN }
  160.    'Add some energy to the Seismoros spirit',   { FEED }
  161.    'Focus "display" spells  on given phrase',   { FOCUS }
  162.    'Display your usable spells  (this list)',   { HELP }
  163.    'Display handy  survival and usage  tips',   { HINTS }
  164.    'Cast a message back to the dawn of time',   { HURL }
  165.    'Display  some  info  about  this  place',   { INFO }
  166.    'Display how long until TSOTL gets tired',   { INQUIRE }
  167.    'Write upon the Tidings  (news)  Scrolls',   { INSCRIBE }
  168.    'Display the messages  sent via  BESEECH',   { LISTEN }
  169.    'Get a generous recharge of Manna-points',   { MANNA }
  170.    'Read the about the True Nature of TSOTL',   { NATURE }
  171.    'Display recent activity on the Mountain',   { OBSERVE }
  172.    'Display  PROBE  stats for  all  wizards',   { OMNIVIEW }
  173.    'Get information  about specified wizard',   { PROBE }
  174.    'Write a new  greeting (sign-on) message',   { PROCLAIM }
  175.    'Promote somebody to next  sorcery level',   { PROMOTE }
  176.    'Display messages you''re allowed to read',  { READ }
  177.    'Display  report  of  previous  visitors',   { RECALL }
  178.    'Reduce somebody  to sorcery level  zero',   { REVIEW }
  179.    'Re-read a single message by  DAY:MINUTE',   { REDUCE }
  180.    'Display the  names  of all  the wizards',   { ROSTER }
  181.    'Display  rules  imposed on the Mountain',   { RULES }
  182.    'Permit a user to rise to  higher levels',   { SANCTIFY }
  183.    'All-bands READ -- use with FOCUS & TUNE',   { SCAN }
  184.    'Display the latest, most important news',   { SCROLLS }
  185.    'Leave message for other wizards to read',   { SEND }
  186.    'Add fifteen minutes to TSOTL''s patience',  { SLOWTIME }
  187.    'Alter the way things  look  around here',   { SPECS }
  188.    'Display the Levels & MP costs of spells',   { SPELLS }
  189.    'Remove energy from the Seismoros spirit',   { STARVE }
  190.    'Like DRAIN, but cheaper -- costs Esteem',   { STEAL }
  191.    'Double the time TSOTL will tolerate you',   { STOPTIME }
  192.    'Straight Talk  article from the Servant',   { STRAIGHT }
  193.    'Provide the Guardians with new question',   { SUGGEST }
  194.    'Instant  transition  to specified level',   { TELEPORT }
  195.    'Set a time after which you wish to READ',   { TIMEWARP }
  196.    'Tune "reading" spells  for given phrase'    { TUNE }
  197.    );
  198. CONST { Local colour }
  199.   MaxDescTexture = 15;
  200.   DescTexture : ARRAY[1..MaxDescTexture] OF STRING[20] =
  201.   ( 'an incredibly scuzzy',  'a peculiar-looking',   'a flaming, white-hot',
  202.     'a horror!  He is a',    'strange enough:  A',   'a mottled & speckled',
  203.     'a vicious, ferocious',  'half-dog and half-',   'a slimey, oooozing',
  204.     'scarey!  He''s a huge', 'something akin to a',  'shaped a bit like a',
  205.     'a gigantic, smelly',    'a bit similar to a',   'a green and yellow');
  206.   MaxDescType = 14;
  207.   DescType    : ARRAY[1..MaxDescType] OF STRING[12] =
  208.   ( 'dragon', 'lizard', 'robot', 'gnome', 'were-wolf', 'unicorn', 'bear',
  209.     'lion', 'gorilla', 'panther', 'leprechaun', 'man', 'reptile', 'cobra' );
  210.   MaxDescCharac = 26;
  211.   DescCharac  : ARRAY[1..MaxDescCharac] OF STRING[26] =
  212.  ( ' wearing plate armour',        ', holding a nasty sabre',
  213.    ' with a bazooka',              ', wearing a digital watch',
  214.    ' holding a ticking bomb',      '.  He''s chewing on a bone',
  215.    ' with a slight lisp',          ' with razor-sharp fangs',
  216.    '.  He doesn''t look happy',    ', grinning evilly',
  217.    ' with a surly disposition',    ', reading a book',
  218.    '.  He is happy to see you',    '.  He seems nice enough',
  219.    ' -- and he looks hungry..',    ' with long yellow tusks',
  220.    '.  A nightmare, for sure',     ' with awful, staring eyes',
  221.    '.  He''s got a gun..',         ' dressed in black satin',
  222.    ', playing solitaire',          ' covered in dust and grime',
  223.    ', picking his teeth..',        ', wearing a tall top hat',
  224.    '.  He looks up and snarls',    '.  Not a pretty sight' );
  225. VAR  { Listed in alphabetical order }
  226.   Adding        : BOOLEAN;
  227.   Alert         : BOOLEAN;
  228.   AlertName     : Line;
  229.   Altitude      : INTEGER;
  230.   AscCnt        : INTEGER;
  231.   Ascendable    : BOOLEAN;
  232.   AscLast       : INTEGER;
  233.   Attn          : ComLine;
  234.   Banner        : ARRAY[1..8] OF ComLine;
  235.   BaudRate      : INTEGER;
  236.   Blanks        : Line;
  237.   BreakPoint    : INTEGER;
  238.   BSCntr        : INTEGER;
  239.   Charging      : BOOLEAN;
  240.   ChatAsk       : BOOLEAN;
  241.   Chattable     : BOOLEAN;
  242.   ChPtr         : INTEGER;
  243.   ChSize        : INTEGER;
  244.   Cloaked       : BOOLEAN;
  245.   Comm          : BOOLEAN;
  246.   Cmd           : Line;
  247.   CmdCosts      : ARRAY[1..NumCmds] OF INTEGER;
  248.   CmdLevel      : INTEGER;
  249.   CmdLevels     : ARRAY[1..NumCmds] OF INTEGER;
  250.   CmdWasTyped   : BOOLEAN;
  251.   CmdParm       : Line;
  252.   CmdLen        : BYTE ABSOLUTE CmdParm;  { New for Version 3.01 }
  253.   CharDuringO   : BOOLEAN;
  254.   Com1Base      : INTEGER;
  255.   Communicative : BOOLEAN;
  256.   Contacting    : BOOLEAN;
  257.   DataPort      : INTEGER;
  258.   Date          : INTEGER;
  259.   Date_Last     : INTEGER;
  260.   Date_Warp     : INTEGER;
  261.   DFLocation    : FNType;
  262.   DisconDelay   : INTEGER;
  263.   DisconMethod  : ComLine;
  264.   DuringOChar   : CHAR;
  265.   EditBuffer    : ARRAY[1..MaxMsgLen] OF STRING[80];
  266.   ExFnKey       : BOOLEAN;
  267.   Explained     : BOOLEAN;
  268.   FocusString   : Line;
  269.   HadCarrier    : BOOLEAN;
  270.   HighBaud      : INTEGER;
  271.   Inputting     : BOOLEAN;
  272.   InputLine     : String100;
  273.   InputLen      : BYTE ABSOLUTE InputLine;
  274.   InputTime     : REAL;
  275.   IntReg        : INTEGER;
  276.   LastChar      : CHAR;
  277.   Last2Char     : CHAR;
  278.   Level         : INTEGER;
  279.   LenCnt        : INTEGER;
  280.   LineContrl    : INTEGER;
  281.   LocalUser     : BOOLEAN;
  282.   LowBaud       : INTEGER;
  283.   Logoff        : BOOLEAN;
  284.   MannaRecharge : BOOLEAN;
  285.   MannaPoints   : INTEGER;
  286.   MaxLev        : INTEGER;
  287.   Mint          : INTEGER;
  288.   Mint_Last     : INTEGER;
  289.   Mint_Warp     : INTEGER;
  290.   MFLocation    : FNType;
  291.   Modem300      : ComLine;
  292.   Modem1200     : ComLine;
  293.   Modem2400     : ComLine;
  294.   ModemAttn     : ComLine;
  295.   ModemConfig   : ComLine;
  296.   ModemContrl   : INTEGER;
  297.   ModemDoAnswer : ComLine;
  298.   ModemHangUp   : ComLine;
  299.   ModemNoAnswer : ComLine;
  300.   ModemOkay     : ComLine;
  301.   ModemPickUp   : ComLine;
  302.   ModemReset    : ComLine;
  303.   ModemStatus   : INTEGER;
  304.   Multiple      : BOOLEAN;
  305.   MsgBands      : ARRAY[1..MaxMsgs] OF CHAR;
  306.   MsgDates      : ARRAY[1..MaxMsgs] OF INTEGER; { 300 msgs uses 1.2K core }
  307.   MsgMints      : ARRAY[1..MaxMsgs] OF INTEGER; { See above }
  308.   MsgPosters    : ARRAY[1..MaxMsgs] OF UNameType;
  309.   MsgPtr        : INTEGER;
  310.   MsgTimesRec   : MsgTimesType;
  311.   MyPassword    : TenType;
  312.   NewUser       : BOOLEAN;
  313.   NextLog       : INTEGER;
  314.   NextMsg       : INTEGER;
  315.   NoAscendMsg   : ComLine;
  316.   NonReadInfo   : BOOLEAN;
  317.   NumSends      : INTEGER;
  318.   OtherUsersRec : UsersType;
  319.   OutFiling     : BOOLEAN;
  320.   Patience      : INTEGER;
  321.   Pleaseable    : BOOLEAN;
  322.   Postings      : INTEGER;
  323.   Promo         : BOOLEAN;
  324.   QuestFileName : FNType;
  325.   QuestRec      : QuestType;
  326.   Read_A        : BOOLEAN;
  327.   Read_B        : BOOLEAN;
  328.   Read_C        : BOOLEAN;
  329.   Read_D        : BOOLEAN;
  330.   Read_P        : BOOLEAN;
  331.   Read_S        : BOOLEAN;
  332.   Read_X        : BOOLEAN;
  333.   ReadBand      : CHAR;
  334.   ReadDate      : INTEGER;
  335.   ReadMint      : INTEGER;
  336.   SaveDescTexture : STRING[20];
  337.   SaveDescType    : STRING[12];
  338.   SaveDescCharac  : STRING[26];
  339.   SaveTime      : INTEGER;
  340.   Secs          : INTEGER;
  341.   SeismoActive  : BOOLEAN;
  342.   SeismoRec     : SeismoType;
  343.   ServantWord   : ComLine;
  344.   ShutDown      : BOOLEAN;
  345.   SlowedTime    : BOOLEAN;
  346.   SpellCost     : INTEGER;
  347.   SpellRepeat   : INTEGER;
  348.   StartDate     : INTEGER;
  349.   StartMint     : INTEGER;
  350.   StatusPort    : INTEGER;
  351.   StoppedTime   : BOOLEAN;
  352.   SuppressOut   : BOOLEAN;
  353.   SysFail       : BOOLEAN;
  354.   SysLogItem    : SysLogType;
  355.   Tactical      : BOOLEAN;
  356.   TestPass      : TenType;
  357.   TimeOutCntr   : INTEGER;
  358.   TimeOutSecs   : INTEGER;
  359.   TuneMatch     : BOOLEAN;
  360.   TuneString    : Line;
  361.   UpCaseInput   : BOOLEAN;
  362.   UserName      : UNameType;
  363.   UserNames     : ARRAY[1..MaxUsers] OF UNameType;
  364.   UserRecPtr    : INTEGER;
  365.   UsersRec      : UsersType;
  366.   VALRetCode    : INTEGER;
  367.   Width         : INTEGER;
  368.   WizOp         : BOOLEAN;
  369.   Wrapping      : BOOLEAN;
  370.   YesNo         : CHAR;
  371. VAR { Files }
  372.   NextMsgFile   : FILE OF INTEGER;
  373.   MsgTimesFile  : FILE OF MsgTimesType;
  374.   QuestFile     : FILE OF QuestType;
  375.   SeismoFile    : FILE OF SeismoType;
  376.   SysLogFile    : FILE OF SysLogType;
  377.   TxtFile       : TEXT;
  378.   UsersFile     : FILE OF UsersType;
  379.  
  380. {$I PYUTILIT.INC}  { Very basic procedures and functions }
  381. {$I PYSERIAL.INC}  { I/O to the serial port }
  382. {$I PYBASEUT.INC}  { Basic utilities specific to Pyroto }
  383. {$I PYFILES.INC}   { All file-handling, including message reading/writing }
  384. {$I PYSIGN.INC}    { Overlays for sign-on and sign-off processing }
  385. {$I PYCMDPRO.INC}  { Overlays for command processing }
  386. {$I PYCMDPAR.INC}  { Parsing of commands }
  387.  
  388. PROCEDURE Contact;  { CONTACT spell and F6 key }
  389. VAR
  390.   ConLine   : Line;
  391.   SaveIing  : BOOLEAN;
  392.   SaveInput : Line;
  393.   SaveSup   : BOOLEAN;
  394.   SaveUCI   : BOOLEAN;
  395.   SoundCnt  : INTEGER;
  396. BEGIN
  397.   {----- Sound the alert -----}
  398.   IF CType <> 'I' THEN Communicative := TRUE;
  399.   SaveSup := SuppressOut;
  400.   SuppressOut := FALSE;
  401.   FOR SoundCnt := 1 TO 50 DO
  402.   BEGIN
  403.     SOUND(1000);
  404.     DELAY(5);
  405.     NOSOUND;
  406.   END;
  407.   {----- Reject unwanted types -----}
  408.   IF (NOT Chattable) AND (CType <> 'I') THEN
  409.   BEGIN
  410.     XLn('Neither TSOTL  nor his Servant are free');
  411.     XLn('to talk at this time; please try later.');
  412.     ChatAsk := TRUE;
  413.   END;
  414.   {----- Accept communication -----}
  415.   IF Chattable OR (CType = 'I') THEN
  416.   BEGIN
  417.     {--- Appropriate messages ---}
  418.     IF CType <> 'I'
  419.     THEN
  420.     BEGIN
  421.       WRITELN(#17#16+' '+UserName+' wants to chat.');
  422.       XLn('Type.   Perhaps TSOTL will talk to you.');
  423.       XLn('Enter E on an empty line to leave here.'); XLF;
  424.     END
  425.     ELSE
  426.     BEGIN
  427.       CharDuringO := FALSE;
  428.       XLF; XLF;
  429.       XLn('Incoming  communication  --  stand by.');
  430.       XLn('Enter E on an empty line to terminate.');
  431.       XLF;
  432.     END;
  433.     ChatAsk     := FALSE;
  434.     Contacting  := TRUE;
  435.     {--- Save environment ---}
  436.     SaveInput   := InputLine;
  437.     SaveIing    := Inputting;
  438.     SaveUCI     := UpCaseInput;
  439.     {--- CONTACT environment ---}
  440.     Inputting   := TRUE;
  441.     UpCaseInput := FALSE;
  442.     {--- Chat ---}
  443.     REPEAT
  444.       ConLine := GetInputLn;
  445.       IF (ConLine = 'W') OR (ConLine = 'w') THEN
  446.       BEGIN
  447.         Wrapping := NOT Wrapping;
  448.         IF Wrapping
  449.         THEN XLn('Word-wrap on.')
  450.         ELSE XLn('Word-wrap off.');
  451.       END;
  452.     UNTIL (Upper(ConLine) = 'E') OR LostCarrier;
  453.     Contacting  := FALSE;
  454.     {--- Restore environment ---}
  455.     UpCaseInput := SaveUCI;
  456.     Inputting   := SaveIing;
  457.     InputLine   := SaveInput;
  458.     IF CType = 'I' THEN
  459.     BEGIN
  460.       XLF;
  461.       XLn('Continuing what you were doing...');
  462.       XLF;
  463.       IF Inputting THEN X(InputLine+^Q);
  464.     END;
  465.   END;
  466.   SuppressOut := SaveSup;
  467. END;
  468.  
  469. {======= MAINLINE CODE =======}
  470.  
  471. BEGIN
  472.   StartUp;
  473.   REPEAT
  474.     IF NOT SysFail THEN                                        {"""""""""""}
  475.     BEGIN                                                      {  Before   }
  476.       AwaitUser;                                               {  the      }
  477.       SignOn;                                                  {  visit    }
  478.     END;                                                       {,,,,,,,,,,,}
  479.     IF (NOT Logoff) AND (NOT SysFail) THEN                     {"""""""""""}
  480.     BEGIN                                                      {           }
  481.       REPEAT                                                   {           }
  482.         GetCommand;                                            {   The     }
  483.         DoCommand;                                             {   visit   }
  484.         IF (NOT Logoff) AND (NOT SysFail) THEN CheckPatience;  {           }
  485.       UNTIL Logoff OR SysFail;                                 {           }
  486.     END;                                                       {,,,,,,,,,,,}
  487.     Disconnect;                                                {"""""""""""}
  488.   UNTIL ShutDown OR SysFail;                                   { After the }
  489.   CleanUp;                                                     { visit     }
  490. END.                                                           {,,,,,,,,,,,}