/////////////////////////////////////////////////////////////////////////////
// OFFLINER script for Telix, started 27.10.1991, last change: 03.01.1993. //
// Copyright (C) 1991-93, Stein Bjrndal                                   //
// This script is a part of OFFLINER, by ystein Homelien.                 //
// Used for logging in to any MBBS v8.1b, 9.8a or 9.9x system.             //
/////////////////////////////////////////////////////////////////////////////

// ==================================================================
// -- Script start --------------------------------------------------
Int
  File,                      // Multi purpose file handle.
  LogFile,                   // Log file handle.

  // Track handles. Used from various functions throughout the script.

  Stat,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T,


  _Error_Count,              // Used for various error conts.
  _Conf_Error_Count,         // Conference error counter (join).
  _Name_Error_Count,         // Name error counter.
  _63,                       // Boolean. Message not available?
  _64,                       // Boolean. All not allowed in conference (mail).
  _BBSDoor_Count,            // BBS door login counter/various use.
  _Instruct_Count,           // Instruct file counter.

  Instruct_OK,               // Boolean. Did instruct complete ok?
  NoDelete,                  // Boolean. Erase OFFLINER's INSTRUCT file?
  CR,                        // Boolean. Add CR at end of LOG string?
  Dumped,                    // Boolean. Any messages dumped at all?
  Tim;                       // Variable used to find current time.

Str
  Filename[80],              // String to store filename.
  CTRL_C[80],                // Store CTRL-C keydef here.
  Current[50],               // Store current conference.

  // Variables 1 to 29 are used to store CONFIGuration for current BBS.

  _Username[32],             // User Name.
  _Password[32],             // Password.
  _Alias[32],                // Alias.
  _Address[32],              // Street address.
  _City[42],                 // Postal Code and City.
  _Country[32],              // Country.
  _Home_tlf[22],             // Home Telephone Number.
  _Work_tlf[22],             // Work Telephone Number.
  _Birthdate[10],            // Birth Date.
  _BBS_Door_number[6],       // # for Door BBS (0 for none).
  _Newfiles_scan[3],         // Scan for new files? (Y/N).
  _Grab_Cnf_list[3],         // Grab conference list? (Y/N).
  _Info_update[3],           // Update user information? (Y/N).
  _Screen_height[4],         // Screen height.
  _Protocol[4],              // Protocol (Z/X/Y/YB).
  _Logoff[3],                // Log off after session? (Y/N).
  _Register_user[3],         // Register user if needed? (Y/N).
  _Clear_confs[3],           // Clear Conferences? (Y/N)
  _Logoff_Delay[5],          // Logoff Delay. (0 for none.)
  _BBS_System[12],           // BBS system.
  _BBS_ID[12],               // BBS ID.
  _CPU_Brand[27],            // Brand of CPU.

  // Variables 30 to 49 are used to store current INSTRUCTion.

  _Instruct_type[70],        // Instruction type.
  _Instruct_1[70],           // _Instruct_1 to _49 is instruction file lines.
  _Instruct_2[70],
  _Instruct_3[70],
  _Instruct_4[70],
  _Instruct_5[70],
  _Instruct_6[70],
  _Instruct_7[70],
  _Instruct_8[70],
  _Instruct_9[70],
  _Instruct_10[70],
  _Instruct_11[70],          // _42 to _49 is reserved for future use.

  // Variables 50 to 59 are used to store various stuff.

  _Various[10],              // Multipurpose variable.
  _Invalid_Confname[70],     // Stores invalid conference.
  _Invalid_Username[70],     // Stores invalid user name.
  _LOGfile_line[80],         // Line to write to LOG file.

  // Variables 60 to 69 are reserved for counters.

  // Variables 70 to 79 is used for some useful stuff.

  _BBS_Dir[70],              // BBS directory.
  _Restore_lang_Cmd[70],     // Command to restore original language.
  _Logoff_Cmd[70];           // Command to log off in original language.

// == Functions follow here =========================================
// -- Check if file exists ------------------------------------------
FExists(str Dir,str FileToFind)
{
  int Result;      // Return value.
  Str File[64];    // File name.
  File = Dir;      // Search directory Dir for file.
  CopyStr(FileToFind,File,StrLen(File),StrLen(FileToFind));
  If (FileFind(File))
    Result = 1;    // If found, Result = True..
  else
    Result = 0;
  Return Result;   // ..else Result = False.
}

// -- Redefine Ctrl-C if STOPIT.SLC exists --------------------------
SetHotKey()
{
  Str Path[64];    // Pathstring.
  Path = _script_dir;
  If (FExists(Path,"STOPIT.SLC"))      // Check if STOPIT.SLC exists.
  {
    KeyGet(3,0,CTRL_C);                // Redefine Ctrl-C to run
    KeySet(3,0,"@STOPIT");             // STOPIT.SLC when pressed.
  }
}

// -- Simply merge two strings --------------------------------------
Merge(str String1, str String2)
{
  Filename = string1;                  // Needed not to modify any of the strings.
  CopyStr(String2,Filename,StrLen(Filename),StrLen(String2));
  Return Filename;                     // Return the the merged strings.
}

// -- Open LOG file -------------------------------------------------
OpenLog()
{
  Filename = Merge(_BBS_Dir,"LOG");    // Open LOGfile in BBS-dir.
  LogFile = FOpen(Filename,"a+");      // Open file to append.
  Log("<- New Session Startet ",0,0);
  Tim = curtime();
  ItoS(TDay(Tim),_Various);
  Log(_Various,0,0);
  Log(".",0,0);
  ItoS(TMonth(Tim),_Various);
  Log(_Various,0,0);
  Log("-",0,0);
  ItoS(TYear(Tim),_Various);
  Log(_Various,0,0);
  Log(", ",0,0);
  Log("->",1,1);
}

// -- Log the session -----------------------------------------------
Log(str _LOGfile_line,int AD,int CR)
{
  str mid[2];
  Mid = "0";
  If (AD)                    // Add date at start of line?
  {
    Tim = curtime();
    ItoS(THour(Tim),_Various);
    If (StrLen(_Various) == 1)
    {
      CopyChrs(_Various,Mid,1,1);
      FPutS(Mid,LogFile);
    }
    else
      FPutS(_Various,LogFile);
    FPutS(":",LogFile);
    Mid = "0";
    ItoS(TMin(Tim),_Various);
    If (StrLen(_Various) == 1)
    {
      CopyChrs(_Various,Mid,1,1);
      FPutS(Mid,LogFile);
    }
    else
      FPutS(_Various,LogFile);
    FPutS(" ",LogFile);
  }
  FPutS(_LOGfile_line,LogFile);
  If (CR)                    // Add Carriage Return to end of line?
    FPutS("^M^J",LogFile);
}

// -- Release TRACK patterns ----------------------------------------
TrackRelease()
{
  Track_Free(T1);
  Track_Free(T2);
  Track_Free(T3);
  Track_Free(T4);
  Track_Free(T5);
  Track_Free(T6);
  Track_Free(T7);
  Track_Free(T8);
  Track_Free(T9);
  Track_Free(T10);
  Track_Free(T11);
  Track_Free(T12);
  Track_Free(T13);
  Track_Free(T14);
  Track_Free(T15);
}

// -- Stop and wait for Command prompt ------------------------------
AwaitCommand()
{
  Int Timer;
  T1    = Track("Command",0);
  Stat  = 0;
  Timer = Timer_Start(20);
  While(1)
  {
    Terminal();
    Stat = Track_Hit(0);
    If (Stat == T1 || Time_Up(Timer))
      Break;
    else
    If (!Carrier())
    {
      HangUp();
      Unload_scr("MBBS");
    }
  }
  TrackRelease();
}

