home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / EMBEDDED.CPP < prev    next >
C/C++ Source or Header  |  1998-05-12  |  86KB  |  2,711 lines

  1.  
  2. // LoraBBS Version 2.99 Free Edition
  3. // Copyright (C) 1987-98 Marco Maccaferri
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include "_ldefs.h"
  20. #include "lora.h"
  21. #include <errno.h>
  22.  
  23. typedef struct {
  24.    PSZ    Key;
  25.    PSZ    Text;
  26.    USHORT Len;
  27. } KEYWORDS;
  28.  
  29. KEYWORDS MeccaKeywords[] = {
  30.    // Color Tokens
  31.    { "black",        "\026\001\000", 3 },
  32.    { "blue",         "\026\001\001", 3 },
  33.    { "green",        "\026\001\002", 3 },
  34.    { "cyan",         "\026\001\003", 3 },
  35.    { "red",          "\026\001\004", 3 },
  36.    { "magenta",      "\026\001\005", 3 },
  37.    { "brown",        "\026\001\006", 3 },
  38.    { "gray",         "\026\001\007", 3 },
  39.    { "darkgray",     "\026\001\010", 3 },
  40.    { "lightblue",    "\026\001\011", 3 },
  41.    { "lightgreen",   "\026\001\012", 3 },
  42.    { "lightcyan",    "\026\001\013", 3 },
  43.    { "lightred",     "\026\001\014", 3 },
  44.    { "lightmagenta", "\026\001\015", 3 },
  45.    { "yellow",       "\026\001\016", 3 },
  46.    { "white",        "\026\001\017", 3 },
  47.  
  48.    // Cursor Control and Video Tokens
  49.    { "bell",         "\007",         1 },
  50.    { "bs",           "\010",         1 },
  51.    { "clreol",       "\026\007",     2 },
  52.    { "cls",          "\014",         1 },
  53.    { "cr",           "\015",         1 },
  54.    { "down",         "\026\004",     2 },
  55.    { "left",         "\026\005",     2 },
  56.    { "locate",       "\026\008",     2 },
  57.    { "lf",           "\012",         1 },
  58.    { "tab",          "\011",         1 },
  59.    { "right",        "\026\006",     2 },
  60.    { "up",           "\026\003",     2 },
  61.  
  62.    // Informational Tokens
  63.    { "age",          "\0062",        2 },
  64.    { "city",         "\006\003",     2 },
  65.    { "date",         "\006\004",     2 },
  66.    { "dl",           "\006\030",     2 },
  67.    { "fname",        "\006\006",     2 },
  68.    { "file_carea",   "\027\006A",    3 },
  69.    { "file_cname",   "\027\006N",    3 },
  70.    { "first",        "\006\006",     2 },
  71.    { "length",       "\006\014",     2 },
  72.    { "minutes",      "\006\013",     2 },
  73.    { "msg_carea",    "\027\015A",    3 },
  74.    { "msg_cmsg",     "\027\015L",    3 },
  75.    { "msg_cname",    "\027\015N",    3 },
  76.    { "msg_hmsg",     "\027\015H",    3 },
  77.    { "msg_nummsg",   "\027\015#",    3 },
  78.    { "node_num",     "\027jN",       3 },
  79.    { "phone",        "\027P",        2 },
  80.    { "ratio",        "\006\031",     2 },
  81.    { "realname",     "\027R",        2 },
  82.    { "remain",       "\006\017",     2 },
  83.    { "syscall",      "\006\021",     2 },
  84.    { "sys_name",     "\022\003",     2 },
  85.    { "sysop_name",   "\022\004",     2 },
  86.    { "time",         "\006\024",     2 },
  87.    { "timeoff",      "\006\020",     2 },
  88.    { "ul",           "\006R",        2 },
  89.    { "user",         "\006\002",     2 },
  90.    { "usercall",     "\006\005",     2 },
  91.  
  92.    // Questionnaire Tokens
  93.    { "choice",       "\017U",        2 },
  94.    { "menu",         "\017R",        2 },
  95.    { "open",         "\017O",        2 },
  96.  
  97.    // Flow control
  98.    { "color",        "\017E",        2 },
  99.    { "colour",       "\017E",        2 },
  100.    { "endcolor",     "\017e",        2 },
  101.    { "endcolour",    "\017e",        2 },
  102.    { "endrip",       "\017I",        2 },
  103.    { "iftask",       "\027b",        2 },
  104.    { "rip",          "\017G",        2 },
  105.  
  106.    { "enter",        "\001",         1 },
  107.    { "pause",        "\006\007",     2 },
  108.    { "quit",         "\017Q",        2 },
  109.    { "quote",        "\006\001",     2 },
  110.    { "repeat",       "\031",         1 },
  111.    { "repeatseq",    "\026\031",     2 },
  112.  
  113.    { NULL, NULL }
  114. };
  115.  
  116. #define NO_DROPFILE        0
  117. #define DOOR_SYS           1
  118. #define DOORX_SYS          2
  119. #define DORINFO1_DEF       3
  120. #define DORINFOX_DEF       4
  121.  
  122. #define SYSTEM_TERMQ       "\\QUEUES\\TELTERM.QUE"
  123.  
  124. TEmbedded::TEmbedded (void)
  125. {
  126.    Com = NULL;
  127.    Snoop = NULL;
  128.    User = NULL;
  129.    Log = NULL;
  130.    Cfg = NULL;
  131.    Language = NULL;
  132.  
  133.    MsgArea = NULL;
  134.    FileArea = NULL;
  135.  
  136.    Task = 1;
  137.    EndRun = Hangup = FALSE;
  138.    Ansi = Color = TRUE;
  139.    Rip = Avatar = FALSE;
  140.    HotKey = More = TRUE;
  141.    strcpy (Path, ".\\");
  142.    AltPath[0] = '\0';
  143.    ScreenHeight = 24;
  144.    TimeLimit = 0;
  145.    StartCall = 0L;
  146.    last_time = 0L;
  147.    IsDown = FALSE;
  148.    CarrierSpeed = 57600L;
  149.  
  150.    fp = NULL;
  151.    AnswerFile = NULL;
  152.    Position = NULL;
  153.    StopNested = Stop = FALSE;
  154.    Nested = 0;
  155.    Response = '\0';
  156.    Traslate[0] = '\0';
  157.    TrasPtr = Traslate;
  158.    TrasLen = 0;
  159.    IsMec = FALSE;
  160.    Required = FALSE;
  161. }
  162.  
  163. TEmbedded::~TEmbedded (void)
  164. {
  165.    if (fp != NULL)
  166.       fclose (fp);
  167. }
  168.  
  169. USHORT TEmbedded::AbortSession (VOID)
  170. {
  171.    USHORT RetVal = FALSE;
  172.    ULONG Len, Timeout;
  173.  
  174.    if (Com != NULL) {
  175.       if (Com->Carrier () == FALSE)
  176.          RetVal = TRUE;
  177.  
  178.       if (RetVal == TRUE && IsDown == FALSE) {
  179.          Timeout = TimerSet (200);
  180.          if (Cfg->CarrierDropTimeout != 0)
  181.             Timeout = TimerSet (Cfg->CarrierDropTimeout * 100L);
  182.  
  183.          do {
  184.             if (Com != NULL) {
  185.                if (Com->Carrier () == TRUE)
  186.                   RetVal = FALSE;
  187.             }
  188.          } while (TimeUp (Timeout) == FALSE && RetVal == TRUE);
  189.       }
  190.    }
  191.  
  192.    if (Snoop != NULL) {
  193.       if (Snoop->Carrier () == FALSE)
  194.          RetVal = TRUE;
  195.    }
  196.  
  197.    if (RetVal == FALSE && TimeLimit != 0) {
  198.       Len = (time (NULL) - StartCall) / 60L;
  199.       if (Len >= TimeLimit)
  200.          RetVal = TRUE;
  201.    }
  202.  
  203.    IsDown = RetVal;
  204.  
  205.    return (RetVal);
  206. }
  207.  
  208. VOID TEmbedded::ClrEol (VOID)
  209. {
  210.    if (Com != NULL) {
  211.       if (Avatar == TRUE) {
  212.          Com->BufferByte (CTRLV);
  213.          Com->BufferByte (CTRLG);
  214.       }
  215.       else if (Ansi == TRUE)
  216.          Com->BufferBytes ((UCHAR *)"\x1B[K", 3);
  217.    }
  218.  
  219.    if (Snoop != NULL && (Ansi == TRUE || Avatar == TRUE))
  220.       Snoop->BufferBytes ((UCHAR *)"\x1B[K", 3);
  221. }
  222.  
  223. USHORT TEmbedded::DisplayFile (PSZ pszFile)
  224. {
  225.    SHORT c;
  226.    USHORT RetVal = FALSE;
  227.    CHAR TempName[128];
  228.  
  229.    LastChar = EOF;
  230.    Line = 1;
  231.    strcpy (TempName, pszFile);
  232.    OnExit[0] = '\0';
  233.    IsMec = FALSE;
  234.  
  235.    if ((fp = OpenFile (TempName)) != NULL) {
  236.       RetVal = TRUE;
  237.       if (Log != NULL)
  238.          Log->Write (":Display File %s", TempName);
  239.       while ((c = GetNextChar ()) != EOF && AbortSession () == FALSE) {
  240.          if (c < 32)
  241.             ProcessControl ((UCHAR)c);
  242.          else {
  243.             if (Com != NULL)
  244.                Com->BufferByte ((UCHAR)c);
  245.             if (Snoop != NULL)
  246.                Snoop->BufferByte ((UCHAR)c);
  247.          }
  248.       }
  249.  
  250.       fclose (fp);
  251.       fp = NULL;
  252.    }
  253.  
  254.    if (AnswerFile != NULL) {
  255.       fclose (AnswerFile);
  256.       AnswerFile = NULL;
  257.       if (Log != NULL)
  258.          Log->Write (":Answer file closed");
  259.    }
  260.  
  261.    if (Com != NULL)
  262.       Com->UnbufferBytes ();
  263.    if (Snoop != NULL)
  264.       Snoop->UnbufferBytes ();
  265.  
  266.    if (OnExit[0] != '\0')
  267.       DisplayFile (OnExit);
  268.  
  269.    Stop = FALSE;
  270.    if (Nested == 0)
  271.       StopNested = FALSE;
  272.  
  273.    return (RetVal);
  274. }
  275.  
  276. USHORT TEmbedded::DisplayPrompt (PSZ pszString, USHORT usColor, USHORT usHilight, USHORT usUnbuffer)
  277. {
  278.    SHORT c;
  279.    USHORT RetVal = FALSE, Hilight = FALSE;
  280.    CHAR Temp[16];
  281.  
  282.    LastChar = EOF;
  283.    Line = 1;
  284.    IsMec = FALSE;
  285.  
  286.    if (LastColor != usColor)
  287.       SetColor (usColor);
  288.  
  289.    if ((Position = pszString) != NULL) {
  290.       RetVal = TRUE;
  291.       while ((c = GetNextChar ()) != EOF && AbortSession () == FALSE) {
  292.          if (c < 32) {
  293.             if (c == '\n') {
  294.                if (Com != NULL)
  295.                   Com->BufferByte ('\r');
  296.                if (Snoop != NULL)
  297.                   Snoop->BufferByte ('\r');
  298.             }
  299.             ProcessControl ((UCHAR)c);
  300.          }
  301.          else if (c == '^') {
  302.             if (PeekNextChar () != '^') {
  303.                Hilight = (USHORT)((Hilight == TRUE) ? FALSE : TRUE);
  304.                SetColor ((Hilight == TRUE) ? usHilight : usColor);
  305.             }
  306.             else {
  307.                GetNextChar ();
  308.                if (Com != NULL)
  309.                   Com->BufferByte ((unsigned char)c);
  310.                if (Snoop != NULL)
  311.                   Snoop->BufferByte ((unsigned char)c);
  312.             }
  313.          }
  314.          else if (c == '\x7E') {
  315.             sprintf (Temp, "%lu", TimeRemain ());
  316.             if (Com != NULL)
  317.                Com->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  318.             if (Snoop != NULL)
  319.                Snoop->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  320.          }
  321.          else {
  322.             if (Com != NULL)
  323.                Com->BufferByte ((unsigned char)c);
  324.             if (Snoop != NULL)
  325.                Snoop->BufferByte ((unsigned char)c);
  326.          }
  327.       }
  328.    }
  329.  
  330.    if (AnswerFile != NULL) {
  331.       fclose (AnswerFile);
  332.       AnswerFile = NULL;
  333.       if (Log != NULL)
  334.          Log->Write (":Answer file closed");
  335.    }
  336.  
  337.    if (usUnbuffer == TRUE) {
  338.       if (Com != NULL)
  339.          Com->UnbufferBytes ();
  340.       if (Snoop != NULL)
  341.          Snoop->UnbufferBytes ();
  342.    }
  343.  
  344.    return (RetVal);
  345. }
  346.  
  347. USHORT TEmbedded::DisplayString (PSZ pszString)
  348. {
  349.    SHORT c;
  350.    USHORT RetVal = FALSE;
  351.  
  352.    LastChar = EOF;
  353.    Line = 1;
  354.    IsMec = FALSE;
  355.  
  356.    if ((Position = pszString) != NULL) {
  357.       RetVal = TRUE;
  358.       while ((c = GetNextChar ()) != EOF && AbortSession () == FALSE) {
  359.          if (c < 32) {
  360.             if (c == '\n') {
  361.                if (Com != NULL)
  362.                   Com->BufferByte ('\r');
  363.                if (Snoop != NULL)
  364.                   Snoop->BufferByte ('\r');
  365.             }
  366.             ProcessControl ((UCHAR)c);
  367.          }
  368.          else {
  369.             if (Com != NULL)
  370.                Com->BufferByte ((unsigned char)c);
  371.             if (Snoop != NULL)
  372.                Snoop->BufferByte ((unsigned char)c);
  373.          }
  374.       }
  375.    }
  376.  
  377.    if (AnswerFile != NULL) {
  378.       fclose (AnswerFile);
  379.       AnswerFile = NULL;
  380.       if (Log != NULL)
  381.          Log->Write (":Answer file closed");
  382.    }
  383.  
  384.    if (Com != NULL)
  385.       Com->UnbufferBytes ();
  386.    if (Snoop != NULL)
  387.       Snoop->UnbufferBytes ();
  388.  
  389.    return (RetVal);
  390. }
  391.  
  392. USHORT TEmbedded::GetAnswer (USHORT flQuestion)
  393. {
  394.    CHAR answer[10];
  395.  
  396.    if (flQuestion & ASK_HELP) {
  397.       if (flQuestion & ASK_DEFYES)
  398.          Printf (Language->Text (LNG_DEFYESNOHELP));
  399.       else if (flQuestion & ASK_DEFNO)
  400.          Printf (Language->Text (LNG_YESDEFNOHELP));
  401.    }
  402.    else {
  403.       if (flQuestion & ASK_DEFYES)
  404.          Printf (Language->Text (LNG_DEFYESNO));
  405.       else if (flQuestion & ASK_DEFNO)
  406.          Printf (Language->Text (LNG_YESDEFNO));
  407.    }
  408.  
  409.    while (AbortSession () == FALSE) {
  410.       Input (answer, 1, INP_NOCRLF|INP_HOTKEY);
  411.  
  412.       if (AbortSession () == FALSE) {
  413.          if (answer[0] == '\0') {
  414.             Printf ("\n");
  415.             if (flQuestion & ASK_DEFYES)
  416.                return (ANSWER_YES);
  417.             else if (flQuestion & ASK_DEFNO)
  418.                return (ANSWER_NO);
  419.          }
  420.  
  421.          answer[0] = (CHAR)toupper (answer[0]);
  422.          if (answer[0] == Language->Yes) {
  423.             Printf ("\n");
  424.             return (ANSWER_YES);
  425.          }
  426.          if (answer[0] == Language->No) {
  427.             Printf ("\n");
  428.             return (ANSWER_NO);
  429.          }
  430.          if (answer[0] == Language->Help) {
  431.             if (flQuestion & ASK_HELP) {
  432.                Printf ("\n");
  433.                return (ANSWER_HELP);
  434.             }
  435.          }
  436.  
  437.          Printf ("\x08 \x08");
  438.       }
  439.    }
  440.  
  441.    return (0);
  442. }
  443.  
  444. USHORT TEmbedded::Getch (VOID)
  445. {
  446.    USHORT RetVal = 0;
  447.  
  448.    if (Com != NULL || Snoop != NULL) {
  449.       while (AbortSession () == FALSE && RetVal == 0) {
  450.          if (Com != NULL) {
  451.             if (Com->BytesReady () == TRUE)
  452.                RetVal = Com->ReadByte ();
  453.          }
  454.          else if (Snoop != NULL) {
  455.             if (Snoop->BytesReady () == TRUE)
  456.                RetVal = Snoop->ReadByte ();
  457.          }
  458.       }
  459.    }
  460.  
  461.    return (RetVal);
  462. }
  463.  
  464. VOID TEmbedded::Idle (VOID)
  465. {
  466.    time_t t;
  467.  
  468.    if ((t = time (NULL)) != last_time) {
  469.       last_time = t;
  470.       if (Snoop != NULL) {
  471.          Snoop->SetTime (t);
  472.          Snoop->SetTimeLeft (TimeRemain (TRUE));
  473.       }
  474.       else if (Com != NULL) {
  475.          Com->SetTime (t);
  476.          Com->SetTimeLeft (TimeRemain (TRUE));
  477.       }
  478.    }
  479. }
  480.  
  481. // ----------------------------------------------------------------------
  482. // Descrizione:
  483. //    Accetta una stringa in input dall'utente.
  484. //
  485. // Argomenti:
  486. //    pszBuffer = Puntatore ad un buffer di caratteri per la stringa
  487. //                digitata dall'utente.
  488. //    usMaxlen  = Lunghezza massima della stringa
  489. //    flAttrib  = Attributi di input. Puo' essere uno dei seguenti
  490. //                valori:
  491. //
  492. //                INP_FIELD    = Traccia uno sfondo pari alla dimensione
  493. //                               massima della stringa.
  494. //                INP_FANCY    = Forza le maiuscole (per i nomi).
  495. //                INP_NOCRLF   = Non visualizza il CR/LF alla fine della
  496. //                               stringa di input.
  497. //                INP_PWD      = Visualizza un asterisco al posto delle
  498. //                               lettere digitate (per l'inserimento di password).
  499. //                INP_NOCOLOR  = Non effettua il reset del colore alla fine
  500. //                               dell'inserimento.
  501. //                INP_HOTKEY   = Attiva gli hotkey se richiesto anche
  502. //                               dall'utente.
  503. //                INP_NUMERIC  = Indica un input numerico, tutto il resto
  504. //                               viene ignorato.
  505. //                INP_NONUMHOT = Impedisce che venga attivato il modo hot-key
  506. //                               se il carattere digitato e' un numero.
  507. //
  508. // Valori di ritorno:
  509. //    pszBuffer = Stringa digitata dall'utente.
  510. // ----------------------------------------------------------------------
  511.  
  512. PSZ TEmbedded::Input (PSZ pszBuffer, USHORT usMaxlen, USHORT flAttrib)
  513. {
  514.    USHORT i, c, Len, DoFancy, Enter;
  515.    USHORT Warn = FALSE;
  516.    PSZ p;
  517.  
  518.    p = pszBuffer;
  519.    Len = 0;
  520.    DoFancy = TRUE;
  521.    Enter = FALSE;
  522.  
  523.    if (Com != NULL)
  524.       Com->UnbufferBytes ();
  525.    if (Snoop != NULL)
  526.       Snoop->UnbufferBytes ();
  527.  
  528.    if ((flAttrib & INP_FIELD) && (Ansi == TRUE || Avatar == TRUE) && Color == TRUE) {
  529.       for (i = 0; i < usMaxlen; i++) {
  530.          if (Com != NULL)
  531.             Com->BufferByte (' ');
  532.          if (Snoop != NULL)
  533.             Snoop->BufferByte (' ');
  534.       }
  535.       for (i = 0; i < usMaxlen; i++) {
  536.          if (Com != NULL)
  537.             Com->BufferByte (8);
  538.          if (Snoop != NULL)
  539.             Snoop->BufferByte (8);
  540.       }
  541.       if (Com != NULL)
  542.          Com->UnbufferBytes ();
  543.       if (Snoop != NULL)
  544.          Snoop->UnbufferBytes ();
  545.    }
  546.  
  547.    LastActivity = time (NULL);
  548.  
  549.    while (Enter == FALSE && AbortSession () == FALSE) {
  550.       if (KBHit ()) {
  551.          Warn = FALSE;
  552.          LastActivity = time (NULL);
  553.          if ((c = Getch ()) == 0)
  554.             c = (short)(Getch () << 8);
  555.  
  556.          if (c == 13)
  557.             Enter = TRUE;
  558.          else if (c == 8 || c == 127) {
  559.             if (Len > 0) {
  560.                if (Com != NULL)
  561.                   Com->SendBytes ((UCHAR *)"\x08 \x08", 3);
  562.                if (Snoop != NULL)
  563.                   Snoop->SendBytes ((UCHAR *)"\x08 \x08", 3);
  564.                p--;
  565.                Len--;
  566.             }
  567.          }
  568.          else if (c >= 32 && c < 127) {
  569.             if (Len < usMaxlen) {
  570.                *p++ = (CHAR)c;
  571.                Len++;
  572.                if (flAttrib & INP_PWD)
  573.                   Putch ('*');
  574.                else
  575.                   Putch ((UCHAR)c);
  576.  
  577.                if (!(flAttrib & INP_NUMERIC) || !isdigit (c)) {
  578.                   if (Len == 1 && flAttrib & INP_HOTKEY && (!isdigit (c) || !(flAttrib & INP_NONUMHOT))) {
  579.                      if (HotKey == TRUE)
  580.                         Enter = TRUE;
  581.                   }
  582.                }
  583.             }
  584.          }
  585.       }
  586.       else {
  587.          if ((time (NULL) - LastActivity) > 180 && Warn == FALSE) {
  588.             Printf ("\n\026\001\014Warning : only 20 seconds to hangup (inactivity) !\026\001\007\n");
  589.             Warn = TRUE;
  590.          }
  591.          if ((time (NULL) - LastActivity) > 200) {
  592.             Printf ("\n\026\001\014User inactive, hanging up...\026\001\007\n");
  593.             StartCall = 0L;
  594.          }
  595.          Idle ();
  596.       }
  597.    }
  598.  
  599.    *p = '\0';
  600.  
  601.    if (flAttrib & INP_FANCY) {
  602.       strlwr (pszBuffer);
  603.       p = pszBuffer;
  604.       *p = (CHAR)toupper (*p);
  605.       while ((p = strchr (p, ' ')) != NULL) {
  606.          p[1] = (CHAR)toupper (p[1]);
  607.          p++;
  608.       }
  609.    }
  610.  
  611.    if (AbortSession () == FALSE) {
  612.       SetColor (7);
  613.       if (!(flAttrib & INP_NOCRLF)) {
  614.          if (Com != NULL)
  615.             Com->BufferBytes ((UCHAR *)"\r\n", 2);
  616.          if (Snoop != NULL)
  617.             Snoop->BufferBytes ((UCHAR *)"\r\n", 2);
  618.       }
  619.       if (Com != NULL)
  620.          Com->UnbufferBytes ();
  621.       if (Snoop != NULL)
  622.          Snoop->UnbufferBytes ();
  623.    }
  624.    else {
  625.       if (Com != NULL)
  626.          Com->ClearOutbound ();
  627.       if (Snoop != NULL)
  628.          Snoop->ClearOutbound ();
  629.    }
  630.  
  631.    return (pszBuffer);
  632. }
  633.  
  634. PSZ TEmbedded::GetString (PSZ pszBuffer, USHORT usMaxlen, USHORT flAttrib)
  635. {
  636.    return (Input (pszBuffer, usMaxlen, flAttrib));
  637. }
  638.  
  639. SHORT TEmbedded::GetNextChar (VOID)
  640. {
  641.    SHORT RetVal = EOF, c;
  642.    UCHAR Byte;
  643.  
  644.    if (Stop == FALSE && (Nested == 0 || StopNested == FALSE)) {
  645.       if (TrasLen != 0) {
  646.          RetVal = *TrasPtr++;
  647.          TrasLen--;
  648.       }
  649.       else if (fp != NULL) {
  650.          if (LastChar == EOF) {
  651.             if (fp != NULL)
  652.                RetVal = (SHORT)fgetc (fp);
  653.          }
  654.          else {
  655.             RetVal = LastChar;
  656.             LastChar = EOF;
  657.          }
  658.       }
  659.       else if (Position != NULL) {
  660.          if (LastChar == EOF) {
  661.             if ((RetVal = Position[0]) == '\0')
  662.                RetVal = EOF;
  663.             else
  664.                Position++;
  665.          }
  666.          else {
  667.             RetVal = LastChar;
  668.             LastChar = EOF;
  669.          }
  670.       }
  671.  
  672.       if (RetVal == '[' && IsMec == TRUE) {
  673.          if (PeekNextChar () != '[') {
  674.             TranslateKeyword ();
  675.             if (TrasLen != 0) {
  676.                RetVal = *TrasPtr++;
  677.                TrasLen--;
  678.             }
  679.             else
  680.                RetVal = GetNextChar ();
  681.          }
  682.          else
  683.             RetVal = GetNextChar ();
  684.       }
  685.  
  686.       if (RetVal == '\\') {
  687.          if (fp != NULL)
  688.             c = (SHORT)fgetc (fp);
  689.          else if (Position != NULL) {
  690.             if ((c = Position[0]) == '\0')
  691.                c = EOF;
  692.             else
  693.                Position++;
  694.          }
  695.  
  696.          if (isdigit (c)) {
  697.             Byte = (UCHAR)((c - '0') * 64);
  698.             if (fp != NULL)
  699.                c = (SHORT)fgetc (fp);
  700.             else if (Position != NULL) {
  701.                if ((c = Position[0]) == '\0')
  702.                   c = EOF;
  703.                else
  704.                   Position++;
  705.             }
  706.             Byte += (UCHAR)((c - '0') * 8);
  707.             if (fp != NULL)
  708.                c = (SHORT)fgetc (fp);
  709.             else if (Position != NULL) {
  710.                if ((c = Position[0]) == '\0')
  711.                   c = EOF;
  712.                else
  713.                   Position++;
  714.             }
  715.             Byte += (UCHAR)(c - '0');
  716.             RetVal = Byte;
  717.          }
  718.          else if (c == 'x') {
  719.             if (fp != NULL)
  720.                c = (SHORT)fgetc (fp);
  721.             else if (Position != NULL) {
  722.                if ((c = Position[0]) == '\0')
  723.                   c = EOF;
  724.                else
  725.                   Position++;
  726.             }
  727.             if ((Byte = (UCHAR)(c - '0')) > 9)
  728.                Byte -= 7;
  729.             Byte <<= 4;
  730.             if (fp != NULL)
  731.                c = (SHORT)fgetc (fp);
  732.             else if (Position != NULL) {
  733.                if ((c = Position[0]) == '\0')
  734.                   c = EOF;
  735.                else
  736.                   Position++;
  737.             }
  738.             c -= '0';
  739.             if (c > 9)
  740.                c -= 7;
  741.             Byte |= (UCHAR)c;
  742.             RetVal = Byte;
  743.          }
  744.          else if (c == 'n')
  745.             RetVal = '\n';
  746.          else if (c == 'r')
  747.             RetVal = '\r';
  748.          else if (c == 'a')
  749.             RetVal = '\a';
  750.          else if (c == 't')
  751.             RetVal = '\t';
  752.          else if (c == '\\')
  753.             RetVal = '\\';
  754.          else {
  755.             LastChar = c;
  756.             RetVal = '\\';
  757.          }
  758.       }
  759.    }
  760.  
  761.    return (RetVal);
  762. }
  763.  
  764. USHORT TEmbedded::KBHit (VOID)
  765. {
  766.    USHORT RetVal = FALSE;
  767.  
  768.    if (Com != NULL) {
  769.       if (Com->BytesReady () == TRUE)
  770.          RetVal = TRUE;
  771.    }
  772.    else if (Snoop != NULL) {
  773.       if (Snoop->BytesReady () == TRUE)
  774.          RetVal = TRUE;
  775.    }
  776.  
  777.    return (RetVal);
  778. }
  779.  
  780. SHORT TEmbedded::MoreQuestion (SHORT nLine)
  781. {
  782.    USHORT SaveColor;
  783.    CHAR Temp[2];
  784.  
  785.    if (nLine == -1 || nLine == 0 || More == FALSE)
  786.       return (nLine);
  787.  
  788.    if (++nLine >= (SHORT)(ScreenHeight - 1)) {
  789.       SaveColor = LastColor;
  790.       while (AbortSession () == FALSE) {
  791.          OutString (Language->Text(LNG_MOREQUESTION));
  792.          GetString (Temp, 1, INP_NOCRLF|INP_NOCOLOR|INP_HOTKEY);
  793.          if (toupper (Temp[0]) == Language->Text(LNG_QUIT)[0]) {
  794.             OutString (Language->Text(LNG_DELETEMOREQUESTION));
  795.             SetColor (SaveColor);
  796.             return (0);
  797.          }
  798.          else if (toupper (Temp[0]) == Language->Text(LNG_NONSTOP)[0]) {
  799.             OutString (Language->Text(LNG_DELETEMOREQUESTION));
  800.             SetColor (SaveColor);
  801.             return (-1);
  802.          }
  803.          else if (toupper (Temp[0]) == Language->Text(LNG_CONTINUE)[0] || Temp[0] == '\0') {
  804.             OutString (Language->Text(LNG_DELETEMOREQUESTION));
  805.             SetColor (SaveColor);
  806.             return (1);
  807.          }
  808.          else
  809.             OutString ("\r");
  810.       }
  811.    }
  812.  
  813.    return (nLine);
  814. }
  815.  
  816. FILE *TEmbedded::OpenFile (PSZ pszName, PSZ pszAccess)
  817. {
  818.    FILE *fp;
  819.    CHAR Temp[128], *p;
  820.  
  821.    strcpy (Temp, pszName);
  822.    strlwr (Temp);
  823.    IsMec = FALSE;
  824.  
  825.    if ((fp = _fsopen (AdjustPath (Temp), pszAccess, SH_DENYNO)) == NULL) {
  826.       if ((p = strchr (Temp, '.')) != NULL)
  827.          *p = '\0';
  828.       strcat (Temp, ".bbs");
  829.       if ((fp = _fsopen (Temp, pszAccess, SH_DENYNO)) == NULL) {
  830.          if (fp == NULL && Rip == TRUE) {
  831.             if ((p = strchr (Temp, '.')) != NULL)
  832.                *p = '\0';
  833.             strcat (Temp, ".rip");
  834.             fp = _fsopen (Temp, pszAccess, SH_DENYNO);
  835.          }
  836.          if (fp == NULL && Avatar == TRUE) {
  837.             if ((p = strchr (Temp, '.')) != NULL)
  838.                *p = '\0';
  839.             strcat (Temp, ".avt");
  840.             fp = _fsopen (Temp, pszAccess, SH_DENYNO);
  841.          }
  842.          if (fp == NULL && Ansi == TRUE) {
  843.             if ((p = strchr (Temp, '.')) != NULL)
  844.                *p = '\0';
  845.             strcat (Temp, ".ans");
  846.             fp = _fsopen (Temp, pszAccess, SH_DENYNO);
  847.          }
  848.          if (fp == NULL) {
  849.             if ((p = strchr (Temp, '.')) != NULL)
  850.                *p = '\0';
  851.             strcat (Temp, ".mec");
  852.             if ((fp = _fsopen (Temp, pszAccess, SH_DENYNO)) != NULL)
  853.                IsMec = TRUE;
  854.          }
  855.       }
  856.       if (fp == NULL && AltPath[0] != '\0') {
  857.          strcpy (Temp, AltPath);
  858.          strcat (Temp, pszName);
  859.          strlwr (Temp);
  860.          if ((fp = _fsopen (AdjustPath (Temp), pszAccess, SH_DENYNO)) == NULL) {
  861.             if ((p = strchr (Temp, '.')) != NULL)
  862.                *p = '\0';
  863.             strcat (Temp, ".bbs");
  864.             if ((fp = _fsopen (Temp, pszAccess, SH_DENYNO)) == NULL) {
  865.                if (fp == NULL && Rip == TRUE) {
  866.                   if ((p = strchr (Temp, '.')) != NULL)
  867.                      *p = '\0';
  868.                   strcat (Temp, ".rip");
  869.                   fp = _fsopen (Temp, pszAccess, SH_DENYNO);
  870.                }
  871.                if (fp == NULL && Avatar == TRUE) {
  872.                   if ((p = strchr (Temp, '.')) != NULL)
  873.                      *p = '\0';
  874.                   strcat (Temp, ".avt");
  875.                   fp = _fsopen (Temp, pszAccess, SH_DENYNO);
  876.                }
  877.                if (fp == NULL && Ansi == TRUE) {
  878.                   if ((p = strchr (Temp, '.')) != NULL)
  879.                      *p = '\0';
  880.                   strcat (Temp, ".ans");
  881.                   fp = _fsopen (Temp, pszAccess, SH_DENYNO);
  882.                }
  883.                if (fp == NULL) {
  884.                   if ((p = strchr (Temp, '.')) != NULL)
  885.                      *p = '\0';
  886.                   strcat (Temp, ".mec");
  887.                   if ((fp = _fsopen (Temp, pszAccess, SH_DENYNO)) != NULL)
  888.                      IsMec = TRUE;
  889.                }
  890.             }
  891.          }
  892.       }
  893.       if (fp == NULL) {
  894.          strcpy (Temp, Path);
  895.          strcat (Temp, pszName);
  896.          strlwr (Temp);
  897.          if ((fp = _fsopen (AdjustPath (Temp), pszAccess, SH_DENYNO)) == NULL) {
  898.             if ((p = strchr (Temp, '.')) != NULL)
  899.                *p = '\0';
  900.             strcat (Temp, ".bbs");
  901.             if ((fp = _fsopen (Temp, pszAccess, SH_DENYNO)) == NULL) {
  902.                if (fp == NULL && Rip == TRUE) {
  903.                   if ((p = strchr (Temp, '.')) != NULL)
  904.                      *p = '\0';
  905.                   strcat (Temp, ".rip");
  906.                   fp = _fsopen (Temp, pszAccess, SH_DENYNO);
  907.                }
  908.                if (fp == NULL && Avatar == TRUE) {
  909.                   if ((p = strchr (Temp, '.')) != NULL)
  910.                      *p = '\0';
  911.                   strcat (Temp, ".avt");
  912.                   fp = _fsopen (Temp, pszAccess, SH_DENYNO);
  913.                }
  914.                if (fp == NULL && Ansi == TRUE) {
  915.                   if ((p = strchr (Temp, '.')) != NULL)
  916.                      *p = '\0';
  917.                   strcat (Temp, ".ans");
  918.                   fp = _fsopen (Temp, pszAccess, SH_DENYNO);
  919.                }
  920.                if (fp == NULL) {
  921.                   if ((p = strchr (Temp, '.')) != NULL)
  922.                      *p = '\0';
  923.                   strcat (Temp, ".mec");
  924.                   if ((fp = _fsopen (Temp, pszAccess, SH_DENYNO)) != NULL)
  925.                      IsMec = TRUE;
  926.                }
  927.             }
  928.          }
  929.       }
  930.    }
  931.  
  932.    return (fp);
  933. }
  934.  
  935. VOID TEmbedded::OutString (PSZ pszFormat, ...)
  936. {
  937.    va_list arglist;
  938.    PSZ p;
  939.  
  940.    va_start (arglist, pszFormat);
  941.    vsprintf (Temp2, pszFormat, arglist);
  942.    va_end (arglist);
  943.  
  944.    p = Temp2;
  945.    while (*p != '\0') {
  946.       if (*p == CTRLV && p[1] == CTRLA) {
  947.          SetColor (p[2]);
  948.          p += 3;
  949.       }
  950.       else {
  951.          if (Com != NULL)
  952.             Com->BufferByte ((UCHAR)*p);
  953.          if (Snoop != NULL)
  954.             Snoop->BufferByte ((UCHAR)*p);
  955.          p++;
  956.       }
  957.    }
  958. }
  959.  
  960. SHORT TEmbedded::PeekNextChar (VOID)
  961. {
  962.    SHORT RetVal = EOF, c;
  963.    UCHAR Byte;
  964.  
  965.    if (Stop == FALSE && (Nested == 0 || StopNested == FALSE)) {
  966.       if (fp != NULL) {
  967.          if (LastChar == EOF) {
  968.             if (fp != NULL)
  969.                RetVal = (SHORT)fgetc (fp);
  970.          }
  971.          else
  972.             RetVal = LastChar;
  973.       }
  974.       else if (Position != NULL) {
  975.          if (LastChar == EOF) {
  976.             if (Position != NULL) {
  977.                if ((RetVal = Position[0]) == '\0')
  978.                   RetVal = EOF;
  979.                else
  980.                   Position++;
  981.             }
  982.          }
  983.          else
  984.             RetVal = LastChar;
  985.       }
  986.  
  987.       if (RetVal == '\\' && LastChar == EOF) {
  988.          if (fp != NULL)
  989.             c = (SHORT)fgetc (fp);
  990.          else if (Position != NULL) {
  991.             if ((c = Position[0]) == '\0')
  992.                c = EOF;
  993.             else
  994.                Position++;
  995.          }
  996.  
  997.          if (isdigit (c)) {
  998.             Byte = (UCHAR)((c - '0') * 64);
  999.             if (fp != NULL)
  1000.                c = (SHORT)fgetc (fp);
  1001.             else if (Position != NULL) {
  1002.                if ((c = Position[0]) == '\0')
  1003.                   c = EOF;
  1004.                else
  1005.                   Position++;
  1006.             }
  1007.             Byte += (UCHAR)((c - '0') * 8);
  1008.             if (fp != NULL)
  1009.                c = (SHORT)fgetc (fp);
  1010.             else if (Position != NULL) {
  1011.                if ((c = Position[0]) == '\0')
  1012.                   c = EOF;
  1013.                else
  1014.                   Position++;
  1015.             }
  1016.             Byte += (UCHAR)(c - '0');
  1017.             RetVal = Byte;
  1018.          }
  1019.          else if (c == 'x') {
  1020.             if (fp != NULL)
  1021.                c = (SHORT)fgetc (fp);
  1022.             else if (Position != NULL) {
  1023.                if ((c = Position[0]) == '\0')
  1024.                   c = EOF;
  1025.                else
  1026.                   Position++;
  1027.             }
  1028.             if ((Byte = (UCHAR)(c - '0')) > 9)
  1029.                Byte -= 7;
  1030.             Byte <<= 4;
  1031.             if (fp != NULL)
  1032.                c = (SHORT)fgetc (fp);
  1033.             else if (Position != NULL) {
  1034.                if ((c = Position[0]) == '\0')
  1035.                   c = EOF;
  1036.                else
  1037.                   Position++;
  1038.             }
  1039.             c -= '0';
  1040.             if (c > 9)
  1041.                c -= 7;
  1042.             Byte |= (UCHAR)c;
  1043.             RetVal = Byte;
  1044.          }
  1045.          else if (c == 'n')
  1046.             RetVal = '\n';
  1047.          else if (c == 'r')
  1048.             RetVal = '\r';
  1049.          else if (c == 'a')
  1050.             RetVal = '\a';
  1051.          else if (c == 't')
  1052.             RetVal = '\t';
  1053.          else if (c == '\\')
  1054.             RetVal = '\\';
  1055.          else
  1056.             RetVal = c;
  1057.       }
  1058.    }
  1059.  
  1060.    LastChar = RetVal;
  1061.  
  1062.    return (RetVal);
  1063. }
  1064.  
  1065. VOID TEmbedded::PressEnter (VOID)
  1066. {
  1067.    USHORT SaveColor;
  1068.    CHAR Temp[2];
  1069.  
  1070.    if (Language != NULL) {
  1071.       SaveColor = LastColor;
  1072.       OutString (Language->Text(LNG_PRESSENTER));
  1073.       GetString (Temp, 1, INP_NOCRLF|INP_NOCOLOR|INP_HOTKEY);
  1074.       OutString ("\r                             \r");
  1075.       SetColor (SaveColor);
  1076.    }
  1077. }
  1078.  
  1079. VOID TEmbedded::Printf (PSZ pszFormat, ...)
  1080. {
  1081.    va_list arglist;
  1082.  
  1083.    va_start (arglist, pszFormat);
  1084.    vsprintf (Temp, pszFormat, arglist);
  1085.    va_end (arglist);
  1086.  
  1087.    DisplayString (Temp);
  1088.  
  1089.    if (Com != NULL)
  1090.       Com->UnbufferBytes ();
  1091.    if (Snoop != NULL)
  1092.       Snoop->UnbufferBytes ();
  1093. }
  1094.  
  1095. VOID TEmbedded::BufferedPrintf (PSZ pszFormat, ...)
  1096. {
  1097.    va_list arglist;
  1098.  
  1099.    va_start (arglist, pszFormat);
  1100.    vsprintf (Temp, pszFormat, arglist);
  1101.    va_end (arglist);
  1102.  
  1103.    DisplayString (Temp);
  1104. }
  1105.  
  1106. VOID TEmbedded::PrintfAt (USHORT usRow, USHORT usColumn, PSZ pszFormat, ...)
  1107. {
  1108.    va_list arglist;
  1109.    CHAR Position[20];
  1110.  
  1111.    va_start (arglist, pszFormat);
  1112.    vsprintf (Temp, pszFormat, arglist);
  1113.    va_end (arglist);
  1114.  
  1115.    if (Avatar == TRUE)
  1116.       sprintf (Position, "\026\010%c%c", usRow, usColumn);
  1117.    else if (Ansi == TRUE)
  1118.       sprintf (Position, "\x1B[%d;%df", usRow, usColumn);
  1119.    if (Com != NULL)
  1120.       Com->BufferBytes ((UCHAR *)Position, (USHORT)strlen (Position));
  1121.    if (Snoop != NULL)
  1122.       Snoop->BufferBytes ((UCHAR *)Position, (USHORT)strlen (Position));
  1123.  
  1124.    DisplayString (Temp);
  1125.  
  1126.    if (Com != NULL)
  1127.       Com->UnbufferBytes ();
  1128.    if (Snoop != NULL)
  1129.       Snoop->UnbufferBytes ();
  1130. }
  1131.  
  1132. VOID TEmbedded::BufferedPrintfAt (USHORT usRow, USHORT usColumn, PSZ pszFormat, ...)
  1133. {
  1134.    va_list arglist;
  1135.    CHAR Position[20];
  1136.  
  1137.    va_start (arglist, pszFormat);
  1138.    vsprintf (Temp, pszFormat, arglist);
  1139.    va_end (arglist);
  1140.  
  1141.    if (Avatar == TRUE || Ansi == TRUE) {
  1142.       if (Avatar == TRUE)
  1143.          sprintf (Position, "\026\010%c%c", usRow, usColumn);
  1144.       else if (Ansi == TRUE)
  1145.          sprintf (Position, "\x1B[%d;%df", usRow, usColumn);
  1146.       if (Com != NULL)
  1147.          Com->BufferBytes ((UCHAR *)Position, (USHORT)strlen (Position));
  1148.       if (Snoop != NULL)
  1149.          Snoop->BufferBytes ((UCHAR *)Position, (USHORT)strlen (Position));
  1150.    }
  1151.  
  1152.    DisplayString (Temp);
  1153. }
  1154.  
  1155. VOID TEmbedded::ProcessControl (UCHAR ucControl)
  1156. {
  1157.    SHORT i, c;
  1158.    CHAR Temp[128], *p;
  1159.  
  1160.    switch (ucControl) {
  1161.       case CTRLA:             // ^A = Premi enter per continuare
  1162.          if (PeekNextChar () != CTRLA)
  1163.             GetString (Temp, 1, INP_HOTKEY);
  1164.          else {
  1165.             GetNextChar ();
  1166.             PressEnter ();
  1167.          }
  1168.          break;
  1169.       case CTRLD:             // ^D = Abilita la pausa a fine pagina
  1170.          More = TRUE;
  1171.          Line = 1;
  1172.          break;
  1173.       case CTRLE:             // ^E = Disabilita la pausa a fine pagina
  1174.          More = FALSE;
  1175.          Line = 1;
  1176.          break;
  1177.       case CTRLF:
  1178.          ProcessControlF ();
  1179.          break;
  1180.       case CTRLK:
  1181.          ProcessControlK ();
  1182.          break;
  1183.       case CTRLL:             // ^L = Cancella lo schermo
  1184.          if (Ansi == TRUE || Avatar == TRUE) {
  1185.             if (Ansi == TRUE && User->ScreenClear == FALSE)
  1186.                OutString ("\x1B[2J\x1B[1;1f");
  1187.             else
  1188.                OutString ("\x0C");
  1189.          }
  1190.          else
  1191.             OutString ("\n");
  1192.          Line = 1;
  1193.          break;
  1194.       case CTRLO:
  1195.          ProcessControlO ();
  1196.          break;
  1197.       case CTRLP:
  1198.          ProcessControlP ();
  1199.          break;
  1200.       case CTRLR:
  1201.          if ((c = GetNextChar ()) != EOF) {
  1202.             switch (c) {
  1203.                case CTRLC:    // ^R^C = System Name
  1204.                   if (Cfg != NULL)
  1205.                      OutString ("%s", Cfg->SystemName);
  1206.                   break;
  1207.                case CTRLD:    // ^R^D = Sysop Name
  1208.                   if (Cfg != NULL)
  1209.                      OutString ("%s", Cfg->SysopName);
  1210.                   break;
  1211.             }
  1212.          }
  1213.          break;
  1214.       case CTRLV:
  1215.          if ((c = GetNextChar ()) != EOF) {
  1216.             switch (c) {
  1217.                case CTRLA:    // ^V^A[^P][col] = Cambia il colore in [col]
  1218.                   if ((c = GetNextChar ()) != EOF) {
  1219.                      if (c == CTRLP) {
  1220.                         if ((c = GetNextChar ()) != EOF)
  1221.                            c &= 0x7F;
  1222.                      }
  1223.                      SetColor (c);
  1224.                   }
  1225.                   break;
  1226.                case CTRLG:    // ^V^G = Cancella fino alla fine della linea
  1227.                   ClrEol ();
  1228.                   break;
  1229.                case CTRLH:    // ^V^H[y][x] = Posiziona il cursore in [x],[y]
  1230.                   if ((c = GetNextChar ()) != EOF) {
  1231.                      if ((i = GetNextChar ()) != EOF) {
  1232.                         if (Avatar == TRUE) {
  1233.                            if (Com != NULL) {
  1234.                               Com->BufferByte (CTRLV);
  1235.                               Com->BufferByte (CTRLA);
  1236.                               Com->BufferByte ((UCHAR)c);
  1237.                               Com->BufferByte ((UCHAR)i);
  1238.                            }
  1239.                            if (Snoop != NULL) {
  1240.                               Snoop->BufferByte (CTRLV);
  1241.                               Snoop->BufferByte (CTRLA);
  1242.                               Snoop->BufferByte ((UCHAR)c);
  1243.                               Snoop->BufferByte ((UCHAR)i);
  1244.                            }
  1245.                         }
  1246.                         else if (Ansi == TRUE)
  1247.                            OutString ("\x1B[%d;%df", c, i);
  1248.                         Line = 1;
  1249.                      }
  1250.                   }
  1251.                   break;
  1252.                case CTRLY:    // ^V^Y[len][s][n] = Ripete la sequenza
  1253.                   c = GetNextChar ();
  1254.                   p = Temp;
  1255.                   for (i = 0; i < c; i++)
  1256.                      *p++ = (CHAR)GetNextChar ();
  1257.                   *p = '\0';
  1258.                   c = GetNextChar ();
  1259.                   for (i = 0; i < c; i++)
  1260.                      OutString ("%s", Temp);
  1261.                   break;
  1262.             }
  1263.          }
  1264.          break;
  1265.       case CTRLW:
  1266.          ProcessControlW ();
  1267.          break;
  1268.       case CTRLY:             // ^Y[char][rep] = Ripete il carattere [char] per [rep] volte
  1269.          if ((c = GetNextChar ()) != EOF) {
  1270.             if ((i = GetNextChar ()) != EOF) {
  1271.                while (i-- > 0) {
  1272.                   if (Com != NULL)
  1273.                      Com->BufferByte ((UCHAR)c);
  1274.                   if (Snoop != NULL)
  1275.                      Snoop->BufferByte ((UCHAR)c);
  1276.                }
  1277.             }
  1278.          }
  1279.          break;
  1280.       case CTRLG:
  1281.       case CTRLH:
  1282.       case '\n':
  1283.       case '\r':
  1284.       case ESC:
  1285.       case DEL:
  1286.          if (Com != NULL)
  1287.             Com->BufferByte (ucControl);
  1288.          if (Snoop != NULL)
  1289.             Snoop->BufferByte (ucControl);
  1290.          if (ucControl == '\n') {
  1291.             if ((Line = MoreQuestion (Line)) == 0)
  1292.                Stop = TRUE;
  1293.          }
  1294.          break;
  1295.       default:
  1296.          if (ucControl >= 128) {
  1297.             if (Com != NULL)
  1298.                Com->BufferByte (ucControl);
  1299.             if (Snoop != NULL)
  1300.                Snoop->BufferByte (ucControl);
  1301.          }
  1302.          break;
  1303.    }
  1304. }
  1305.  
  1306. VOID TEmbedded::ProcessControlF (VOID)
  1307. {
  1308.    SHORT c;
  1309.  
  1310.    if ((c = GetNextChar ()) != EOF) {
  1311.       switch (c) {
  1312.          case 'A':      // ^FA = Nome e cognome dell'utente
  1313.             if (User != NULL)
  1314.                OutString ("%s", User->Name);
  1315.             break;
  1316.          case 'B':      // ^FB = New files check
  1317.             OutString ("%s", (User->NewFileCheck == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1318.             break;
  1319.          case 'D':    // ^FD = E-Mail address
  1320.             if (User != NULL)
  1321.                OutString ("%s", User->InetAddress);
  1322.             break;
  1323.          case 'E':    // ^FE = Phone number
  1324.             if (User != NULL)
  1325.                OutString ("%s", User->DayPhone);
  1326.             break;
  1327.          case 'I':    // ^FI = IBM characters YES/NO
  1328.             OutString ("%s", (User->IBMChars == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1329.             break;
  1330.          case 'K':    // ^F0 = Full Screen Editor YES/NO
  1331.             OutString ("%s", (User->Kludges == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1332.             break;
  1333.          case 'N':    // ^FN = Last message read
  1334.             if (User != NULL && MsgArea != NULL)
  1335.                OutString ("%lu", MsgArea->LastReaded);
  1336.             break;
  1337.          case 'O':    // ^FO = New messages
  1338.             if (User != NULL && MsgArea != NULL)
  1339.                OutString ("%lu", MsgArea->ActiveMsgs - MsgArea->LastReaded);
  1340.             break;
  1341.          case 'P':      // ^FP = Numero di chiamate fatte dall'utente
  1342.             if (User != NULL)
  1343.                OutString ("%ld", User->TotalCalls);
  1344.             break;
  1345.          case 'Q':    // ^FR = Upload Files
  1346.             if (User != NULL)
  1347.                OutString ("%u", User->UploadFiles);
  1348.             break;
  1349.          case 'R':    // ^FR = Upload Bytes
  1350.             if (User != NULL)
  1351.                OutString ("%lu", User->UploadBytes);
  1352.             break;
  1353.          case 'S':    // ^FS = Download Files
  1354.             if (User != NULL)
  1355.                OutString ("%lu", User->DownloadFiles);
  1356.             break;
  1357.          case 'T':    // ^FT = Download Bytes
  1358.             if (User != NULL)
  1359.                OutString ("%lu", User->DownloadBytes);
  1360.             break;
  1361.          case 'U':      // ^FU = Time online, this call
  1362.             OutString ("%lu", (time (NULL) - StartCall) / 60L);
  1363.             break;
  1364.          case 'V':    // ^FV = Screen Length
  1365.             if (User != NULL)
  1366.                OutString ("%u", User->ScreenHeight);
  1367.             break;
  1368.          case 'W': {  // ^FW = Solo il nome dell'utente
  1369.             PSZ Temp, p;
  1370.  
  1371.             if (User != NULL) {
  1372.                if ((Temp = (PSZ)malloc (sizeof (User->Name))) != NULL) {
  1373.                   strcpy (Temp, User->Name);
  1374.                   if ((p = strtok (Temp, " ")) != NULL)
  1375.                      OutString ("%s", p);
  1376.                }
  1377.             }
  1378.             break;
  1379.          }
  1380.          case 'X':    // ^FX = Ansi YES/NO
  1381.             OutString ("%s", (Ansi == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1382.             break;
  1383.          case 'Y':    // ^FY = More? YES/NO
  1384.             OutString ("%s", (User->MorePrompt == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1385.             break;
  1386.          case 'Z':    // ^FZ = Screen Clear YES/NO
  1387.             OutString ("%s", (User->ScreenClear == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1388.             break;
  1389.  
  1390.          case CTRLA: {  // ^F^A = Show next quote
  1391.             FILE *fp;
  1392.             int fd;
  1393.             CHAR Temp[128], *p;
  1394.             ULONG Position = 0L;
  1395.  
  1396.             sprintf (Temp, "%squotes.dat", Cfg->SystemPath);
  1397.             if ((fd = sopen (Temp, O_RDONLY|O_BINARY, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  1398.                read (fd, &Position, sizeof (Position));
  1399.                close (fd);
  1400.             }
  1401.  
  1402.             if ((fp = OpenFile ("quotes", "rt")) != NULL) {
  1403.                if (Position >= filelength (fileno (fp)))
  1404.                   Position = 0L;
  1405.                fseek (fp, Position, SEEK_SET);
  1406.                while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  1407.                   if ((p = strchr (Temp, '\r')) != NULL)
  1408.                      *p = '\0';
  1409.                   if ((p = strchr (Temp, '\n')) != NULL)
  1410.                      *p = '\0';
  1411.                   if (Temp[0] == '\0')
  1412.                      break;
  1413.                   if (Temp[strlen (Temp) - 1] == '\n')
  1414.                      Temp[strlen (Temp) - 1] = '\0';
  1415.                   OutString ("%s\r\n", Temp);
  1416.                }
  1417.                Position = ftell (fp);
  1418.                fclose (fp);
  1419.             }
  1420.  
  1421.             sprintf (Temp, "%squotes.dat", Cfg->SystemPath);
  1422.             if ((fd = sopen (Temp, O_WRONLY|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  1423.                write (fd, &Position, sizeof (Position));
  1424.                close (fd);
  1425.             }
  1426.             break;
  1427.          }
  1428.          case CTRLB:    // ^F^B = Nome e cognome dell'utente
  1429.             if (User != NULL)
  1430.                OutString ("%s", User->Name);
  1431.             break;
  1432.          case CTRLC:    // ^F^C = City
  1433.             if (User != NULL)
  1434.                OutString ("%s", User->City);
  1435.             break;
  1436.          case CTRLD: {  // ^F^D = Today's date (dd mmm yy)
  1437.             time_t t;
  1438.             struct tm *ltm;
  1439.  
  1440.             t = time (NULL);
  1441.             ltm = localtime (&t);
  1442.             OutString ("%d %3.3s %d", ltm->tm_mday, Language->Months[ltm->tm_mon], ltm->tm_year + 1900);
  1443.             break;
  1444.          }
  1445.          case CTRLE:    // ^F^E = Numero di chiamate fatte dall'utente
  1446.             if (User != NULL)
  1447.                OutString ("%ld", User->TotalCalls);
  1448.             break;
  1449.          case CTRLF: {  // ^F^F = Solo il nome dell'utente
  1450.             PSZ Temp, p;
  1451.  
  1452.             if (User != NULL) {
  1453.                if ((Temp = (PSZ)malloc (sizeof (User->Name))) != NULL) {
  1454.                   strcpy (Temp, User->Name);
  1455.                   if ((p = strtok (Temp, " ")) != NULL)
  1456.                      OutString ("%s", p);
  1457.                }
  1458.             }
  1459.             break;
  1460.          }
  1461.          case CTRLG:    // ^F^G = Pausa di 1 secondo
  1462.             if (Com != NULL)
  1463.                Com->UnbufferBytes ();
  1464.             if (Snoop != NULL)
  1465.                Snoop->UnbufferBytes ();
  1466.             Pause (100);
  1467.             break;
  1468.          case CTRLK:    // ^F^K = Time of previous calls today
  1469.             if (User != NULL)
  1470.                OutString ("%lu", User->TodayTime);
  1471.             break;
  1472.          case CTRLL:    // ^F^L = Time online, this call
  1473.             OutString ("%lu", (time (NULL) - StartCall) / 60L);
  1474.             break;
  1475.          case CTRLN:    // ^F^N = Hangup now
  1476.             Hangup = TRUE;
  1477.             break;
  1478.          case CTRLO:    // ^F^O = Tempo rimasto
  1479.             OutString ("%lu", TimeRemain ());
  1480.             break;
  1481.          case CTRLP: {  // ^F^P = Time off (hh:mm:ss)
  1482.             time_t t;
  1483.             struct tm *ltm;
  1484.  
  1485.             t = time (NULL) + TimeRemain (TRUE);
  1486.             ltm = localtime (&t);
  1487.             OutString ("%2d:%02d:%02d", ltm->tm_hour, ltm->tm_min, ltm->tm_sec);
  1488.             break;
  1489.          }
  1490.          case CTRLQ: {  // ^F^Q = Total calls
  1491.             class TStatistics *Stats;
  1492.  
  1493.             if ((Stats = new TStatistics) != NULL) {
  1494.                Stats->Read (Task);
  1495.                OutString ("%lu", Stats->TotalCalls);
  1496.                delete Stats;
  1497.             }
  1498.             break;
  1499.          }
  1500.          case CTRLR:    // ^F^R = Net download (download - upload)
  1501.             if (User != NULL)
  1502.                OutString ("%lu", User->DownloadBytes - User->UploadBytes);
  1503.             break;
  1504.          case CTRLS:    // ^F^S = User's signature
  1505.             if (User != NULL)
  1506.                OutString ("%s", User->Signature);
  1507.             break;
  1508.          case CTRLT: {  // ^F^T = Current time (hh:mm:ss)
  1509.             time_t t;
  1510.             struct tm *ltm;
  1511.  
  1512.             t = time (NULL);
  1513.             ltm = localtime (&t);
  1514.             OutString ("%2d:%02d:%02d", ltm->tm_hour, ltm->tm_min, ltm->tm_sec);
  1515.             break;
  1516.          }
  1517.          case CTRLU:    // ^F^U = Answers are required
  1518.             Required = TRUE;
  1519.             break;
  1520.          case CTRLV:    // ^F^V = Answers are not required
  1521.             Required = FALSE;
  1522.             break;
  1523.          case CTRLW:    // ^F^W = Upload KBytes
  1524.             if (User != NULL)
  1525.                OutString ("%lu", (User->UploadBytes + 1023L) / 1024L);
  1526.             break;
  1527.          case CTRLX:    // ^F^X = Download KBytes
  1528.             if (User != NULL)
  1529.                OutString ("%lu", (User->DownloadBytes + 1023L) / 1024L);
  1530.             break;
  1531.          case CTRLY:    // ^F^Y = DL/UL Bytes Ratio
  1532.             if (User != NULL) {
  1533.                if (User->UploadBytes != 0)
  1534.                   OutString ("%lu:1", User->DownloadBytes / User->UploadBytes);
  1535.                else
  1536.                   OutString ("%lu:0", (User->DownloadBytes + 1023L) / 1024L);
  1537.             }
  1538.             break;
  1539.  
  1540.          case '0':    // ^F0 = Full Screen Editor YES/NO
  1541.             OutString ("%s", (User->FullEd == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1542.             break;
  1543.          case '2':    // ^F2 = User's age
  1544.             if (User != NULL)
  1545.                OutString ("%u", User->Age ());
  1546.             break;
  1547.          case '3':    // ^F3 = Hotkey YES/NO
  1548.             OutString ("%s", (HotKey == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1549.             break;
  1550.          case '5':    // ^F5 = Birthdate
  1551.             OutString ("%d-%02d-%04d", User->BirthDay, User->BirthMonth, User->BirthYear);
  1552.             break;
  1553.          case '6':    // ^F6 = Mailcheck YES/NO
  1554.             OutString ("%s", (User->MailCheck == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1555.             break;
  1556.          case '8':    // ^F8 = Avatar YES/NO
  1557.             OutString ("%s", (Avatar == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1558.             break;
  1559.          case '9':      // ^F9  = DL/UL Files Ratio
  1560.             if (User != NULL) {
  1561.                if (User->UploadFiles != 0)
  1562.                   OutString ("%lu:1", User->DownloadFiles / User->UploadFiles);
  1563.                else
  1564.                   OutString ("%lu:0", User->DownloadFiles);
  1565.             }
  1566.             break;
  1567.  
  1568.          case '[': {    // ^F[ = Remaining download for today
  1569.             class TLimits *Limits;
  1570.  
  1571.             if ((Limits = new TLimits (Cfg->SystemPath)) != NULL) {
  1572.                Limits->Read (User->LimitClass);
  1573.                if (CarrierSpeed <= 2400 && Limits->DownloadAt2400 != 0)
  1574.                   OutString ("%lu", (Limits->DownloadAt2400 >= User->DownloadBytes) ? Limits->DownloadAt2400 - User->DownloadBytes : 0L);
  1575.                else if (CarrierSpeed > 2400 && CarrierSpeed <= 9600 && Limits->DownloadAt9600 != 0)
  1576.                   OutString ("%lu", (Limits->DownloadAt9600 >= User->DownloadBytes) ? Limits->DownloadAt9600 - User->DownloadBytes : 0L);
  1577.                else if (CarrierSpeed > 9600 && CarrierSpeed <= 14400 && Limits->DownloadAt14400 != 0)
  1578.                   OutString ("%lu", (Limits->DownloadAt14400 >= User->DownloadBytes) ? Limits->DownloadAt14400 - User->DownloadBytes : 0L);
  1579.                else if (CarrierSpeed > 14400 && CarrierSpeed <= 28800 && Limits->DownloadAt28800 != 0)
  1580.                   OutString ("%lu", (Limits->DownloadAt28800 >= User->DownloadBytes) ? Limits->DownloadAt28800 - User->DownloadBytes : 0L);
  1581.                else if (CarrierSpeed > 28800 && CarrierSpeed <= 33600 && Limits->DownloadAt33600 != 0)
  1582.                   OutString ("%lu", (Limits->DownloadAt33600 >= User->DownloadBytes) ? Limits->DownloadAt33600 - User->DownloadBytes : 0L);
  1583.                else
  1584.                   OutString ("%lu", (Limits->DownloadLimit >= User->DownloadBytes) ? Limits->DownloadLimit - User->DownloadBytes : 0L);
  1585.                delete Limits;
  1586.             }
  1587.             break;
  1588.          }
  1589.          case '\\':     // ^F\ = Language Name
  1590.             if (Language != NULL)
  1591.                OutString ("%s", Language->Comment);
  1592.             break;
  1593.          case ';':      // ^F; = Full Screen Reader YES/NO
  1594.             OutString ("%s", (User->FullReader == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1595.             break;
  1596.          case '?':      // ^F? = Video mode
  1597.             if (Rip == TRUE)
  1598.                OutString ("%s", "RIP   ");
  1599.             else if (Avatar == TRUE)
  1600.                OutString ("%s", "AVATAR");
  1601.             else if (Ansi == TRUE)
  1602.                OutString ("%s", "ANSI  ");
  1603.             else
  1604.                OutString ("%s", "TTY   ");
  1605.             break;
  1606.          case ':':      // ^F: = Fullscreen listings
  1607.             OutString ("%s", (User->FullScreen == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1608.             break;
  1609.          case '!':      // ^F! = Color YES/NO
  1610.             OutString ("%s", (Color == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1611.             break;
  1612.          case '=':      // ^F= = Rip graphics YES/NO
  1613.             OutString ("%s", (Rip == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1614.             break;
  1615.          case '$':      // ^F$ = In User list YES/NO
  1616.             OutString ("%s", (User->InUserList == TRUE) ? Language->Text (LNG_YES) : Language->Text (LNG_NO));
  1617.             break;
  1618.       }
  1619.    }
  1620. }
  1621.  
  1622. VOID TEmbedded::ProcessControlK (VOID)
  1623. {
  1624.    SHORT c;
  1625.  
  1626.    if ((c = GetNextChar ()) != EOF) {
  1627.       switch (c) {
  1628.          case 'A': {    // ^KA = Total calls
  1629.             class TStatistics *Stats;
  1630.  
  1631.             if ((Stats = new TStatistics) != NULL) {
  1632.                Stats->Read (Task);
  1633.                OutString ("%lu", Stats->TotalCalls);
  1634.                delete Stats;
  1635.             }
  1636.             break;
  1637.          }
  1638.          case 'B': {    // ^KB = Name of the last user on this line
  1639.             class TStatistics *Stats;
  1640.  
  1641.             if ((Stats = new TStatistics) != NULL) {
  1642.                Stats->Read (Task);
  1643.                OutString ("%s", Stats->User);
  1644.                delete Stats;
  1645.             }
  1646.             break;
  1647.          }
  1648.          case 'D':      // ^KD = First message in area
  1649.             if (MsgArea != NULL)
  1650.                OutString ("%lu", MsgArea->FirstMessage);
  1651.             break;
  1652.          case 'E':      // ^KE = Last message in area
  1653.             if (MsgArea != NULL)
  1654.                OutString ("%lu", MsgArea->LastMessage);
  1655.             break;
  1656.          case 'I': {    // ^KI = Current time (hh:mm:ss)
  1657.             time_t t;
  1658.             struct tm *ltm;
  1659.  
  1660.             t = time (NULL);
  1661.             ltm = localtime (&t);
  1662.             OutString ("%2d:%02d:%02d", ltm->tm_hour, ltm->tm_min, ltm->tm_sec);
  1663.             break;
  1664.          }
  1665.          case 'J': {    // ^KJ = Today's date (dd mmm yy)
  1666.             time_t t;
  1667.             struct tm *ltm;
  1668.  
  1669.             t = time (NULL);
  1670.             ltm = localtime (&t);
  1671.             OutString ("%d %3.3s %d", ltm->tm_mday, Language->Months[ltm->tm_mon], ltm->tm_year + 1900);
  1672.             break;
  1673.          }
  1674.          case 'K':      // ^KK = Time online, this call
  1675.             OutString ("%lu", (time (NULL) - StartCall) / 60L);
  1676.             break;
  1677.          case 'Q': {    // ^KQ = Timelimit per call
  1678.             class TLimits *Limits;
  1679.  
  1680.             if ((Limits = new TLimits (Cfg->SystemPath)) != NULL) {
  1681.                Limits->Read (User->LimitClass);
  1682.                OutString ("%u", Limits->CallTimeLimit);
  1683.                delete Limits;
  1684.             }
  1685.             break;
  1686.          }
  1687.          case 'T': {    // ^KT = Download limit per day
  1688.             class TLimits *Limits;
  1689.  
  1690.             if ((Limits = new TLimits (Cfg->SystemPath)) != NULL) {
  1691.                Limits->Read (User->LimitClass);
  1692.                if (CarrierSpeed <= 2400 && Limits->DownloadAt2400 != 0)
  1693.                   OutString ("%lu", Limits->DownloadAt2400);
  1694.                else if (CarrierSpeed > 2400 && CarrierSpeed <= 9600 && Limits->DownloadAt9600 != 0)
  1695.                   OutString ("%lu", Limits->DownloadAt9600);
  1696.                else if (CarrierSpeed > 9600 && CarrierSpeed <= 14400 && Limits->DownloadAt14400 != 0)
  1697.                   OutString ("%lu", Limits->DownloadAt14400);
  1698.                else if (CarrierSpeed > 14400 && CarrierSpeed <= 28800 && Limits->DownloadAt28800 != 0)
  1699.                   OutString ("%lu", Limits->DownloadAt28800);
  1700.                else if (CarrierSpeed > 28800 && CarrierSpeed <= 33600 && Limits->DownloadAt33600 != 0)
  1701.                   OutString ("%lu", Limits->DownloadAt33600);
  1702.                else
  1703.                   OutString ("%lu", Limits->DownloadLimit);
  1704.                delete Limits;
  1705.             }
  1706.             break;
  1707.          }
  1708.          case 'W':      // ^KW = Numero di linea
  1709.             OutString ("%u", Task);
  1710.             break;
  1711.          case 'X':      // ^KX = Hangup now
  1712.             Hangup = TRUE;
  1713.             break;
  1714.          case 'Y':      // ^KY = Title of current message area
  1715.             if (MsgArea != NULL)
  1716.                OutString ("%s", MsgArea->Display);
  1717.             break;
  1718.          case 'Z':      // ^KZ = Title of current file area
  1719.             if (FileArea != NULL)
  1720.                OutString ("%s", FileArea->Display);
  1721.             break;
  1722.  
  1723.          case '0':      // ^K0 = Time remain
  1724.             OutString ("%u", TimeRemain ());
  1725.             break;
  1726.          case '1':      // ^K1 = Name of current message area
  1727.             if (MsgArea != NULL)
  1728.                OutString ("%s", MsgArea->Key);
  1729.             break;
  1730.          case '2':      // ^K2 = Name of current file area
  1731.             if (FileArea != NULL)
  1732.                OutString ("%s", FileArea->Key);
  1733.             break;
  1734.          case '7':      // ^K7 = Number of tagged files
  1735.             if (User != NULL) {
  1736.                if (User->FileTag != NULL)
  1737.                   OutString ("%u", User->FileTag->TotalFiles);
  1738.             }
  1739.             break;
  1740.          case '8':      // ^K8 = Number of files in current area
  1741.             if (FileArea != NULL)
  1742.                OutString ("%lu", FileArea->ActiveFiles);
  1743.             break;
  1744.          case '9':      // ^K9 = Number of messages in current area
  1745.             if (MsgArea != NULL)
  1746.                OutString ("%lu", MsgArea->ActiveMsgs);
  1747.             break;
  1748.          case '[': {    // ^K[ = Remaining download for today
  1749.             class TLimits *Limits;
  1750.  
  1751.             if ((Limits = new TLimits (Cfg->SystemPath)) != NULL) {
  1752.                Limits->Read (User->LimitClass);
  1753.                if (CarrierSpeed <= 2400 && Limits->DownloadAt2400 != 0)
  1754.                   OutString ("%lu", (Limits->DownloadAt2400 >= User->DownloadBytes) ? Limits->DownloadAt2400 - User->DownloadBytes : 0L);
  1755.                else if (CarrierSpeed > 2400 && CarrierSpeed <= 9600 && Limits->DownloadAt9600 != 0)
  1756.                   OutString ("%lu", (Limits->DownloadAt9600 >= User->DownloadBytes) ? Limits->DownloadAt9600 - User->DownloadBytes : 0L);
  1757.                else if (CarrierSpeed > 9600 && CarrierSpeed <= 14400 && Limits->DownloadAt14400 != 0)
  1758.                   OutString ("%lu", (Limits->DownloadAt14400 >= User->DownloadBytes) ? Limits->DownloadAt14400 - User->DownloadBytes : 0L);
  1759.                else if (CarrierSpeed > 14400 && CarrierSpeed <= 28800 && Limits->DownloadAt28800 != 0)
  1760.                   OutString ("%lu", (Limits->DownloadAt28800 >= User->DownloadBytes) ? Limits->DownloadAt28800 - User->DownloadBytes : 0L);
  1761.                else if (CarrierSpeed > 28800 && CarrierSpeed <= 33600 && Limits->DownloadAt33600 != 0)
  1762.                   OutString ("%lu", (Limits->DownloadAt33600 >= User->DownloadBytes) ? Limits->DownloadAt33600 - User->DownloadBytes : 0L);
  1763.                else
  1764.                   OutString ("%lu", (Limits->DownloadLimit >= User->DownloadBytes) ? Limits->DownloadLimit - User->DownloadBytes : 0L);
  1765.                delete Limits;
  1766.             }
  1767.             break;
  1768.          }
  1769.       }
  1770.    }
  1771. }
  1772.  
  1773. VOID TEmbedded::ProcessControlO (VOID)
  1774. {
  1775.    SHORT c;
  1776.    CHAR *p;
  1777.  
  1778.    if ((c = GetNextChar ()) != EOF) {
  1779.       switch (c) {
  1780.          case 'C': {    // ^OC[cmd] = Run external program
  1781.             CHAR File[64], *p;
  1782.  
  1783.             p = File;
  1784.             while ((c = GetNextChar ()) != EOF) {
  1785.                if (c <= ' ')
  1786.                   break;
  1787.                *p++ = (CHAR)c;
  1788.             }
  1789.             *p = '\0';
  1790.  
  1791.             if (c == '\r' && PeekNextChar () == '\n')
  1792.                GetNextChar ();
  1793.  
  1794.             RunExternal (File);
  1795.             break;
  1796.          }
  1797.          case 'E':      // ^OE = Display only if ANSI/Avatar enabled
  1798.             if (Ansi == FALSE && Avatar == FALSE) {
  1799.                while ((c = GetNextChar ()) != EOF) {
  1800.                   if (c == CTRLO) {
  1801.                      if ((c = GetNextChar ()) == 'e')
  1802.                         break;
  1803.                   }
  1804.                }
  1805.             }
  1806.             break;
  1807.          case 'e':      // ^Oe = End of ANSI/Avatar only text
  1808.             break;
  1809.          case 'F':      // ^OF = Set On Exit filename
  1810.             p = OnExit;
  1811.             while ((c = GetNextChar ()) != EOF) {
  1812.                if (c <= ' ')
  1813.                   break;
  1814.                *p++ = (CHAR)c;
  1815.             }
  1816.             *p = '\0';
  1817.             if (c == '\r' && PeekNextChar () == '\n')
  1818.                GetNextChar ();
  1819.             break;
  1820.          case 'G':      // ^OG = Display only if RIPscript enabled
  1821.             if (Rip == FALSE) {
  1822.                while ((c = GetNextChar ()) != EOF) {
  1823.                   if (c == CTRLO) {
  1824.                      if ((c = GetNextChar ()) == 'I')
  1825.                         break;
  1826.                   }
  1827.                }
  1828.             }
  1829.             break;
  1830.          case 'I':      // ^OI = End of Rip only text
  1831.             break;
  1832.          case 'L': {    // ^OL[file] = Change language
  1833.             CHAR File[64], *p;
  1834.  
  1835.             p = File;
  1836.             while ((c = GetNextChar ()) != EOF) {
  1837.                if (c <= ' ')
  1838.                   break;
  1839.                *p++ = (CHAR)c;
  1840.             }
  1841.             *p = '\0';
  1842.  
  1843.             if (c == '\r' && PeekNextChar () == '\n')
  1844.                GetNextChar ();
  1845.  
  1846.             Language->Load (File);
  1847.             strcpy (AltPath, Language->TextFiles);
  1848.             break;
  1849.          }
  1850.          case 'M': {    // ^OM[comment] = Memorizza l'ultima risposta al ^OR
  1851.             CHAR Comment[64], *p;
  1852.  
  1853.             p = Comment;
  1854.             do {
  1855.                if ((c = GetNextChar ()) > ' ')
  1856.                   *p++ = (CHAR)c;
  1857.             } while (c != EOF && c > ' ');
  1858.             *p = '\0';
  1859.             if (c == 0x0D && PeekNextChar () == 0x0A)
  1860.                GetNextChar ();
  1861.  
  1862.             if (AnswerFile != NULL)
  1863.                fprintf (AnswerFile, "  %s: %c\n", Comment, Response);
  1864.             break;
  1865.          }
  1866.          case 'N': {    // ^ON[comment] = Attende una stringa dall'utente e la memorizza
  1867.             CHAR Comment[64], Answer[64], *p;
  1868.  
  1869.             p = Comment;
  1870.             do {
  1871.                if ((c = GetNextChar ()) > ' ')
  1872.                   *p++ = (CHAR)c;
  1873.             } while (c != EOF && c > ' ');
  1874.             *p = '\0';
  1875.             if (c == 0x0D && PeekNextChar () == 0x0A)
  1876.                GetNextChar ();
  1877.  
  1878.             do {
  1879.                GetString (Answer, (USHORT)(sizeof (Answer) - 1), 0);
  1880.             } while (AbortSession () == FALSE && Answer[0] == '\0' && Required == TRUE);
  1881.             if (AnswerFile != NULL)
  1882.                fprintf (AnswerFile, "  %s: %s\n", Comment, Answer);
  1883.             break;
  1884.          }
  1885.          case 'O': {    // ^OO[file] = Open answer file
  1886.             CHAR File[64], *p;
  1887.  
  1888.             p = File;
  1889.             while ((c = GetNextChar ()) != EOF) {
  1890.                if (c <= ' ')
  1891.                   break;
  1892.                *p++ = (CHAR)c;
  1893.             }
  1894.             *p = '\0';
  1895.             if (c == '\r' && PeekNextChar () == '\n')
  1896.                GetNextChar ();
  1897.  
  1898.             if (AnswerFile != NULL)
  1899.                fclose (AnswerFile);
  1900.             if ((AnswerFile = fopen (File, "at")) != NULL) {
  1901.                if (Log != NULL)
  1902.                   Log->Write ("+Answer file %s opened", File);
  1903.             }
  1904.             else {
  1905.                if (Log != NULL)
  1906.                   Log->Write ("!Failed to open answer file %s", File);
  1907.             }
  1908.             break;
  1909.          }
  1910.          case 'P':      // ^OP = Write user's data to answer file
  1911.             if (AnswerFile != NULL)
  1912.                fprintf (AnswerFile, "* %s\t%s\t%s\t\n", User->Name, User->City, "");
  1913.             break;
  1914.          case 'Q':      // ^OQ = Fine immediata del file
  1915.             Stop = TRUE;
  1916.             break;
  1917.          case 'R': {    // ^OR = Attende un comando dall'utente
  1918.             USHORT Good = FALSE;
  1919.             CHAR Valid[128], *p;
  1920.  
  1921.             p = Valid;
  1922.             do {
  1923.                if ((c = GetNextChar ()) > ' ')
  1924.                   *p++ = (CHAR)c;
  1925.             } while (c != EOF && c > ' ');
  1926.             if (c == 0x0D && PeekNextChar () == 0x0A)
  1927.                GetNextChar ();
  1928.             *p = '\0';
  1929.             strupr (Valid);
  1930.  
  1931.             while (AbortSession () == FALSE && Good == FALSE) {
  1932.                GetString (Temp, 1, INP_HOTKEY|INP_NOCRLF);
  1933.                if ((Response = (CHAR)toupper (Temp[0])) == '\0')
  1934.                   Response = '|';
  1935.                if (strchr (Valid, Response) != NULL)
  1936.                   Good = TRUE;
  1937.                else if (Response != '|')
  1938.                   OutString ("\x08 \x08");
  1939.             }
  1940.  
  1941.             OutString ("\n");
  1942.             break;
  1943.          }
  1944.          case 'S': {    // ^OS = Passa il controllo ad un'altro file
  1945.             p = Temp;
  1946.             do {
  1947.                if ((c = GetNextChar ()) > ' ')
  1948.                   *p++ = (CHAR)c;
  1949.             } while (c != EOF && c > ' ');
  1950.             if (c == 0x0D && PeekNextChar () == 0x0A)
  1951.                GetNextChar ();
  1952.             *p = '\0';
  1953.  
  1954.             if (Temp[0] != '\0') {
  1955.                if (fp != NULL)
  1956.                   fclose (fp);
  1957.                fp = OpenFile (Temp);
  1958.                Line = 1;
  1959.             }
  1960.             break;
  1961.          }
  1962.          case 'T':      // ^OT = Salta all'inizio del file
  1963.             if (fp != NULL)
  1964.                fseek (fp, 0L, SEEK_SET);
  1965.             break;
  1966.          case 'U':      // ^OU[char] = La riga prosegue se l'utente ha risposto [char]
  1967.             if ((c = GetNextChar ()) != EOF) {
  1968.                if (toupper (c) != toupper (Response))
  1969.                   do {
  1970.                      if ((c = GetNextChar ()) == 0x0D) {
  1971.                         if (PeekNextChar () == 0x0A)
  1972.                            GetNextChar ();
  1973.                         else
  1974.                            c = 0;
  1975.                      }
  1976.                   } while (c != EOF && c != 0x0D);
  1977.             }
  1978.             break;
  1979.          case 'V': {    // ^OV[pos] = Si posiziona a [pos] nel file
  1980.             ULONG Pos = 0L;
  1981.  
  1982.             while (isdigit (PeekNextChar ())) {
  1983.                c = GetNextChar ();
  1984.                Pos *= 10L;
  1985.                Pos += c - 0x30;
  1986.             }
  1987.  
  1988.             if (PeekNextChar () == 0x0D) {
  1989.                GetNextChar ();
  1990.                if (PeekNextChar () == 0x0A)
  1991.                   GetNextChar ();
  1992.             }
  1993.  
  1994.             if (fp != NULL)
  1995.                fseek (fp, Pos, SEEK_SET);
  1996.             break;
  1997.          }
  1998.       }
  1999.    }
  2000. }
  2001.  
  2002. VOID TEmbedded::ProcessControlP (VOID)
  2003. {
  2004.    SHORT c;
  2005.  
  2006.    if ((c = GetNextChar ()) != EOF) {
  2007.       switch (c) {
  2008.          case 'L':
  2009.             do {
  2010.                if ((c = GetNextChar ()) == 0x0D) {
  2011.                   if (PeekNextChar () == 0x0A)
  2012.                      GetNextChar ();
  2013.                   else
  2014.                      c = 0;
  2015.                }
  2016.             } while (c != EOF && c != 0x0D);
  2017.             break;
  2018.       }
  2019.    }
  2020. }
  2021.  
  2022. VOID TEmbedded::ProcessControlW (VOID)
  2023. {
  2024.    SHORT c;
  2025.    CHAR Temp[128], *p;
  2026.  
  2027.    if ((c = GetNextChar ()) != EOF) {
  2028.       switch (c) {
  2029.          case 'b':      // ^Wb[n] = If Task == [n]
  2030.             p = Temp;
  2031.             while ((c = GetNextChar ()) != EOF) {
  2032.                if (c <= ' ')
  2033.                   break;
  2034.                *p++ = (CHAR)c;
  2035.             }
  2036.             *p = '\0';
  2037.  
  2038.             if (c == '\r' && PeekNextChar () == '\n')
  2039.                GetNextChar ();
  2040.  
  2041.             if (Task != atoi (Temp))
  2042.                do {
  2043.                   if ((c = GetNextChar ()) == 0x0D) {
  2044.                      if (PeekNextChar () == 0x0A)
  2045.                         GetNextChar ();
  2046.                      else
  2047.                         c = 0;
  2048.                   }
  2049.                } while (c != EOF && c != 0x0D);
  2050.             break;
  2051.          case 'E':
  2052.             StopNested = TRUE;
  2053.             break;
  2054.          case 'G':
  2055.             switch (c = GetNextChar ()) {
  2056.                case 'A':      // ^W^FA = Name of current file area
  2057.                   if (FileArea != NULL)
  2058.                      OutString ("%s", FileArea->Key);
  2059.                   break;
  2060.                case 'N':      // ^W^FN = Description of current file area
  2061.                   if (FileArea != NULL)
  2062.                      OutString ("%s", FileArea->Display);
  2063.                   break;
  2064.             }
  2065.             break;
  2066.          case 'j':
  2067.             switch (c = GetNextChar ()) {
  2068.                case 'N':      // ^WjN = Node number
  2069.                   OutString ("%d", Task);
  2070.                   break;
  2071.             }
  2072.             break;
  2073.          case 'L': {    // ^WL = Link con un'altro file
  2074.             FILE *SaveFP;
  2075.             CHAR SaveResponse;
  2076.  
  2077.             p = Temp;
  2078.             do {
  2079.                if ((c = GetNextChar ()) > ' ')
  2080.                   *p++ = (CHAR)c;
  2081.             } while (c != EOF && c > ' ');
  2082.             if (c == 0x0D && PeekNextChar () == 0x0A)
  2083.                GetNextChar ();
  2084.             *p = '\0';
  2085.  
  2086.             if (Temp[0] != '\0') {
  2087.                strlwr (Temp);
  2088.  
  2089.                SaveFP = fp;
  2090.                SaveResponse = Response;
  2091.                if (strstr (Temp, ".cmd") == NULL) {
  2092.                   Nested++;
  2093.                   DisplayFile (Temp);
  2094.                   if (--Nested == 0) {
  2095.                      if (StopNested == TRUE)
  2096.                         Stop = TRUE;
  2097.                      StopNested = FALSE;
  2098.                   }
  2099.                }
  2100. #if defined(__OS2__)
  2101.                else {
  2102.                   fp = NULL;
  2103.                   CallRexx (this, Temp);
  2104.                }
  2105. #endif
  2106.  
  2107.                Response = SaveResponse;
  2108.                fp = SaveFP;
  2109.             }
  2110.             break;
  2111.          }
  2112.          case 'P':
  2113.             if (User != NULL)
  2114.                OutString ("%s", User->DayPhone);
  2115.             break;
  2116.          case 'R':
  2117.             if (User != NULL)
  2118.                OutString ("%s", User->RealName);
  2119.             break;
  2120.          case 'W':      // ^WW[comment] = Scrive la stringa nell'answer file
  2121.             p = Temp;
  2122.             do {
  2123.                if ((c = GetNextChar ()) > ' ')
  2124.                   *p++ = (CHAR)c;
  2125.             } while (c != EOF && c > ' ');
  2126.             *p = '\0';
  2127.             if (c == 0x0D && PeekNextChar () == 0x0A)
  2128.                GetNextChar ();
  2129.  
  2130.             if (AnswerFile != NULL)
  2131.                fprintf (AnswerFile, "  %s\n", Temp);
  2132.             break;
  2133.  
  2134.          case CTRLA: {  // ^W^A = User's last call date (dd mmm yy)
  2135.             struct tm *ltm;
  2136.  
  2137.             if (User != NULL) {
  2138.                ltm = localtime ((time_t *)&User->LastCall);
  2139.                OutString ("%d %3.3s %d", ltm->tm_mday, Language->Months[ltm->tm_mon], ltm->tm_year + 1900);
  2140.             }
  2141.             break;
  2142.          }
  2143.          case CTRLC:    // ^W^C = System Name
  2144.             if (Cfg != NULL)
  2145.                OutString ("%s", Cfg->SystemName);
  2146.             break;
  2147.          case CTRLD:    // ^W^D = Sysop Name
  2148.             if (Cfg != NULL)
  2149.                OutString ("%s", Cfg->SysopName);
  2150.             break;
  2151.          case CTRLF:
  2152.             switch (c = GetNextChar ()) {
  2153.                case 'A':      // ^W^FA = Name of current file area
  2154.                   if (FileArea != NULL)
  2155.                      OutString ("%s", FileArea->Key);
  2156.                   break;
  2157.                case 'N':      // ^W^FN = Description of current file area
  2158.                   if (FileArea != NULL)
  2159.                      OutString ("%s", FileArea->Display);
  2160.                   break;
  2161.             }
  2162.             break;
  2163.          case CTRLM: {
  2164.             switch (c = GetNextChar ()) {
  2165.                case '#':      // ^W^M# = Number of messages in current area
  2166.                   if (MsgArea != NULL)
  2167.                      OutString ("%lu", MsgArea->ActiveMsgs);
  2168.                   break;
  2169.                case 'A':      // ^W^MA = Name of current message area
  2170.                   if (MsgArea != NULL)
  2171.                      OutString ("%s", MsgArea->Key);
  2172.                   break;
  2173.                case 'L':      // ^W^MH = Highest message in area
  2174.                   if (MsgArea != NULL)
  2175.                      OutString ("%lu", MsgArea->LastMessage);
  2176.                   break;
  2177.                case 'N':      // ^W^MN = Description of current message area
  2178.                   if (MsgArea != NULL)
  2179.                      OutString ("%s", MsgArea->Display);
  2180.                   break;
  2181.             }
  2182.             break;
  2183.          }
  2184.       }
  2185.    }
  2186. }
  2187.  
  2188. VOID TEmbedded::RunExternal (PSZ Command)
  2189. {
  2190.    FILE *fp;
  2191.    USHORT DropFile;
  2192.    CHAR Cmd[128], Temp[64], *p, *a;
  2193.    struct tm *ltm;
  2194.  
  2195.    DropFile = NO_DROPFILE;
  2196.  
  2197.    a = Cmd;
  2198.    p = Command;
  2199.    do {
  2200.       if (*p == '%') {
  2201.          p++;
  2202.          switch (*p) {
  2203.             case '%':
  2204.                *a++ = '%';
  2205.                break;
  2206.             case 'b':      // Baud rate
  2207.                sprintf (a, "%lu", Cfg->Speed);
  2208.                a += strlen (a);
  2209.                break;
  2210.             case 'c':
  2211.                strcpy (a, User->City);
  2212.                a += strlen (a);
  2213.                break;
  2214.             case 'K':      // Task number (hex)
  2215.                sprintf (a, "%02x", Task);
  2216.                a += strlen (a);
  2217.                break;
  2218.             case 'k':      // Task number
  2219.                sprintf (a, "%u", Task);
  2220.                a += strlen (a);
  2221.                break;
  2222.             case 'L':      // Com port number and baud rate (Opus style)
  2223.                sprintf (a, "-p%d -b%u", atoi (&Cfg->Device[3]), Cfg->Speed);
  2224.                a += strlen (a);
  2225.                break;
  2226.             case 'p': {    // Com port handle
  2227. #if defined(__OS2__) || defined(__NT__)
  2228.                class TSerial *Serial = (class TSerial *)Com;
  2229.  
  2230.                sprintf (a, "%lu", Serial->hFile);
  2231. #else
  2232.                sprintf (a, "%d", atoi (&Cfg->Device[3]));
  2233. #endif
  2234.                a += strlen (a);
  2235.                break;
  2236.             }
  2237.             case 'P':      // Com port number
  2238.                sprintf (a, "%d", atoi (&Cfg->Device[3]));
  2239.                a += strlen (a);
  2240.                break;
  2241.             case 'T':      // Time left (seconds)
  2242.                sprintf (a, "%lu", TimeRemain (TRUE));
  2243.                a += strlen (a);
  2244.                break;
  2245.             case 't':      // Time left (minutes)
  2246.                sprintf (a, "%lu", TimeRemain ());
  2247.                a += strlen (a);
  2248.                break;
  2249.             case 'U':
  2250.                *a++ = '_';
  2251.                break;
  2252.             case 'W':      // Speed
  2253.                sprintf (a, "%lu", Cfg->Speed);
  2254.                a += strlen (a);
  2255.                break;
  2256.             case 'Z':      // User name (uppercase)
  2257.                strcpy (a, User->Name);
  2258.                a += strlen (strupr (a));
  2259.                break;
  2260.             default:
  2261.                *a++ = '%';
  2262.                *a++ = *p;
  2263.                break;
  2264.          }
  2265.       }
  2266.       else if (*p == '*') {
  2267.          p++;
  2268.          switch (toupper (*p)) {
  2269.             case '*':
  2270.                *a++ = '*';
  2271.                break;
  2272.             case 'B':      // Baud rate
  2273.                sprintf (a, "%lu", Cfg->Speed);
  2274.                a += strlen (a);
  2275.                break;
  2276.             case 'C':      // Location of the command processor
  2277.                if (getenv ("COMSPEC") != NULL) {
  2278.                   strcpy (a, getenv ("COMSPEC"));
  2279.                   a += strlen (a);
  2280.                }
  2281.                break;
  2282.             case 'D':      // Dropfile type
  2283.                p++;
  2284.                if (*p == 'D')
  2285.                   DropFile = DOOR_SYS;
  2286.                else if (*p == 'F')
  2287.                   DropFile = DOORX_SYS;
  2288.                else if (*p == 'I')
  2289.                   DropFile = DORINFO1_DEF;
  2290.                else if (*p == 'J')
  2291.                   DropFile = DORINFOX_DEF;
  2292.                break;
  2293.             case 'N':      // Task number
  2294.                sprintf (a, "%u", Task);
  2295.                a += strlen (a);
  2296.                break;
  2297.             case 'P':      // Com port number
  2298.                sprintf (a, "%d", atoi (&Cfg->Device[3]));
  2299.                a += strlen (a);
  2300.                break;
  2301.             case 'T':      // Time left
  2302.                sprintf (a, "%lu", TimeRemain ());
  2303.                a += strlen (a);
  2304.                break;
  2305.             default:
  2306.                *a++ = '*';
  2307.                *a++ = *p;
  2308.                break;
  2309.          }
  2310.       }
  2311.       else
  2312.          *a++ = *p;
  2313.    } while (*p++ != '\0');
  2314.  
  2315.    switch (DropFile) {
  2316.       case DOOR_SYS:
  2317.       case DOORX_SYS:
  2318.          if (DropFile == DOOR_SYS)
  2319.             sprintf (Temp, "%sdoor.sys", Cfg->SystemPath);
  2320.          else
  2321.             sprintf (Temp, "%sdoor%u.sys", Cfg->SystemPath, Task);
  2322.  
  2323.          Log->Write (":Creating %s", Temp);
  2324.          if ((fp = fopen (Temp, "wt")) != NULL) {
  2325.             fprintf (fp, "%s\n", Cfg->Device);
  2326.             fprintf (fp, "%lu\n", Cfg->Speed);
  2327.             fprintf (fp, "8\n");
  2328.             fprintf (fp, "%u\n", Task);
  2329.             fprintf (fp, "%lu\n", Cfg->Speed);
  2330.             fprintf (fp, "Y\n");
  2331.             fprintf (fp, "Y\n");
  2332.             fprintf (fp, "Y\n");
  2333.             fprintf (fp, "Y\n");
  2334.             fprintf (fp, "%s\n", User->Name);
  2335.             fprintf (fp, "%s\n", User->City);
  2336.             fprintf (fp, "%s\n", User->DayPhone);
  2337.             fprintf (fp, "\n");
  2338.             fprintf (fp, "\n");
  2339.             fprintf (fp, "%u\n", User->Level);
  2340.             fprintf (fp, "%lu\n", User->TotalCalls);
  2341.             ltm = localtime ((time_t *)&User->LastCall);
  2342.             fprintf (fp, "%02d/%02d/%04d\n", ltm->tm_mon + 1, ltm->tm_mday, ltm->tm_year);
  2343.             fprintf (fp, "%lu\n", TimeRemain (TRUE));
  2344.             fprintf (fp, "%lu\n", TimeRemain ());
  2345.             fprintf (fp, "%s\n", (Ansi == TRUE || Avatar == TRUE) ? "GR" : "NG");
  2346.             fprintf (fp, "%u\n", ScreenHeight);
  2347.             fprintf (fp, "Y\n");
  2348.             fprintf (fp, "\n");
  2349.             fprintf (fp, "\n");
  2350.             fprintf (fp, "01/01/99\n");
  2351.             fprintf (fp, "1\n");
  2352.             fprintf (fp, "N\n");
  2353.             fprintf (fp, "%d\n", User->UploadFiles);
  2354.             fprintf (fp, "%d\n", User->DownloadFiles);
  2355.             fprintf (fp, "%d\n", User->FilesToday);
  2356.             fprintf (fp, "%d\n", 2000);
  2357.             fclose (fp);
  2358.          }
  2359.          break;
  2360.  
  2361.       case DORINFO1_DEF:
  2362.       case DORINFOX_DEF:
  2363.          if (DropFile == DOOR_SYS)
  2364.             sprintf (Temp, "%sdorinfo1.def", Cfg->SystemPath);
  2365.          else
  2366.             sprintf (Temp, "%sdorinfo%u.def", Cfg->SystemPath, Task);
  2367.  
  2368.          Log->Write (":Creating %s", Temp);
  2369.          if ((fp = fopen (Temp, "wt")) != NULL) {
  2370.             fprintf (fp, "%s\n", Cfg->SystemName);
  2371.             strcpy (Temp, Cfg->SysopName);
  2372.             if ((p = strtok (Temp, " ")) != NULL) {
  2373.                fprintf (fp, "%s\n", p);
  2374.                if ((p = strtok (NULL, "")) != NULL) {
  2375.                   while (*p == ' ')
  2376.                      p++;
  2377.                   fprintf (fp, "%s\n", p);
  2378.                }
  2379.                else
  2380.                   fprintf (fp, "\n");
  2381.             }
  2382.             else
  2383.                fprintf (fp, "\n\n");
  2384.             fprintf (fp, "%s\n", Cfg->Device);
  2385.             fprintf (fp, "%u BAUD,N,8,1\n", Cfg->Speed);
  2386.             fprintf (fp, "%u\n", Task);
  2387.             strcpy (Temp, User->Name);
  2388.             if ((p = strtok (Temp, " ")) != NULL) {
  2389.                fprintf (fp, "%s\n", p);
  2390.                if ((p = strtok (NULL, "")) != NULL) {
  2391.                   while (*p == ' ')
  2392.                      p++;
  2393.                   fprintf (fp, "%s\n", p);
  2394.                }
  2395.                else
  2396.                   fprintf (fp, "\n");
  2397.             }
  2398.             else
  2399.                fprintf (fp, "\n\n");
  2400.             fprintf (fp, "%s\n", User->City);
  2401.             fprintf (fp, "%s\n", (Ansi == TRUE || Avatar == TRUE) ? "1" : "0");
  2402.             fprintf (fp, "%u\n", User->Level);
  2403.             fprintf (fp, "%lu\n", TimeRemain ());
  2404.             fprintf (fp, "-1\n");
  2405.             fclose (fp);
  2406.          }
  2407.          break;
  2408.    }
  2409.  
  2410.    DisplayFile ("leaving");
  2411.    if (Log != NULL) {
  2412.       Log->Write (":Running: %s", Cmd);
  2413.       Log->Suspend ();
  2414.    }
  2415.  
  2416.    ::RunExternal (Cmd);
  2417.  
  2418.    if (Log != NULL) {
  2419.       Log->Resume ();
  2420.       Log->Write (":Returned from door");
  2421.    }
  2422.    DisplayFile ("return");
  2423. }
  2424.  
  2425. VOID TEmbedded::SetColor (USHORT usColor)
  2426. {
  2427.    LastColor = usColor;
  2428.  
  2429.    if ((Ansi == TRUE || Avatar == TRUE) && Color == TRUE) {
  2430.       if (Com != NULL) {
  2431.          if (Avatar == TRUE) {
  2432.             Com->BufferByte (CTRLV);
  2433.             Com->BufferByte (CTRLA);
  2434.             Com->BufferByte ((UCHAR)usColor);
  2435.          }
  2436.          else if (Ansi == TRUE) {
  2437.             Com->BufferBytes ((UCHAR *)"\x1B[0", 3);
  2438.  
  2439.             if (usColor & BLINK)
  2440.                Com->BufferBytes ((UCHAR *)";5", 2);
  2441.  
  2442.             switch (usColor & 0x0F) {
  2443.                case BLACK:
  2444.                   Com->BufferBytes ((UCHAR *)";30", 3);
  2445.                   break;
  2446.                case BLUE:
  2447.                   Com->BufferBytes ((UCHAR *)";34", 3);
  2448.                   break;
  2449.                case GREEN:
  2450.                   Com->BufferBytes ((UCHAR *)";32", 3);
  2451.                   break;
  2452.                case CYAN:
  2453.                   Com->BufferBytes ((UCHAR *)";36", 3);
  2454.                   break;
  2455.                case RED:
  2456.                   Com->BufferBytes ((UCHAR *)";31", 3);
  2457.                   break;
  2458.                case MAGENTA:
  2459.                   Com->BufferBytes ((UCHAR *)";35", 3);
  2460.                   break;
  2461.                case BROWN:
  2462.                   Com->BufferBytes ((UCHAR *)";33", 3);
  2463.                   break;
  2464.                case LGREY:
  2465.                   Com->BufferBytes ((UCHAR *)";37", 3);
  2466.                   break;
  2467.                case DGREY:
  2468.                   Com->BufferBytes ((UCHAR *)";1;30", 5);
  2469.                   break;
  2470.                case LBLUE:
  2471.                   Com->BufferBytes ((UCHAR *)";1;34", 5);
  2472.                   break;
  2473.                case LGREEN:
  2474.                   Com->BufferBytes ((UCHAR *)";1;32", 5);
  2475.                   break;
  2476.                case LCYAN:
  2477.                   Com->BufferBytes ((UCHAR *)";1;36", 5);
  2478.                   break;
  2479.                case LRED:
  2480.                   Com->BufferBytes ((UCHAR *)";1;31", 5);
  2481.                   break;
  2482.                case LMAGENTA:
  2483.                   Com->BufferBytes ((UCHAR *)";1;35", 5);
  2484.                   break;
  2485.                case YELLOW:
  2486.                   Com->BufferBytes ((UCHAR *)";1;33", 5);
  2487.                   break;
  2488.                case WHITE:
  2489.                   Com->BufferBytes ((UCHAR *)";1;37", 5);
  2490.                   break;
  2491.             }
  2492.  
  2493.             switch (usColor & 0xF0) {
  2494.                case _BLACK:
  2495.                   Com->BufferBytes ((UCHAR *)";40", 3);
  2496.                   break;
  2497.                case _BLUE:
  2498.                   Com->BufferBytes ((UCHAR *)";44", 3);
  2499.                   break;
  2500.                case _GREEN:
  2501.                   Com->BufferBytes ((UCHAR *)";42", 3);
  2502.                   break;
  2503.                case _CYAN:
  2504.                   Com->BufferBytes ((UCHAR *)";46", 3);
  2505.                   break;
  2506.                case _RED:
  2507.                   Com->BufferBytes ((UCHAR *)";41", 3);
  2508.                   break;
  2509.                case _MAGENTA:
  2510.                   Com->BufferBytes ((UCHAR *)";45", 3);
  2511.                   break;
  2512.                case _BROWN:
  2513.                   Com->BufferBytes ((UCHAR *)";43", 3);
  2514.                   break;
  2515.                case _LGREY:
  2516.                   Com->BufferBytes ((UCHAR *)";47", 3);
  2517.                   break;
  2518.             }
  2519.  
  2520.             Com->BufferBytes ((UCHAR *)"m", 1);
  2521.          }
  2522.       }
  2523.  
  2524.       if (Snoop != NULL && (Ansi == TRUE || Avatar == TRUE)) {
  2525.          Snoop->BufferBytes ((UCHAR *)"\x1B[0", 3);
  2526.  
  2527.          if (usColor & BLINK)
  2528.             Snoop->BufferBytes ((UCHAR *)";5", 2);
  2529.  
  2530.          switch (usColor & 0x0F) {
  2531.             case BLACK:
  2532.                Snoop->BufferBytes ((UCHAR *)";30", 3);
  2533.                break;
  2534.             case BLUE:
  2535.                Snoop->BufferBytes ((UCHAR *)";34", 3);
  2536.                break;
  2537.             case GREEN:
  2538.                Snoop->BufferBytes ((UCHAR *)";32", 3);
  2539.                break;
  2540.             case CYAN:
  2541.                Snoop->BufferBytes ((UCHAR *)";36", 3);
  2542.                break;
  2543.             case RED:
  2544.                Snoop->BufferBytes ((UCHAR *)";31", 3);
  2545.                break;
  2546.             case MAGENTA:
  2547.                Snoop->BufferBytes ((UCHAR *)";35", 3);
  2548.                break;
  2549.             case BROWN:
  2550.                Snoop->BufferBytes ((UCHAR *)";33", 3);
  2551.                break;
  2552.             case LGREY:
  2553.                Snoop->BufferBytes ((UCHAR *)";37", 3);
  2554.                break;
  2555.             case DGREY:
  2556.                Snoop->BufferBytes ((UCHAR *)";1;30", 5);
  2557.                break;
  2558.             case LBLUE:
  2559.                Snoop->BufferBytes ((UCHAR *)";1;34", 5);
  2560.                break;
  2561.             case LGREEN:
  2562.                Snoop->BufferBytes ((UCHAR *)";1;32", 5);
  2563.                break;
  2564.             case LCYAN:
  2565.                Snoop->BufferBytes ((UCHAR *)";1;36", 5);
  2566.                break;
  2567.             case LRED:
  2568.                Snoop->BufferBytes ((UCHAR *)";1;31", 5);
  2569.                break;
  2570.             case LMAGENTA:
  2571.                Snoop->BufferBytes ((UCHAR *)";1;35", 5);
  2572.                break;
  2573.             case YELLOW:
  2574.                Snoop->BufferBytes ((UCHAR *)";1;33", 5);
  2575.                break;
  2576.             case WHITE:
  2577.                Snoop->BufferBytes ((UCHAR *)";1;37", 5);
  2578.                break;
  2579.          }
  2580.  
  2581.          switch (usColor & 0xF0) {
  2582.             case _BLACK:
  2583.                Snoop->BufferBytes ((UCHAR *)";40", 3);
  2584.                break;
  2585.             case _BLUE:
  2586.                Snoop->BufferBytes ((UCHAR *)";44", 3);
  2587.                break;
  2588.             case _GREEN:
  2589.                Snoop->BufferBytes ((UCHAR *)";42", 3);
  2590.                break;
  2591.             case _CYAN:
  2592.                Snoop->BufferBytes ((UCHAR *)";46", 3);
  2593.                break;
  2594.             case _RED:
  2595.                Snoop->BufferBytes ((UCHAR *)";41", 3);
  2596.                break;
  2597.             case _MAGENTA:
  2598.                Snoop->BufferBytes ((UCHAR *)";45", 3);
  2599.                break;
  2600.             case _BROWN:
  2601.                Snoop->BufferBytes ((UCHAR *)";43", 3);
  2602.                break;
  2603.             case _LGREY:
  2604.                Snoop->BufferBytes ((UCHAR *)";47", 3);
  2605.                break;
  2606.          }
  2607.  
  2608.          Snoop->BufferBytes ((UCHAR *)"m", 1);
  2609.       }
  2610.    }
  2611. }
  2612.  
  2613. VOID TEmbedded::Putch (UCHAR ucByte)
  2614. {
  2615.    if (Com != NULL)
  2616.       Com->SendByte (ucByte);
  2617.    if (Snoop != NULL)
  2618.       Snoop->SendByte (ucByte);
  2619. }
  2620.  
  2621. ULONG TEmbedded::TimeRemain (USHORT seconds)
  2622. {
  2623.    ULONG RetVal = 1440L * 60L, Len;
  2624.  
  2625.    if (TimeLimit != 0) {
  2626.       Len = time (NULL) - StartCall;
  2627.       RetVal = (TimeLimit * 60L) - Len;
  2628.    }
  2629.  
  2630.    if (seconds == FALSE)
  2631.       RetVal /= 60L;
  2632.  
  2633.    return (RetVal);
  2634. }
  2635.  
  2636. VOID TEmbedded::UnbufferBytes (VOID)
  2637. {
  2638.    if (Com != NULL)
  2639.       Com->UnbufferBytes ();
  2640.    if (Snoop != NULL)
  2641.       Snoop->UnbufferBytes ();
  2642. }
  2643.  
  2644. VOID TEmbedded::TranslateKeyword (VOID)
  2645. {
  2646.    USHORT Len;
  2647.    SHORT i, c, PutOn = FALSE, WasColor = FALSE;
  2648.    CHAR Key[64], *p, Color = 0;
  2649.  
  2650.    Traslate[0] = '\0';
  2651.    TrasPtr = Traslate;
  2652.    TrasLen = Len = 0;
  2653.  
  2654.    while ((c = GetNextChar ()) != EOF) {
  2655.       if (c > ' ')
  2656.          break;
  2657.    }
  2658.  
  2659.    for (;;) {
  2660.       p = Key;
  2661.       if (c != EOF) {
  2662.          *p++ = (CHAR)c;
  2663.          while ((c = GetNextChar ()) != EOF) {
  2664.             if (c == ']' || c <= ' ')
  2665.                break;
  2666.             *p++ = (CHAR)c;
  2667.          }
  2668.          *p++ = '\0';
  2669.  
  2670.          if (!stricmp (Key, "on"))
  2671.             PutOn = TRUE;
  2672.          else if (WasColor == TRUE && !stricmp (Key, "blink"))
  2673.             Traslate[Len - 1] |= 0x80;
  2674.          else if (isdigit (Key[0]))
  2675.             Traslate[Len++] = (CHAR)atoi (Key);
  2676.          else {
  2677.             for (i = 0; MeccaKeywords[i].Key != NULL; i++) {
  2678.                if (!stricmp (Key, MeccaKeywords[i].Key)) {
  2679.                   if (PutOn == FALSE) {
  2680.                      memcpy (&Traslate[Len], MeccaKeywords[i].Text, MeccaKeywords[i].Len);
  2681.                      Len += MeccaKeywords[i].Len;
  2682.                   }
  2683.                   WasColor = FALSE;
  2684.                   if (MeccaKeywords[i].Text[0] == '\026' && MeccaKeywords[i].Text[1] == '\001') {
  2685.                      WasColor = TRUE;
  2686.                      if (PutOn == TRUE) {
  2687.                         Color = (CHAR)(MeccaKeywords[i].Text[2] << 4);
  2688.                         Traslate[Len - 1] |= Color;
  2689.                         PutOn = FALSE;
  2690.                      }
  2691.                   }
  2692.                   break;
  2693.                }
  2694.             }
  2695.          }
  2696.  
  2697.          if (c != ']' && c != EOF) {
  2698.             while ((c = GetNextChar ()) != EOF && c != ']') {
  2699.                if (c > ' ')
  2700.                   break;
  2701.             }
  2702.          }
  2703.       }
  2704.       if (c == ']' || c == EOF)
  2705.          break;
  2706.    }
  2707.  
  2708.    TrasLen = Len;
  2709. }
  2710.  
  2711.