// -- Set user defaults at login and logout -------------------------
SetDefaults(str which)
{
  CPutS("^H^H^HU L ");
  If (Which == "Login")
  {
    CPutS("0");
    If (_BBS_System != "MBBS v8.1")
      CputS(" MF 50");
    CPutS(" Q CHAT N W^M");
    AwaitCommand();
  }
  else
  {
    CPutS(_Screen_height);
    If (_BBS_System != "MBBS v8.1")
      CPutS(" MF 0");
    CputS(" Q CHAT A^M");
    AwaitCommand();
  }
}

// -- Read configuration file for current BBS -----------------------
Read_Config()
{
  File = FOpen(Merge(_BBS_Dir,"CONFIG."),"r");
  If (FError(File))
  {
    PrintS(">> Error reading CONFIG file. <<");
    PrintSC(">> Path : ");
    PrintSC(_BBS_Dir);
    PrintS(" <<");
    HangUp();
  }
  else
  {
    FGetS(_Username,32,File);
    FGetS(_Password,32,File);
    FGetS(_Alias,32,File);
    FGetS(_Address,32,File);
    FGetS(_City,42,File);
    FGetS(_Country,32,File);
    FGetS(_Home_tlf,22,File);
    FGetS(_Work_tlf,22,File);
    FGetS(_Birthdate,10,File);
    FGetS(_BBS_Door_number,6,File);
    FGetS(_Newfiles_scan,3,File);
    FGetS(_Grab_Cnf_list,3,File);
    FGetS(_Info_update,3,File);
    FGetS(_Screen_height,4,File);
    FGetS(_Protocol,4,File);
    FGetS(_Logoff,3,File);
    FGetS(_Register_user,3,File);
    FGetS(_Clear_confs,3,File);
    FGetS(_Logoff_Delay,5,File);
    FGetS(_BBS_System,12,File);
    FGetS(_BBS_ID,12,File);
    FGetS(_CPU_Brand,27,File);
  }
  FClose(File);
}

// -- ASCII upload (replaces TELIX's internal ASCII upload) ---------
Ascii_up(str FileToUpload)
{
  File = FOpen(FileToUpload,"r");
  While(!FEOF(File))
    CPutC(FGetC(File));
  FClose(File);
}

// -- Login and Register procedures ---------------------------------
Login()
{
  Int Sent=0;
  Str Finished[5];
  T1  = Track("^M^J--more--",0);
  T2  = Track("Kommando",0);
  T3  = Track("vudkommando",0);
  T4  = Track("FIRST name?",0);
  T5  = Track("<Reg/Name/Lgff>:",0);
  T6  = Track("will echo):",0);
  T7  = Track("language key",0);
  T8  = Track("logon password",0);
  T9  = Track("street address",0);
  T10 = Track("postal code and",0);
  T11 = Track("home telephone",0);
  T12 = Track("Satisfied with",0);
  T13 = Track("Command",0);
  T14 = Track("^M^J--mer--",0);
  Finished      = "N";
  _BBSDoor_Count           = 1;
  Stat          = 0;

  CPutS("^X^X^M");           // Force name prompt.
  While(1)
  {
    Terminal();
    Stat = Track_Hit(0);
    if (Stat == T1)          // --more--
      CPutS("^M");
    else
    if (Stat == T2)          // Norwegian language key.
    {
      _Restore_lang_Cmd = "U LANG N G";
      _Logoff_Cmd = "HA J N J";
      CPutS("U SPR;; Q^M");
    }
    else
    if (Stat == T3)          // Swedish language key.
    {
      _Restore_lang_Cmd = "U LANG S Q";
      _Logoff_Cmd = "LO J N J";
      CPutS("K SPR;; Q^M");
    }
    else
    if (Stat == T4)          // "FIRST name?"
    {
      If (!Sent)
      {
        FlushBuf();
        If (_BBS_System == "MBBS v8.1") Delay_scr(10);
        CPutS(_Username);
        If (_BBS_System == "MBBS v9.9") CPutS(" Q");
        CPutS("^M");
        Sent = 1;
      }
    }
    else
    if (Stat == T5)
    {
      If (_Register_user == "Y")
      {
        CPutS("R");
        CPutS("^M");
        Log("Registered user ",1,0);
        Log(_Username,0,0);
        Log(".",0,1);
        _Info_update = "Y";           // Force user update.
      }
    }
    else
    if (Stat == T6)          // "will echo):"
    {
      CPutS(_Password);
      CPutS("^M");
      If (_BBS_System != "MBBS v9.9") CPutS("^X");
    }
    else
    if (Stat == T7)          // "language key"
      CPutS("^M");
    else
    if (Stat == T8)          // "logon password"
    {
      CPutS(_Password);
      CPutS("^M");
    }
    else
    if (Stat == T9)          // "street adress"
    {
      CPutS(_Address);
      CPutS("^M");
    }
    else
    if (Stat == T10)         // "postal code and"
    {
      CPutS(_City);
      CPutS(", ");
      CPutS(_Country);
      CPutS("^M");
    }
    else
    if (Stat == T11)         // "home telephone"
    {
      CPutS(_Home_tlf);
      CPutS("^M");
      CPutS(_Work_tlf);
      CPutS("^M");
    }
    else
    if (Stat == T12)         // "Satisfied with"
      CPutS("Y^M");
    else
    if (Stat == T13)         // "Command"
    {
      If (_BBS_Door_number != "0")        // Check if we need to open BBS door.
      {
        If (_BBSDoor_Count == 2)        // If this is the second try, give up.
          Break;             // And get out.
        else
        {
          Log("Opened BBS door #",1,0);
          Log(_BBS_Door_number,0,0);
          Log(".",0,1);
          CPutS("Q OPEN ");  // Open the BBS door.
          CPutS(_BBS_Door_number);
          CPutS("^M");
          ++ _BBSDoor_Count;
        }
      }
      else
        Break;               // No door, just get out.
    }
    else
    if (Stat == T14)         // "^M^J--mer--"
      CPutS("^M");
    else
    If (!Carrier())          // Check if we're still OnLine
    {
      HangUp();
      Unload_scr("MBBS");
    }
  }
  TrackRelease();
  Log("Logged into ",1,0);
  Log(_Entry_name,0,0);
  Log(".",0,1);
}

// -- User info update procedure ------------------------------------
UserInfoUpdate()
{
  Log("Updated user information.",1,1);
  CPutS("^H^HX S U T ");     // Set protocol.
  CPutS(_Protocol);
  CPutS(" M Y Y Y Y Y ");
  If (_BBS_System == "MBBS v8.1")
    CPutS("FILT^M");
  else
    CPutS("Y AF Z MODE M^M");
  T1   = Track("enabled",0);
  T2   = Track("disabled",0);
  Stat = 0;
  While(1)
  {
    Terminal();
    Stat = Track_Hit(0);
    If (Stat == T1)
     CPutS("^H^HU FILT^M");
    else
    If (Stat == T2)
      Break;
    If (!Carrier())
    {
      HangUp();
      Unload_scr("MBBS");
    }
  }
  CPutS("^H^HU C^M");                  // Check if conference status on,
  T1   = Track("will be show",0);
  T2   = Track("will not be",0);
  Stat = 0;
  While(1)
  {
    Terminal();
    Stat = Track_Hit(0);
    If (Stat == T1)
     CPutS("^H^HU C^M");
    else
    If (Stat == T2)
      Break;
    If (!Carrier())
    {
      HangUp();
      Unload_scr("MBBS");
    }
  }
  CPutS("^H^HU ADDR^M");               // Set adress.
  Waitfor("street address",3);
  CPutS("^X");
  CPutS(_Address);
  CPutS("^M^X");
  CPutS(_City);
  CPutS(", ");
  CPutS(_Country);
  CPutS("^M^X");
  CPutS(_Home_tlf);
  CPutS("^M^X");
  CPutS(_Work_tlf);
  CPutS("^M");
  CPutS("^H^HU ALIAS^M");              // Set alias.
  Waitfor("your new alias:",3);
  CPutS("^X");
  CPutS(_Alias);
  CPutS("^M");
  TrackRelease();
  If (_BBS_System == "MBBS v8.1")
  {
    T1   = Track("^M^JDate to scan",0);
    T2   = Track("^M^JDirectory name",0);
    T3   = Track("File Command",0);
    Stat = 0;
    Delay_scr(10);
    CPutS("F N^M");
    While(1)
    {
      Terminal();
      Stat = Track_Hit(0);
      If (Stat == T1)
       CPutS("^M");
      else
      If (Stat == T2)
       CPutS("*^M^X");
      else
      If (Stat == T3)
        Break;
      If (!Carrier())
      {
        HangUp();
        Unload_scr("MBBS");
      }
    }
  }
  else
  CPutS("^H^HF N;;^M^X");
  TrackRelease();
  AwaitCommand();
}

// -- Password change routine ---------------------------------------
ChangePassword()
{
  Str NewPass[10];
  File = FOpen(Merge(_BBS_Dir,"PASSWORD."),"r");
  If (!FError(File))
  {
    FGetS(NewPass,10,File);
    FClose(File);
    FDelete(Merge(_BBS_Dir,"PASSWORD"));
    File = FOpen(Merge(_BBS_Dir,"PASSWORD.NEW"),"a+");
    FPutS("Old Password: ",File);
    FPutS(_Password,File);
    FPutS("^M^J",File);
    FPutS("New Password: ",File);
    FPutS(NewPass,File);
    FPutS("^M^J",File);
    FClose(File);
    T1    = Track("^M^JSure you want to change your password",0);
    T2    = Track("^M^JPlease enter your password (dots ",0);
    T3    = Track("^M^JPlease enter new password (dots ",0);
    T4    = Track("^M^JPlease enter it again as an extra",0);
    T5    = Track("^M^JLogon password changed.",0);
    T6    = Track("Command",0);
    Stat  = 0;
    CPutS("^H^HU P^M");
    while (1)
    {
      Terminal();
      Stat = Track_Hit(0);
      If (Stat == T1)
        CPutS("Y^M");
      else
      If (Stat == T2)
      {
        CPutS(_Password);
        CPutS("^M");
      }
      else
      If (Stat == T3)
      {
        CPutS(NewPass);
        CPutS("^M");
      }
      else
      If (Stat == T4)
      {
        CPutS(NewPass);
        CPutS("^M");
      }
      else
      If (Stat == T5 || Stat == T6)
        Break;
      else
      If (!Carrier())
      {
        HangUp();
        Unload_scr("MBBS");
      }
    }
    Log("Password changed from ",1,0);
    Log(_Password,0,0);
    Log(" to ",0,0);
    Log(NewPass,0,0);
    Log(".",0,1);
    Log("  Update your OFFLINER configuration!",1,1);
  }
  TrackRelease();
}

// -- Clear all conferences -----------------------------------------
ClearConferences()
{
  int Stop,Again,Next;
  Log("Clearing conferences.",1,1);
  T1    = Track("^M^JNo unread messages",0);
  T2    = Track("^M^JNo more unread",0);
  T3    = Track("^M^JNo new messages",0);
  T4    = Track(" conference status:",0);
  T5    = Track(" added to scratchpad",0);
  T6    = Track("Command",0);
  Stat  = 0;
  Again = 0;
  Stop  = 0;
  Next  = 0;
  CPutS("^H^HR M O DU C^M");
  while (1)
  {
    Terminal();
    Stat = Track_Hit(0);
    if (Stat == T1)
      Stop = 1;
    else
    if (Stat == T2 || Stat == T3)
      Next = 1;
    else
    if (Stat == T4)
      Again = 1;
    else
    if (Stat == T5)
      Dumped = 1;
    else
    if (Stat == T6)
    {
      If (Stop)
        Break;
      else
      If (Again)
      {
        CPutS("^H^HR M O DU C^M");
        Again = 0;
      }
      else
      If (Next)
      {
        CPutS("^M");
        Next = 0;
      }
    }
    else
    If (!Carrier())
    {
      HangUp();
      Unload_scr("MBBS");
    }
  }
  TrackRelease();
}

// -- Grab messages -------------------------------------------------
Grab()
{
  Int OK = 1;
  _Various   = "Y";
  _Error_Count   = 0;
  Stat  = 0;
  T1    = Track("^M^J<0> mess",0);
  T2    = Track("Command",0);
  T3    = Track("^M^JScratchpad emp",0);
  T4    = Track("^M^JSending",0);
  T5    = Track(" send ready.",0);
  T6    = Track("Download aborted",0);
  T7    = Track("Invalid command",0);
  T8    = Track("Download completed",0);
  T9    = Track("Not enough space on disk!",0);
  T10   = Track("Protocol Choice",0);
  T11   = Track(" the scratchpad ARCed first",0);
  CPutS("^H^H^HR D A^M");          // Dump all conferences to scratchpad.
  While(1)
  {
    Terminal();
    Stat = Track_Hit(0);
    If (Stat == T1)
      _Various = "N";
    else
    If (Stat == T2)
      Break;
  }

  If (_Various == "Y" || Dumped)          // SEnd
  {
    Log("Grabbing messages.",1,1);
    TryAgain:
    ++ _Error_Count;
    CPutS("^H^H^HSE^M");
    Stat = 0;
    While(1)
    {
      Terminal();
      Stat = Track_Hit(0);
      If (Stat == T2)
      {
        If (OK || _Error_Count == 3)
          Break;
        else
          Goto TryAgain;
      }
      else
      If (Stat == T3 || Stat == T8)
        OK = 1;
      else
      If (Stat == T4 || Stat == T5)
      {
        If (_Protocol != "Z" || _Protocol != "YB")
        {
          CopyStr(_BBS_Dir,Filename,0,StrLen(_BBS_Dir)-1);
          CopyStr(".ZIP",Filename,StrLen(Filename),4);
          FNStrip(Filename,3,Filename);
          If (_Protocol == "X")  Receive('X',Filename);
          If (_Protocol == "Y")  Receive('1',Filename);
        }
        else
          If (_Protocol == "YB") Receive('Y',"");
      }
      else
      If (Stat == T6 || Stat == T7)
        OK = 0;
      else
      If (Stat == T9)
      {
        Log("  Not enough space on disk!",1,1);
        OK = 0;
        Break;
      }
      else
      If (Stat == T10)
      {
        Log("  Configuration incomplete!",1,1);
        CPutS(_Protocol);
        CputS("^M");
      }
      else
      If (Stat == T11)
        CPutS("Y^M");
      else
      If (!Carrier())
      {
        HangUp();
        Unload_scr("MBBS");
      }
    }
    If (!OK)
      Log("  Unable to download scratchpad!",1,1);
  }
  TrackRelease();
}

// -- List conferences and logit ------------------------------------
GetConfList()
{
  FDelete(Merge(_BBS_Dir,"CONFLIST.GRB"));
  Log("Grabbing conference list.",1,1);
  T1   = Track("^M^JConference:",0);
  T2   = Track("Command",0);
  CPutS("^H^HR SHOW A^M");
  Waitfor("SHOW",2);
  Capture(Merge(_BBS_Dir,"CONFLIST.GRB"));
  Stat = 0;
  While(1)
  {
    Terminal();
    Stat = Track_Hit(0);
    If (Stat == T2) Break;
  }
  If (_BBS_System != "MBBS v9.9")
  {
    CPutS("Q MJ^M^X");
    Stat = 0;
    While(1)
    {
      Terminal();
      Stat = Track_Hit(0);
      If (Stat == T1) CPuts("N^M^X");
      If (Stat == T2) Break;
    }
  }
  Capture("*CLOSE*");
  AwaitCommand();
}

// -- Scan for new files routine ------------------------------------
NewFiles(str Path)
{
  T1  = Track("^M^JDate to scan for",0);
  T2  = Track("^M^JDirectory name",0);
  T3  = Track(") File Command",0);
  T4  = Track("^M^JYour time in the file",0);
  Log("Scanning for new files.",1,1);
  File = FOpen(Merge(_BBS_Dir,"NEWFILES.GRB"),"a+");
  FPutS("^M^J",File);
  FPutS("ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ^M^J",File);
  FPutS(">>                           N E W   F I L E S                            <<^M^J",File);
  FPutS("ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ^M^J",File);
  FClose(File);
  Stat = 0;
  CPutS("F N;;^M");
  Waitfor("F N;;^M^J",3);
  Capture(Merge(_BBS_Dir,"NEWFILES.GRB"));
  while (1)
  {
    Terminal();
    Stat = Track_Hit(0);
    if (Stat == T1)
      CPutS("^M");
    else
    if (Stat == T2)
      CPutS("*^M");
    else
    if (Stat == T3)
    {
      Capture("*CLOSE*");
      Break;
    }
    else
    if (Stat == T4)
    {
      Capture("*CLOSE*");
      Log("  Not enough file time to complete listing!",1,1);
      Break;
    }
    If (!Carrier())                    // Check if we're still OnLine.
    {
      HangUp();
      Unload_scr("MBBS");
    }
  }
  TrackRelease();
  AwaitCommand();
}

// == This is the sub-functions for instruction processing ==========
// -- Join conference sub-function ----------------------------------
Joinconf(Int Log_Join)
{
  Int Again   = 0;
  If (Log_Join)
  {
    Log("Joining conference ",1,0);
    Log(_Instruct_1,0,0);
    Log(".",0,1);
  }
  T1          = Track("^M^JTopic?",0);
  T2          = Track("^M^JEnter conference name",0);
  T3          = Track("Command",0);
  Stat        = 0;
  _Name_Error_Count         = 1;
  CPutS("J ");
  CPutS(_Instruct_1);
  CPutS("^M");
  While(_Name_Error_Count < 4)
  {
    Terminal();
    Stat = Track_Hit(0);
    If (Stat == T1 || Stat == T2)
    {
      CPutS("^M");
      If (_Name_Error_Count == 3)
      {
        Log("  Unable to join conference!",1,1);
        Again       = 0;
        Instruct_OK = 0;
      }
      else
        Again = 1;
    }
    else
    If (Stat == T3)
    {
      If (Again)
      {
        CPutS("J ");
        CPutS(_Instruct_1);
        CPutS("^M");
        Again   = 0;
        Current = _Instruct_1;
        ++ _Name_Error_Count;
      }
      else
        Goto Joined;
    }
    else
    If (!Carrier())
    {
      HangUp();
      Unload_scr("MBBS");
    }
  }
  Joined:
  TrackRelease();
}

// -- Resign from conference sub-function ---------------------------
ResConf()
{
  Int Again;
  Log("Resigning from conference ",1,0);
  Log(_Instruct_1,0,0);
  Log(".",0,1);
  JoinConf(0);
  If (Instruct_OK)
  {
    T1    = Track("^M^JResigning from",0);
    T2    = Track("^M^JYou cannot resign",0);
    T3    = Track("Command",0);
    _Conf_Error_Count   = 1;
    Stat  = 0;
    Again = 0;
    CPutS("RES Y^M");
    While (_Conf_Error_Count < 4)
    {
      Terminal();
      Stat = Track_Hit(0);
      If (Stat == T1)
        Again = 0;
      else
      If (Stat == T2)
      {
        Log("  This is an obligatory conference!",1,1);
        Instruct_OK = 0;
        Again = 0;
      }
      else
      If (Stat == T3)
      {
        If (Again)
        {
          CPutS("RES Y^M");
          ++ _Conf_Error_Count;
          Again = 1;
        }
        else
          Break;
      }
      else
      If (!Carrier())
      {
        HangUp();
        Unload_scr("MBBS");
      }
    }
  }
  TrackRelease();
}

// -- Message entry sub-routine -------------------------------------
Message()
{
  Int Subj_Sent,Entered,Again;
  Stat = 0;
  _Conf_Error_Count  = 1;                            // Conf test counter.
  _Name_Error_Count  = 1;                            // Name test counter.
  _63  = 0;
  _64  = 0;

  Log("Entering message to ",1,0);
  Log(_Instruct_2,0,0);
  Log(" in ",0,0);
  Log(_Instruct_1,0,0);
  Log(".",0,1);
  If (_Instruct_3 != "0")
  {
    Log("  Reply to message #",1,0);
    Log(_Instruct_3,0,1);
  }
  If (!FExists("",_Instruct_6))
  {
    Log("  TEXT file not found. Entry aborted!",1,1);
    Instruct_OK = 0;
    Goto EndMessage;
  }

  T1  = Track("^M^JSorry, ALL is not",0);
  T2  = Track(" saved!",0);
  T3  = Track("^M^JInclude original",0);
  T4  = Track("^M^JSend carbon copies",0);
  T5  = Track("^M^J          Subject of",0);
  T6  = Track("^M^JPrivate message (Ent",0);
  T7  = Track("----+----7->",0);
  T8  = Track("^M^JTopic?",0);
  T9  = Track("^M^JInvalid conference",0);
  T10 = Track("^M^JPlease enter both",0);
  T11 = Track("^M^JSorry, that name is not",0);
  T12 = Track("^M^JMessage is not",0);
  T13 = Track(" Command",0);
  T14 = Track("^M^JSorry! That user is not",0);
  T15 = Track("^M^JThis is a READ ONLY",0);

  Again   = 1;
  Entered = 0;
  while (1)
  {
    If (Again)
    {
      Again     = 0;
      Subj_Sent = 0;
      If (Current != _Instruct_1)
      {
        CPutS("^H^HJ ");
        CPutS(_Instruct_1);
        CPutS(" ");
        Current = _Instruct_1;
      }
      If (_Instruct_3 == "0")
      {
        CPutS("R E ");
        CPutS(_Instruct_2);
        CPutS("^M");
      }
      else
      {
        CPutS("R RE ");
        CPutS(_Instruct_3);
        CPutS("^M");
      }
    }
    Terminal();
    Stat = Track_Hit(0);
    if (Stat == T1)              // "Sorry, ALL is not.."..
    {
      CPutS("^X^M");
      _Invalid_Username = _Instruct_2;
      _Instruct_2 = "SYSOP";
      _64 = 1;
      Again = 1;
    }
    else
    If (Stat == T2)          // " saved!"..
    {
      Log("  Message sent successfully.",1,1);
      Entered = 1;
    }
    else
    if (Stat == T8 || Stat == T9)
    { 
      CPutS("^X^M");
      Current = "";
      If (_Conf_Error_Count == 3)          // "Topic?.."..
      {                      // "Invalid conferenc.."..
        _Invalid_Confname = _Instruct_1;
        _Instruct_1 = "Post";
        _Instruct_3 = "0";
      }
      If (_Conf_Error_Count == 6)
        _Instruct_1 = "Mail";
      If (_Conf_Error_Count == 9)
        _Instruct_1 = "EMail";
      If (_Conf_Error_Count == 12)
      {
        Log("  Message save failed!",1,1);
        Instruct_OK = 0;
        Entered = 1;
      }
      ++ _Conf_Error_Count;
      Again = 1;
    }
    else
    if (Stat == T3 || Stat == T4)
      CPutS("N^M");          // "Include original.."..
    else                     // "Send carbon copi.."..
    if (Stat == T5)          // "Subject of messa.."..
    { 
      If (!Subj_Sent)
      {
        CPutS("^X");
        CPutS(_Instruct_4);
        CPutS("^M");
        Subj_Sent = 1;
      }
    }
    else
    if (Stat == T6)          // "Private message.."..
    {
      CPutS(_Instruct_5);
      CPutS("^M");
    }
    else
    if (Stat == T7)          // "----+----7->"..
    {
      CPutS("^KZ");
      If (_Conf_Error_Count > 2)
      {
        CPutS(" ž OFFLINER: Unable to join conference '");
        CPutS(_Invalid_Confname);
        CPutS("'^M^M");
        Log("  Unable to join conference ",1,0);
        Log(_Invalid_Confname,0,1);
        Log("  Message entered in ",1,0);
        Log(_Instruct_1,0,0);
        Log(".",0,1);
      }
      If (_Name_Error_Count > 2)
      {
        CPutS(" ž OFFLINER: Unable to send message to '");
        CPutS(_Invalid_Username);
        CPutS("'^M^M");
        Log("  Unable to send message to ",1,0);
        Log(_Invalid_Username,0,1);
        Log("  Message redirected to ",1,0);
        Log(_Instruct_2,0,0);
        Log(".",0,1);
      }
      If (_63)
      {
        CPutS(" ž OFFLINER: Message moved from conference '");
        CPutS(_Invalid_Confname);
        CPutS("'^M^M");
        Log("  READ ONLY/user not member of ",1,0);
        Log(_Invalid_Confname,0,1);
        Log("  Message moved to ",1,0);
        Log(_Instruct_1,0,0);
        Log(".",0,1);
      }
      If (_64)
      {
        CPutS(" ž OFFLINER: Message originally to ALL.");
        CPutS("^M^M");
        Log("  ALL not allowed in ",1,0);
        Log(_Invalid_Confname,0,1);
        Log("  Message redirected to ",1,0);
        Log(_Instruct_1,0,0);
        Log(".",0,1);
      }
      Ascii_Up(_Instruct_6);        // Send message.
      CPutS("^Z");
    }
    else
    if (Stat == T10 || Stat == T11)
    {                            // "Please enter both.."..
      CPutS("^X^M^M");           // "Sorry, that name .."..
      If (_Name_Error_Count == 3)
      {
        _Invalid_Username = _Instruct_2;
        _Instruct_2 = "SYSOP";
      }
      If (_Name_Error_Count == 6)
      {
        Log("  Message save failed!",1,1);
        Instruct_OK = 0;
        Entered = 1;
      }
      ++ _Name_Error_Count;
      Again = 1;
    }
    else
    if (Stat == T12)         // "Message is not.."..
    {
      _Instruct_3   = "0";
      Again = 1;
      Log("  Original message not available.",1,1);
    }
    else
    if (Stat == T13)         // "Command.."..
    {
      If (Entered)
        Break;
    }
    else
    if (Stat == T14 || Stat == T15)
    {                                   // "This is a READ ONLY.."..
      _Invalid_Confname   = _Instruct_1;// "Sorry! That user is.."..
      _Instruct_1   = "Post";
      _Instruct_3   = "0";
      _63   = 1;
      Again = 1;
    }
    else
    If (!Carrier())                    // Check if we're still OnLine.
    {
      HangUp();
      Unload_scr("MBBS");
    }
  }
  EndMessage:
  TrackRelease();
}

// -- Download file sub-function ------------------------------------
Download()
{
  str Line[80],Test[15];
  int Midfile;
  Log("Downloading file ",1,0);
  Log(_Instruct_1,0,0);
  Log(".",0,1);
  Stat        = 0;
  T1          = Track("^M^JFile not found!",0);
  T2          = Track("Download aborted!",0);
  T3          = Track("Download completed!",0);
  T4          = Track("You are not allowed",0);
  T5          = Track("Command",0);
  T6          = Track("^M^JStarting",0);
  T7          = Track("send ready.",0);
  T8          = Track("time left for that!");
  Capture(Merge(_BBS_Dir,"$GETIT$.$$$"));
  CPutS("^H^HF D ");
  CPutS(_Instruct_1);
  CPutS("^M");
  while (1)
  {
    Terminal();
    Stat = Track_Hit(0);
    if (Stat == T1)
    {
      Log("  File not found!",1,1);
      Instruct_OK = 0;
    }
    else
    if (Stat == T2)
    {
      Log("  Download abortet!",1,1);
      Instruct_OK = 0;
    }
    else
    if (Stat == T3)
    {
      Capture("*CLOSE*");
      MidFile = FOpen(Merge(_BBS_Dir,"$GETIT$.$$$"),"r");
      Line = "";
      While(!FEOF(MidFile))
      {
        Line = "";
        Test = _Instruct_1;
        FGetS(Line,80,MidFile);
        SubChrs(Line,2,StrLen(_Instruct_1),Test);
        If (Test == _Instruct_1)
          Break;
      }
      FClose(MidFile);
      FDelete(Merge(_BBS_Dir,"$GETIT$.$$$"));
      Log("  Download completed.",1,1);
      File = FOpen(Merge(_BBS_Dir,"DOWNLOAD.LST"),"a+");
      FPutS(Line,File);
      FPutS("^M^J",File);
      FClose(File);
    }
    else
    if (Stat == T4)
    {
      Log("  Access error. No DL access?",1,1);
      Instruct_OK = 0;
    }
    if (Stat == T5)
      Break;
    else
    If (Stat == T6 || Stat == T7)
    {
      Delay_Scr(20);
      If (_Protocol == "X")  Receive('X',_Instruct_1);
      If (_Protocol == "Y")  Receive('1',_Instruct_1);
      If (_Protocol == "YB") Receive('Y',"");
    }
    else
    if (Stat == T8)
    {
      Log("  Not enough time left for file transfer!",1,1);
      Instruct_OK = 0;
    }
    else
    If (!Carrier())                    // Check if we're still OnLine.
    {
      HangUp();
      Unload_scr("MBBS");
    }
  }
  Capture("*CLOSE*");
  TrackRelease();
}

// -- Upload file sub-function --------------------------------------
Upload()
{
  Str Mid[70];
  Int Done;
  Log("Uploading file ",1,0);
  Log(_Instruct_1,0,0);
  Log(".",0,1);
  Goto Start;

  // ---------------------------------------
  Retract:
  TrackRelease();
  Stat = 0;
  T1   = Track("^M^JYou are not allowed",0);
  T2   = Track("^M^JSure you want",0);
  CPutS("^X^M");
  CPutS("F RET ");
  CPutS(_Instruct_1);
  CPutS("^M");
  While(1)
  {
    Terminal();
    Stat = Track_Hit(0);
    If (Stat == T1)
    {
      Log("  RETract failed. Aborting!",1,1);
      Instruct_OK = 0;
      Goto No_Upload;
    }
    else
    If (Stat == T2)
    {
      CputS("Y^M");
      TrackRelease();
      Goto All_Over;
    }
    else
    If (!Carrier())
      Goto No_Upload;
  }
  // ---------------------------------------

  Start:
  If (!FExists("",_Instruct_2))
  {
    Log("  File doesn't exist on disk. Upload skipped!",1,1);
    Instruct_OK = 0;
    Goto No_UpLoad;
  }

  If (_Instruct_7 == "C")
  {
    Mid = _Instruct_1;
    _Instruct_1 = _Instruct_8;
    JoinConf(0);
    _Instruct_1 = Mid;
  }

  All_Over:
  Instruct_OK = 1;
  T1          = Track("^M^JPlease enter both",0);
  T2          = Track("^M^JSorry, that name",0);
  T3          = Track("^M^JFile name",0);
  T4          = Track("^M^JYou are not allowed",0);
  T5          = Track("Command",0);
  _Name_Error_Count         = 0;
  _Conf_Error_Count         = 0;

  Try_Again:
  CPutS("^H^HF ");
  If (_Instruct_7 == "P")
  {
    CPutS("PU ");
    CPutS(_Instruct_8);
  }
  else
    CPutS("UP ");
  CPutS("^M");

  Done  = 1;
  Stat  = 0;
  while (1)
  {
    Terminal();
    Stat = Track_Hit(0);
    if (Stat == T1 || Stat == T2)
    {
      CPutS("^X^M");
      If (_Name_Error_Count == 3)
      {
        Log("  Unable to upload to user ",1,0);
        Log(_Instruct_8,0,0);
        Log(", file SKIPPED.",0,1);
        Instruct_OK = 0;
        Goto No_UpLoad;
      }
      ++ _Name_Error_Count;
      Done = 0;
    }
    else
    if (Stat == T3)          // "File name"..
    {
      If (!Done)
        CPutS("^X^M");
      else
      {
        Done = 1;
        Break;
      }
    }
    else
    if (Stat == T4)          // "You are not allowed"..
    {
      Log("  Access error. No UL access?",1,1);
      Instruct_OK = 0;
      Goto No_UpLoad;
    }
    else
    if (Stat == T5)          // "Command"..
    {
      If (!Done)
        Goto Try_Again;
    }
    else
    If (!Carrier())          // Check if we're still OnLine.
      Goto No_UpLoad;
  }

  TrackRelease();

  T1      = Track("^M^JFile exists",0);
  T2      = Track("^M^JInvalid file",0);
  T3      = Track("^M^JPlease enter desc",0);
  T4      = Track("^M^JMake file private",0);
  T5      = Track("^M^JIs file to be pub",0);
  T6      = Track("^M^JWant notification",0);
  T7      = Track("^M^JDirectory name",0);
  T8      = Track("^M^JStarting",0);
  T9      = Track("^M^JEnter detail",0);
  T10     = Track("^M^JUpload abort",0);
  T12     = Track("Command",0);
  T13     = Track("receive ready.",0);
  T14     = Track("+----7->",0);
  T15     = Track("^M^JFile name",0);
  _Conf_Error_Count     = 0;
  _Name_Error_Count     = 0;
  Stat    = 0;
  Goto Name;

  while (1)
  {
    Terminal();
    Stat = Track_Hit(0);
    if (Stat == T1)          // "File exists"..
    {
      Log("  File exists!",1,1);
      If (_Instruct_1 == "Y")
      {
        Log("  RETracting file.",1,1);
        Goto Retract;
      }
      else
      {
        CPutS("^X^M");
        Goto No_Upload;
      }
    }
    else
    if (Stat == T2)          // "Invalid file name"..
    { 
      If (_Conf_Error_Count == 3)
        Log("  Invalid file name!",1,1);
    }
    else
    if (Stat == T3)          // "Please enter desc"..
    { 
      CPutS(_Instruct_3);
      CPutS("^M");
    }
    else
    if (Stat == T4)          // "Make file private"..
    {
      If (_Instruct_7 == "C")
      {
        CPutS("Y^M");
        Log("  File made private to conference ",1,0);
        Log(_Instruct_8,0,0);
        Log(".",0,1);
      }
      else
        CPuts("N^M");
    }
    else
    if (Stat == T5)          // "Is file to be public"..
      CPutS("Y^M");
    else
    if (Stat == T6)          // "Want notification"..
    { 
      CPutS(_Instruct_6);
      CPutS("^M");
    }
    else
    if (Stat == T7)          // "Directory name"..
      CPutS("^M");
    else
    if (Stat == T8 || Stat == T13)
    {                        // "Starting" or "receive ready"..
      Delay_Scr(20);
      If (_Protocol == "X")  Send('X',_Instruct_2);
      If (_Protocol == "Y")  Send('1',_Instruct_2);
      If (_Protocol == "YB") Send('Y',_Instruct_2);
      If (_Protocol == "Z")  Send('Z',_Instruct_2);
    }
    else                     // "Enter detailed desc"..
    if (Stat == T9)
    {
      Instruct_OK = 1;
      If (_Instruct_type != "")
      {
        If (FExists("",_Instruct_type)) // Does TEXT.* file exist?
          CPutS("Y^M");
        else
        {
          Log("  TEXT file with detailed description does not exist on disk!",1,1);
          CPutS("N^M");
        }
      }
      else
        CPutS("N^M");
    }
    else
    if (Stat == T10)         // "Upload aborted!"..
    {
      Log("  Upload aborted!",1,1);
      Instruct_OK = 0;
    }
    else
    if (Stat == T12)         // "Command"..
      Break;
    else
    If (Stat == T14)         // "+----7->"..
    {
      CPutS("^KZ");
      Ascii_up(_Instruct_type);
      CPutS("^Z");
      Log("  Detailed description entered.",1,1);
    }
    else
    If (Stat == T15)         // "File name"..
    {
      Name:
      If (_Conf_Error_Count < 3)
      {
        CPutS("^H^H^H^H^H^H^H^H^H^H^H^H");
        CPutS(_Instruct_1);
        CPutS("^M");
        ++ _Conf_Error_Count;
      }
    }
    else
    If (!Carrier())                    // Check if we're still OnLine.
    {
      HangUp();
      Unload_scr("MBBS");
    }
  }
  No_UpLoad:
  TrackRelease();
}

// -- Download bulletin sub-function --------------------------------
Bulldown()
{ 
  Int DLing,MidFile;
  Str Test[75],Line[80];
  If (_Instruct_2 != "0")
  {
    Log("Downloading bulletin #",1,0);
    Log(_Instruct_2,0,0);
  }
  else
    Log("Logging list of bulletins",1,0);
  If (_Instruct_1 != "")
  {
    Log(", conf ",0,0);
    Log(_Instruct_1,0,0);
  }
  Log(".",0,1);
  If (_Instruct_1 != "")
    JoinConf(0);
  If (Instruct_OK)
  {
    T1          = Track("^M^JInvalid com",0);
    T2          = Track("^M^JThere is no ",0);
    T3          = Track("^M^JBulletin num",0);
    T4          = Track("Command",0);
    T5          = Track("^M^J--more--",0);
    T6          = Track("Download completed",0);
    T7          = Track("^M^JStarting",0);
    T8          = Track(" send ready.",0);
    DLing       = 0;
    Stat        = 0;
    If (_Instruct_2 == "0")
    {
      Capture(Merge(_down_dir,"BULLETIN.LST"));
      CPutS("^H^HR B^M");
      While(1)
      {
        Terminal();
        Stat = Track_Hit(0);
        If (Stat == T3)
          CPutS("^M");
        else
        If (Stat == T4)
          Break;
        else
        If (Stat == T5)
          CPutS("^M");
        else
        If (!Carrier())
        {
          HangUp();
          Unload_scr("MBBS");
        }
      }
      Capture("*CLOSE*");
      Instruct_OK = 1;
    }
    else
    {
      CPutS("^H^HR B ");
      CPutS(_Instruct_2);
      CPutS("^M^X");
      While(1)
      {
        Terminal();
        Stat = Track_Hit(0);
        If (Stat == T1)
        {
          Log("  Unknown error in Bulletin Download. Noise?",1,1);
          Instruct_OK = 0;
          DLing = 1;
        }
        else
        If (Stat == T2)
        {
          Log("  There is no bulletin with that number!",1,1);
          Instruct_OK = 0;
          DLing = 1;
        }
        else
        If (Stat == T3)
        {
          If (!DLing)
          {
            Capture(Merge(_BBS_Dir,"$GETIT$.$$$"));
            CPutS("^H^HD^M");
          }
          else
            CPutS("^M");
        }
        else
        If (Stat == T4)
        {
          Capture("*CLOSE*");
          Break;
        }
        else
        If (Stat == T7 || Stat == T8)
        {
          DLing = 1;
          Capture("*CLOSE*");
          If (_Protocol != "Z" || _Protocol != "YB")
          {
            MidFile = FOpen(Merge(_BBS_Dir,"$GETIT$.$$$"),"r");
            Line = "";
            While(!FEOF(MidFile))
            {
              FGetS(Line,80,MidFile);
              SubChrs(Line,0,9,Test);
              If (Test == "Filename:")
              {
                Test = "";
                SubChrs(Line,10,StrLen(Line)-10,Test);
                Break;
              }
              Test = "";
            }
            FClose(MidFile);
            FDelete(Merge(_BBS_Dir,"$GETIT$.$$$"));
            If (_Protocol == "X")  Receive('X',Test);
            If (_Protocol == "Y")  Receive('1',Test);
          }
          else
            If (_Protocol == "YB") Receive('Y',"");
        }
        else
        If (!Carrier())
        {
          HangUp();
          Unload_scr("MBBS");
        }
      }
    }
  }
  TrackRelease();
}

// -- List file directory sub-function ------------------------------
Listdir()
{
  int
  Again = 0,
  DL_File;

  Log("Listing file directory ",1,0);
  Log(_Instruct_1,0,0);
  Log(".",0,1);

  T1   = Track("^M^JDirectory",0);
  T2   = Track(Merge(_Instruct_1,"^M^J"),0);
  T3   = Track("File Command",0);
  Stat = 0;
  _Error_Count  = 1;
  DL_File  = FOpen(Merge(_BBS_Dir,"NEWFILES.GRB"),"a+");

  FPutS("^M^J",DL_File);
  FPutS("ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ^M^J",DL_File);
  FPutS(">> D I R E C T O R Y : ",DL_File);
  FPutS(_Instruct_1,DL_File);
  FPutS("^M^J",DL_File);
  FPutS("ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ^M^J",DL_File);
  FClose(DL_File);

  Capture(Merge(_BBS_Dir,"NEWFILES.GRB"));
  Capture("*PAUSE*");
  CPutS("F L ");
  CPutS(_Instruct_1);
  CPutS("^M");
  while (_Error_Count < 4)
  {
    Terminal();
    Stat = Track_Hit(0);
    if (Stat == T1)
    {
      Capture("*PAUSE*");
      CPutS("^M");
      If (_Error_Count == 3)
      {
        Log("  Unable to list directory!",1,1);
        Instruct_OK = 0;
        Capture("*CLOSE*");
        Again = 0;
      }
      else
        Again = 1;
    }
    else
    if (Stat == T2)
      Capture("*UNPAUSE*");
    else
    If (Stat == T3)
    {
      Capture("*PAUSE*");
      If (Again)
      {
        CPutS("F L ");
        CPutS(_Instruct_1);
        CPutS("^M");
        ++ _Error_Count;
      }
      else
        Break;
    }
    else
    If (!Carrier())                    // Check if we're still OnLine.
    {
      HangUp();
      Unload_scr("MBBS");
    }
  }
  Capture("*CLOSE*");
  TrackRelease();
}

// -- Enter or change user resume sub-function ----------------------
Resume()
{
  Int Again = 0;
  Log("Updating user resum.",1,1);

  If (!FExists("",_Instruct_1))
  {
    Log("  Text file with resume does not exist!.",1,1);
    Instruct_OK = 0;
    Goto NoResume;
  }

  T1   = Track("^M^JWant your address",0);
  T2   = Track("^M^JSorry, no resum user info",0);
  T3   = Track("+----7->",0);
  T4   = Track("Command",0);
  _Error_Count  = 1;
  Stat = 0;
  CPutS("Q EDIT^M");
  While(_Error_Count < 4)
  {
    Terminal();
    Stat = Track_Hit(0);
    If (Stat == T1)          // "Want your adress.."..
    {
      CPutS(_Instruct_2);
      CPutS("^M");
    }
    else
    If (Stat == T2)          // "Sorry, no resum on user info.."..
    {
      Log("  No user resum on this BBS!",1,1);
      Instruct_OK = 0;
      Break;
    }
    else
    If (Stat == T3)          // "-+----7->"..
    {
      If (_BBS_System == "MBBS v9.9")
      {
        CPutS("^KC");
      }
      else
      {
        CPutS("^Y^Y^Y^Y^Y^Y^Y^Y^Y^M^A^Y");
        While(!Waitfor("1 ",3))
        {
          CPutS("^Y^Y^Y^Y^Y^Y^Y^Y^Y^M^A^Y");
        }
      }
      CPutS("^KZ");                // Supress echo.
      Ascii_up(_Instruct_1);               // Send message (resume).
      CPutS("^Z");                 // Then get out of editor.
      Again = 0;
    }
    else
    If (Stat == T4)          // "Command"..
    {
      If (Again)
      {
        CPutS("Q EDIT^M");
        ++ _Error_Count;
        If (_Error_Count == 4)
        {
          Log("  Unable to update user resum.",1,1);
          Instruct_OK = 0;
          Break;
        }
      }
      else
      {
        If (Instruct_OK || _Error_Count > 3)
          Break;
      }
    }
  }
  NoResume:
  TrackRelease();
}

// -- Request messages from a conference sub-function ---------------
Request()
{
  Current = "";
  Str Line[80] = "", From[7] = "", To[7] = "", Test[6];
  Int Start,End,MidFile;
  Log("Requesting messages ",1,0);
  Log(_Instruct_2,0,0);
  Log(" to ",0,0);
  Log(_Instruct_3,0,0);
  Log(" in conference ",0,0);
  Log(_Instruct_1,0,0);
  Log(".",0,1);
  JoinConf(0);
  If (Instruct_OK)
  {
    Stat        = 0;
    T1          = Track(">:",0);
    Capture(Merge(_BBS_Dir,"$GETIT$.$$$"));
    CPutS("^H^HR M G^M");
    While(1)
    {
      Terminal();
      Stat = Track_Hit(0);
      If (Stat == T1)
      {
        Capture("*CLOSE*");
        Break;
      }
    }
    TrackRelease();
    MidFile = FOpen(Merge(_BBS_Dir,"$GETIT$.$$$"),"r");
    Line = "";
    While(!FEOF(MidFile))
    {
      Test = "";
      FGetS(Line,80,MidFile);
      SubChrs(Line,0,4,Test);
      If (Test == "From")
        Break;
    }
    FClose(MidFile);
    FDelete(Merge(_BBS_Dir,"$GETIT$.$$$"));
    If (Line != "" && Instruct_OK)
    {
      Start = StrChr(Line,0,'<') + 1;
      End   = StrChr(Line,0,'-');
      SubChrs(Line,Start,End-Start,From);
      Start = StrChr(Line,0,'-') + 1;
      End   = StrChr(Line,0,'>');
      SubChrs(Line,Start,End-Start,To);
      If (StoI(_Instruct_3) < StoI(From) || StoI(_Instruct_2) > StoI(To))
      {
        Log("  Requested messages out of range. Request skipped!",1,1);
        Instruct_Ok = 0;
        CPutS(To);
        CPutS("^M");
        CPutS(To);
        CPutS("^M");
        Goto StopDump;
      }
      If (StoI(_Instruct_2) >= StoI(From) && StoI(_Instruct_2) <= StoI(To))
        CPutS(_Instruct_2);
      else
      {
        Log("  Starting number too low. Using ",1,0);
        Log(From,0,0);
        Log(".",0,1);
        CputS(From);
      }
      CPutS("^M");
      If (StoI(_Instruct_3) >= StoI(From) && StoI(_Instruct_3) <= StoI(To))
        CPutS(_Instruct_3);
      else
      {
        Log("  Ending number too high. Using ",1,0);
        Log(To,0,0);
        Log(".",0,1);
        CPutS(To);
      }
      CputS("^M");
      AwaitCommand();
      CPutS("^H^HR DU C^M");
    }
    else
      Cputs("^X^M^M");
    StopDump:
    AwaitCommand();
  }
}

// -- Instructions --------------------------------------------------
DoInstruct()
{
  str
  Instruct_File[80],
  EXT[3];                              // To store file extension as string.
  _Instruct_Count = 0;
  While(_Instruct_Count < 100)
  {
    Instruct_OK   = 1;
    Instruct_File = Merge(_BBS_Dir,"INSTRUCT.");
    ++ _Instruct_Count;
    ItoS(_Instruct_Count,EXT);
    File = FOpen(Merge(Instruct_File,EXT),"r");
    If (!FError(File))                 // If instruction file exist, continue.
    {
      FGetS(_Instruct_type,70,File);              // Instruction type.
      FGetS(_Instruct_1,70,File);              // 11 more lines...
      FGetS(_Instruct_2,70,File);
      FGetS(_Instruct_3,70,File);
      FGetS(_Instruct_4,70,File);
      FGetS(_Instruct_5,70,File);
      FGetS(_Instruct_6,70,File);
      FGetS(_Instruct_7,70,File);
      FGetS(_Instruct_8,70,File);
      FGetS(_Instruct_9,70,File);
      FGetS(_Instruct_10,70,File);
      FGetS(_Instruct_11,70,File);
      FClose(File);

      If (_Instruct_type == "MESSAGE")  Message();
      If (_Instruct_type == "DOWNLOAD") Download();
      If (_Instruct_type == "UPLOAD")   Upload();
      If (_Instruct_type == "BULLDOWN") Bulldown();
      If (_Instruct_type == "JOINCONF") Joinconf(1);
      If (_Instruct_type == "RESCONF")  Resconf();
      If (_Instruct_type == "LISTDIR")  Listdir();
      If (_Instruct_type == "RESUME")   Resume();
      If (_Instruct_type == "REQUEST")  Request();
      _Instruct_type = "";
      If (Instruct_OK)
        FDelete(Merge(Instruct_file,EXT));
      else
        NoDelete = 0;
    }
  }
  if (NoDelete)
    FDelete(Merge(_BBS_Dir,"INSTRUCT"));
  AwaitCommand();
}

// == Script main body ==============================================
Main(str BBS_dir)
{
  FDelete(Merge(BBS_dir,"LOG"));   // Delete files from last session.
  FDelete(Merge(BBS_dir,"NEWFILES.GRB"));
  FDelete(Merge(BBS_dir,"$GETIT$.$$$"));
  FDelete(Merge("","$STOPIT$.$$$"));
 
  _BBSDoor_Count          = 1;
  _BBS_Dir          = BBS_dir;    // Store BBS_dir in global variable.
  _Restore_lang_Cmd          = "";
  _Logoff_Cmd          = "G Y N Y";  // LogOff string.
  NoDelete     = 1;
  Current      = "";         // Keep track of current conference.
  CTRL_C       = "";         // Store keydef for Ctrl-C.
  Dumped       = 0;
  _alarm_on    = 0;
  _zmod_rcrash = 0;          // ZModem crash recovery OFF.
  _zmod_auto   = 1;          // ZModem auto-download ON.

  SetHotKey();               // Redefine Ctrl-C.
  OpenLog();                 // Start new LOG file.
  Read_Config();             // Read CONFIG file for current BBS.
  Login();                   // Lets login and wait for Command prompt.
  SetDefaults("Login");      // Set user defaults for this session.
  If (FExists(_BBS_Dir,"PASSWORD"))
    ChangePassword();
  If (_Info_update == "Y")
    UserInfoUpdate();
  If (_Clear_confs == "Y")
    ClearConferences();
  DoInstruct();                         // Do instructions.
  Grab();
  If (_Grab_Cnf_list == "Y")            // Grab list of conferences.
    GetConfList();
  If (_Newfiles_scan == "Y")            // Scan for new files?
    NewFiles();
  SetDefaults("Logoff");
  If (_Restore_lang_Cmd != "")          // Restore to original language.
  {
    CPutS(_Restore_lang_Cmd);
    CPutS("^M");
    AwaitCommand();
  }
  If (FExists("","$STOPIT$.$$$"))
  {                              // In case $STOPIT$.$$$ exists, CTRL-C
    _Logoff = "N";               // has been pressed and logoff is stopped.
    FDelete("$STOPIT$.$$$");
    Log("Logoff stopped by hotkey.",1,1);
  }
  If (CTRL_C != "")
    KeySet(3,0,CTRL_C);
  If (_Logoff == "Y")
  {
    If (_Logoff_Delay != "0")
    {
      For (_BBSDoor_Count = StoI(_Logoff_Delay); _BBSDoor_Count > 0; _BBSDoor_Count = _BBSDoor_Count - 1)
      {
        ItoS(_BBSDoor_Count,_Logoff_Delay);
        Status_Wind(Merge(Merge("LogOff in ",_Logoff_Delay)," seconds. Press ESC to abort script."),10);
      }
    }
    CPutS(_Logoff_Cmd);
    CPutS(" [OFFLINER]^M^X");
    Waitfor("Logout",10);
    HangUp();
    Tone(200,7); Tone(205,7);
    Tone(200,7); Tone(205,7);
    Tone(200,7); Tone(205,7);
    Tone(200,7); Tone(205,7);
  }
  else
  {
    If (_Restore_lang_Cmd == "") CPutS("R D CLEAR^M");
    else           CPutS("L D SLETT^M");
  }
  Log("Script session completed.",1,1);
  FClose(LogFile);
}
// -- End of script -------------------------------------------------
// ==================================================================

