home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / BBS.CPP < prev    next >
Text File  |  1998-05-12  |  91KB  |  2,596 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.  
  22. // ----------------------------------------------------------------------
  23.  
  24. typedef struct {
  25.    USHORT Task;
  26.    CHAR   Status[32];
  27.    CHAR   Name[48];
  28.    CHAR   City[48];
  29.    ULONG  Speed;
  30.    USHORT NoDisturb;
  31. } USERON;
  32.  
  33. class TUseron
  34. {
  35. public:
  36.    TUseron (PSZ pszDataPath);
  37.    ~TUseron (void);
  38.  
  39.    USHORT Task;
  40.    CHAR   Status[32];
  41.    CHAR   Name[48];
  42.    CHAR   City[48];
  43.    ULONG  Speed;
  44.    USHORT NoDisturb;
  45.  
  46.    VOID   Disable (VOID);
  47.    VOID   Enable (VOID);
  48.    USHORT First (VOID);
  49.    USHORT Next (VOID);
  50.    VOID   Read (USHORT nTask);
  51.    VOID   Update (VOID);
  52.  
  53. private:
  54.    CHAR   DataFile[128];
  55.    USERON User;
  56. };
  57.  
  58. TUseron::TUseron (PSZ pszDataPath)
  59. {
  60.    strcpy (DataFile, pszDataPath);
  61.    strcat (DataFile, "useron.dat");
  62.    AdjustPath (strlwr (DataFile));
  63. }
  64.  
  65. TUseron::~TUseron (void)
  66. {
  67. }
  68.  
  69. VOID TUseron::Enable (VOID)
  70. {
  71.    int fd;
  72.    USHORT i;
  73.  
  74.    if ((fd = open (DataFile, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  75.       if (lseek (fd, (Task - 1) * sizeof (USERON), SEEK_SET) == -1) {
  76.          lseek (fd, 0L, SEEK_SET);
  77.          for (i = 0; i < Task; i++) {
  78.             if (read (fd, &User, sizeof (USERON)) != sizeof (USERON)) {
  79.                memset (&User, 0, sizeof (USERON));
  80.                write (fd, &User, sizeof (USERON));
  81.             }
  82.          }
  83.       }
  84.       else
  85.          read (fd, &User, sizeof (USERON));
  86.  
  87.       memset (&User, 0, sizeof (USERON));
  88.       User.Task = Task;
  89.       strcpy (User.Status, Status);
  90.       strcpy (User.Name, Name);
  91.       strcpy (User.City, City);
  92.       User.Speed = Speed;
  93.       User.NoDisturb = NoDisturb;
  94.  
  95.       lseek (fd, tell (fd) - sizeof (USERON), SEEK_SET);
  96.       write (fd, &User, sizeof (USERON));
  97.  
  98.       close (fd);
  99.    }
  100. }
  101.  
  102. USHORT TUseron::First (VOID)
  103. {
  104.    Task = 0;
  105.  
  106.    return (Next ());
  107. }
  108.  
  109. VOID TUseron::Disable (VOID)
  110. {
  111.    int fd;
  112.    USHORT i;
  113.  
  114.    if ((fd = open (DataFile, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  115.       if (lseek (fd, (Task - 1) * sizeof (USERON), SEEK_SET) == -1) {
  116.          lseek (fd, 0L, SEEK_SET);
  117.          for (i = 0; i < Task; i++) {
  118.             if (read (fd, &User, sizeof (USERON)) != sizeof (USERON)) {
  119.                memset (&User, 0, sizeof (USERON));
  120.                write (fd, &User, sizeof (USERON));
  121.             }
  122.          }
  123.       }
  124.       else
  125.          read (fd, &User, sizeof (USERON));
  126.  
  127.       memset (&User, 0, sizeof (USERON));
  128.  
  129.       lseek (fd, tell (fd) - sizeof (USERON), SEEK_SET);
  130.       write (fd, &User, sizeof (USERON));
  131.  
  132.       close (fd);
  133.    }
  134. }
  135.  
  136. USHORT TUseron::Next (VOID)
  137. {
  138.    int fd;
  139.    USHORT RetVal = FALSE;
  140.  
  141.    if ((fd = open (DataFile, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  142.       while (read (fd, &User, sizeof (USERON)) == sizeof (USERON)) {
  143.          if (User.Task > Task) {
  144.             RetVal = TRUE;
  145.             break;
  146.          }
  147.       }
  148.       close (fd);
  149.    }
  150.  
  151.    if (RetVal == TRUE) {
  152.       Task = User.Task;
  153.       strcpy (Status, User.Status);
  154.       strcpy (Name, User.Name);
  155.       strcpy (City, User.City);
  156.       Speed = User.Speed;
  157.       NoDisturb = User.NoDisturb;
  158.    }
  159.  
  160.    return (RetVal);
  161. }
  162.  
  163. VOID TUseron::Update (VOID)
  164. {
  165.    int fd;
  166.    USHORT i;
  167.  
  168.    if ((fd = open (DataFile, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  169.       if (lseek (fd, (Task - 1) * sizeof (USERON), SEEK_SET) == -1) {
  170.          lseek (fd, 0L, SEEK_SET);
  171.          for (i = 0; i < Task; i++) {
  172.             if (read (fd, &User, sizeof (USERON)) != sizeof (USERON)) {
  173.                memset (&User, 0, sizeof (USERON));
  174.                write (fd, &User, sizeof (USERON));
  175.             }
  176.          }
  177.       }
  178.       else
  179.          read (fd, &User, sizeof (USERON));
  180.  
  181.       memset (&User, 0, sizeof (USERON));
  182.       User.Task = Task;
  183.       strcpy (User.Status, Status);
  184.       strcpy (User.Name, Name);
  185.       strcpy (User.City, City);
  186.       User.Speed = Speed;
  187.       User.NoDisturb = NoDisturb;
  188.  
  189.       lseek (fd, tell (fd) - sizeof (USERON), SEEK_SET);
  190.       write (fd, &User, sizeof (USERON));
  191.  
  192.       close (fd);
  193.    }
  194. }
  195.  
  196. VOID TUseron::Read (USHORT nTask)
  197. {
  198.    int fd;
  199.    USHORT i;
  200.  
  201.    if ((fd = open (DataFile, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  202.       if (lseek (fd, (Task - 1) * sizeof (USERON), SEEK_SET) == -1) {
  203.          lseek (fd, 0L, SEEK_SET);
  204.          for (i = 0; i < Task; i++) {
  205.             if (read (fd, &User, sizeof (USERON)) != sizeof (USERON)) {
  206.                memset (&User, 0, sizeof (USERON));
  207.                write (fd, &User, sizeof (USERON));
  208.             }
  209.          }
  210.       }
  211.       else
  212.          read (fd, &User, sizeof (USERON));
  213.  
  214.       User.Task = nTask;
  215.       strcpy (User.Status, Status);
  216.       strcpy (User.Name, Name);
  217.       strcpy (User.City, City);
  218.       User.Speed = Speed;
  219.       User.NoDisturb = NoDisturb;
  220.  
  221.       close (fd);
  222.    }
  223. }
  224.  
  225. // ----------------------------------------------------------------------
  226.  
  227. TBbs::TBbs (void)
  228. {
  229.    StartCall = 0L;
  230.    Com = Snoop = NULL;
  231.    Log = NULL;
  232.    Cfg = NULL;
  233.    Progress = NULL;
  234.    MailerStatus = NULL;
  235.    Status = NULL;
  236.    Remote = REMOTE_NONE;
  237.    Speed = 57600L;
  238.  
  239.    Task = 1;
  240.    AutoDetect = TRUE;
  241.    FancyNames = TRUE;
  242.    Logoff = FALSE;
  243.    Local = FALSE;
  244.    Stack.Clear ();
  245.    TimeLimit = 0;
  246.  
  247.    Snoop = NULL;
  248.    Menu = new TMenu;
  249.    Language = new TLanguage;
  250.    Embedded = new TEmbedded;
  251. }
  252.  
  253. TBbs::~TBbs (void)
  254. {
  255.    if (Embedded != NULL)
  256.       delete Embedded;
  257.    if (Language != NULL)
  258.       delete Language;
  259.    if (User != NULL)
  260.       delete User;
  261.    if (Menu != NULL)
  262.       delete Menu;
  263.    if (Snoop != NULL)
  264.       delete Snoop;
  265. }
  266.  
  267. VOID TBbs::DisableUseronRecord (VOID)
  268. {
  269.    class TUseron *Useron;
  270.  
  271.    if ((Useron = new TUseron (Cfg->SystemPath)) != NULL) {
  272.       Useron->Task = Task;
  273.       Useron->Disable ();
  274.       delete Useron;
  275.    }
  276. }
  277.  
  278. VOID TBbs::SetUseronRecord (PSZ pszStatus)
  279. {
  280.    class TUseron *Useron;
  281.  
  282.    if ((Useron = new TUseron (Cfg->SystemPath)) != NULL) {
  283.       Useron->Task = Task;
  284.       strcpy (Useron->Status, pszStatus);
  285.       if (User != NULL && User->Name[0] != '\0') {
  286.          strcpy (Useron->Name, User->Name);
  287.          strcpy (Useron->City, User->City);
  288.          Useron->NoDisturb = FALSE;
  289.       }
  290.       else
  291.          Useron->NoDisturb = TRUE;
  292.       Useron->Speed = Speed;
  293.       Useron->Enable ();
  294.       delete Useron;
  295.    }
  296. }
  297.  
  298. VOID TBbs::ToggleNoDisturb (VOID)
  299. {
  300.    class TUseron *Useron;
  301.  
  302.    if ((Useron = new TUseron (Cfg->SystemPath)) != NULL) {
  303.       Useron->Read (Task);
  304.       Useron->NoDisturb = (Useron->NoDisturb == TRUE) ? FALSE : TRUE;
  305.       Useron->Update ();
  306.       delete Useron;
  307.    }
  308. }
  309.  
  310. VOID TBbs::SetBirthDate (VOID)
  311. {
  312.    CHAR Temp[16], *p;
  313.  
  314.    do {
  315.       Embedded->Printf (Language->Text (LNG_ASKBIRTHDATE));
  316.       Embedded->Input (Temp, 10, INP_FIELD);
  317.    } while (strlen (Temp) < 10 && Embedded->AbortSession () == FALSE);
  318.    if ((p = strtok (Temp, "-")) != NULL) {
  319.       User->BirthMonth = (UCHAR)atoi (p);
  320.       if ((p = strtok (NULL, "-")) != NULL)
  321.          User->BirthDay = (UCHAR)atoi (p);
  322.       if ((p = strtok (NULL, "-")) != NULL)
  323.          User->BirthYear = (USHORT)atoi (p);
  324.    }
  325.    CheckBirthday ();
  326. }
  327.  
  328. VOID TBbs::ExecuteCommand (class TMenu *Menu)
  329. {
  330.    CHAR Temp[32], *p;
  331.  
  332.    switch (Menu->Command) {
  333.       case MNU_APPENDMENU:
  334.          if (Menu->Load (Menu->Argument, TRUE) == FALSE) {
  335.             if (Log != NULL)
  336.                Log->Write ("!Can't append menu %s", Menu->Argument);
  337.          }
  338.          break;
  339.       case MNU_ONLINEUSERS: {
  340.          class TUseron *Useron;
  341.  
  342.          if ((Useron = new TUseron (Cfg->SystemPath)) != NULL) {
  343.             Embedded->BufferedPrintf (Language->Text (LNG_ONLINETITLE), Cfg->SystemName);
  344.             Embedded->BufferedPrintf (Language->Text (LNG_ONLINEHEADER));
  345.             if (Useron->First () == TRUE)
  346.                do {
  347.                   Embedded->BufferedPrintf (Language->Text (LNG_ONLINEENTRY), Useron->Name, Useron->Task, Useron->Speed, Useron->Status, Useron->City);
  348.                } while (Useron->Next () == TRUE);
  349.             Embedded->Printf ("\n");
  350.             delete Useron;
  351.          }
  352.          break;
  353.       }
  354.       case MNU_CLEARSTACK:
  355.          Stack.Clear ();
  356.          break;
  357.       case MNU_DISPLAY:
  358.          Embedded->DisplayFile (Menu->Argument);
  359.          break;
  360.       case MNU_FILEDATELIST:
  361.          SetUseronRecord ("Browsing files");
  362.          if (Library != NULL)
  363.             Library->ListRecentFiles ();
  364.          break;
  365.       case MNU_FILEDELETE:
  366.          if (Library != NULL)
  367.             Library->RemoveFiles ();
  368.          break;
  369.       case MNU_FILEDOWNLOAD:
  370.       case MNU_FILEDOWNLOADANY:
  371.          SetUseronRecord ("Download");
  372.          if (Library != NULL) {
  373.             if ((p = strstr (Menu->Argument, "/f=")) == NULL)
  374.                p = strstr (Menu->Argument, "/F=");
  375.             if (p != NULL) {
  376.                p += 3;
  377.                Library->DownloadFile (p, NULL, 0L);
  378.             }
  379.             else
  380.                Library->Download (NULL, (Menu->Command == MNU_FILEDOWNLOADANY) ? TRUE : FALSE);
  381.          }
  382.          break;
  383.       case MNU_FILEDOWNLOADLIST:
  384.          if (Library != NULL)
  385.             Library->DownloadList ();
  386.          break;
  387.       case MNU_FILEKEYWORDLIST:
  388.          SetUseronRecord ("Browsing files");
  389.          if (Library != NULL)
  390.             Library->SearchKeyword ();
  391.          break;
  392.       case MNU_FILENAMELIST:
  393.          SetUseronRecord ("Browsing files");
  394.          if (Library != NULL)
  395.             Library->ListFiles ();
  396.          break;
  397.       case MNU_FILENEWLIST:
  398.          SetUseronRecord ("Browsing files");
  399.          if (Library != NULL)
  400.             Library->SearchNewFiles ();
  401.          break;
  402.       case MNU_FILESELECT:
  403.          if (Library != NULL)
  404.             Library->SelectArea (Menu->Argument);
  405.          break;
  406.       case MNU_ADDTAGGED:
  407.          if (Library != NULL)
  408.             Library->AddTagged ();
  409.          break;
  410.       case MNU_LISTTAGGED:
  411.          if (Library != NULL)
  412.             Library->ListTagged ();
  413.          break;
  414.       case MNU_DELETETAGGED:
  415.          if (Library != NULL)
  416.             Library->DeleteTagged ();
  417.          break;
  418.       case MNU_DELETEALLTAGGED:
  419.          if (Library != NULL)
  420.             Library->DeleteAllTagged ();
  421.          break;
  422.       case MNU_FILETEXTLIST:
  423.          SetUseronRecord ("Browsing files");
  424.          if (Library != NULL)
  425.             Library->SearchText ();
  426.          break;
  427.       case MNU_FILEUPLOAD:
  428.          SetUseronRecord ("Upload");
  429.          if (Library != NULL)
  430.             Library->Upload ();
  431.          break;
  432.       case MNU_FILEUPLOADUSER:
  433.          SetUseronRecord ("Upload");
  434.          if (Library != NULL)
  435.             Library->UploadUser (Menu->Argument);
  436.          break;
  437.       case MNU_FILEDISPLAY:
  438.          if (Library != NULL)
  439.             Library->TypeFile ( );
  440.          break;
  441.       case MNU_FINGER: {
  442.          class TInternet *Inet;
  443.  
  444.          SetUseronRecord ("Finger");
  445.          if ((Inet = new TInternet) != NULL) {
  446.             Inet->Cfg = Cfg;
  447.             Inet->Com = Com;
  448.             Inet->Snoop = Snoop;
  449.             Inet->Log = Log;
  450.             Inet->Embedded = Embedded;
  451.             Inet->Finger (Menu->Argument);
  452.             delete Inet;
  453.          }
  454.          break;
  455.       }
  456.       case MNU_FTP: {
  457.          class TInternet *Inet;
  458.  
  459.          SetUseronRecord ("FTP");
  460.          if ((Inet = new TInternet) != NULL) {
  461.             Inet->Cfg = Cfg;
  462.             Inet->Com = Com;
  463.             Inet->Snoop = Snoop;
  464.             Inet->Log = Log;
  465.             Inet->Embedded = Embedded;
  466.             Inet->User = User;
  467.             Inet->FTP (Menu->Argument);
  468.             delete Inet;
  469.          }
  470.          break;
  471.       }
  472.       case MNU_IRC: {
  473.          class TInternet *Inet;
  474.  
  475.          SetUseronRecord ("IRC");
  476.          if ((Inet = new TInternet) != NULL) {
  477.             Inet->Cfg = Cfg;
  478.             Inet->Com = Com;
  479.             Inet->Snoop = Snoop;
  480.             Inet->Log = Log;
  481.             Inet->Embedded = Embedded;
  482.             Inet->User = User;
  483.             Inet->IRC (Menu->Argument);
  484.             delete Inet;
  485.          }
  486.          break;
  487.       }
  488.       case MNU_CLEARGOSUB:
  489.          Stack.Clear ();
  490.          // Fall-through
  491.       case MNU_GOSUB:
  492.          if (Menu->Argument[0] != '\0') {
  493.             Stack.Add (MenuName, (USHORT)(strlen (MenuName) + 1));
  494.             strcpy (MenuName, Menu->Argument);
  495.             Reload = TRUE;
  496.          }
  497.          break;
  498.       case MNU_CLEARGOTO:
  499.          Stack.Clear ();
  500.          // Fall-through
  501.       case MNU_GOTO:
  502.          if (Menu->Argument[0] != '\0') {
  503.             strcpy (MenuName, Menu->Argument);
  504.             Reload = TRUE;
  505.          }
  506.          break;
  507.       case MNU_INQUIREPERSONAL: {
  508.          class TInquire *Inquire;
  509.  
  510.          if ((Inquire = new TInquire) != NULL) {
  511.             Inquire->Cfg = Cfg;
  512.             Inquire->Embedded = Embedded;
  513.             Inquire->User = User;
  514.             Inquire->Language = Language;
  515.             Inquire->Current = Message->Current;
  516.             Inquire->Log = Log;
  517.             if (!stricmp (Menu->Argument, "/all"))
  518.                Inquire->Type = TYPE_PERSONAL;
  519.             else
  520.                Inquire->Type = TYPE_PERSONALNEW;
  521.             Inquire->Query ();
  522.          }
  523.          break;
  524.       }
  525.       case MNU_INQUIRETEXT: {
  526.          class TInquire *Inquire;
  527.  
  528.          if ((Inquire = new TInquire) != NULL) {
  529.             Inquire->Cfg = Cfg;
  530.             Inquire->Embedded = Embedded;
  531.             Inquire->User = User;
  532.             Inquire->Language = Language;
  533.             Inquire->Current = Message->Current;
  534.             Inquire->Log = Log;
  535.             Inquire->Type = TYPE_KEYWORD;
  536.             Inquire->Query ();
  537.          }
  538.          break;
  539.       }
  540.       case MNU_LOGOFF: {
  541.          USHORT Answer;
  542.  
  543.          SetUseronRecord ("Logoff");
  544.  
  545.          if (User != NULL) {
  546.             if (User->FileTag != NULL) {
  547.                if (User->FileTag->TotalFiles > 0)
  548.                   Embedded->Printf (Language->Text(LNG_HAVETAGGED), User->FileTag->TotalFiles);
  549.             }
  550.          }
  551.  
  552.          do {
  553.             Embedded->Printf (Language->Text (LNG_DISCONNECT));
  554.             if ((Answer = Embedded->GetAnswer (ASK_DEFNO|ASK_HELP)) == ANSWER_YES)
  555.                Logoff = TRUE;
  556.             if (Answer == ANSWER_HELP)
  557.                Embedded->DisplayFile ("why_hu");
  558.          } while (Answer == ANSWER_HELP && Embedded->AbortSession () == FALSE);
  559.          break;
  560.       }
  561.       case MNU_MAILCHECK:
  562.          if (EMail != NULL)
  563.             EMail->CheckUnread ();
  564.          break;
  565.       case MNU_MAILDELETE:
  566.          if (EMail != NULL)
  567.             EMail->Delete ();
  568.          break;
  569.       case MNU_MAILLIST:
  570.          if (EMail != NULL)
  571.             EMail->BriefList ();
  572.          break;
  573.       case MNU_MAILREAD:
  574.          if (EMail != NULL)
  575.             EMail->ReadMessages (TRUE);
  576.          break;
  577.       case MNU_MAILWRITELOCAL:
  578.       case MNU_MAILWRITEFIDONET:
  579.       case MNU_MAILWRITEINTERNET:
  580.          if (EMail != NULL) {
  581.             if (Menu->Command == MNU_MAILWRITELOCAL)
  582.                EMail->Write (MAIL_LOCAL, Menu->Argument);
  583.             else if (Menu->Command == MNU_MAILWRITEFIDONET)
  584.                EMail->Write (MAIL_FIDONET, Menu->Argument);
  585.             else if (Menu->Command == MNU_MAILWRITEINTERNET)
  586.                EMail->Write (MAIL_INTERNET, Menu->Argument);
  587.          }
  588.          break;
  589.       case MNU_MAILNEXT:
  590.          SetUseronRecord ("Reading e-mail");
  591.          if (EMail != NULL)
  592.             EMail->ReadNext ();
  593.          break;
  594.       case MNU_MAILPREVIOUS:
  595.          SetUseronRecord ("Reading e-mail");
  596.          if (EMail != NULL)
  597.             EMail->ReadPrevious ();
  598.          break;
  599.       case MNU_MAILNONSTOP:
  600.          SetUseronRecord ("Reading e-mail");
  601.          if (EMail != NULL)
  602.             EMail->ReadNonStop ();
  603.          break;
  604.       case MNU_MAILINDIVIDUAL: {
  605.          ULONG Number;
  606.  
  607.          SetUseronRecord ("Reading e-mail");
  608.          Number = atol (Cmd);
  609.          if (EMail != NULL)
  610.             EMail->Read (Number);
  611.          break;
  612.       }
  613.       case MNU_MAILREPLY:
  614.          SetUseronRecord ("Message editor");
  615.          if (EMail != NULL)
  616.             EMail->Reply ();
  617.          break;
  618.       case MNU_MSGBRIEFLIST:
  619.          if (Message != NULL)
  620.             Message->BriefList ();
  621.          break;
  622.       case MNU_MSGDELETE:
  623.          if (Message != NULL)
  624.             Message->Delete ();
  625.          break;
  626.       case MNU_MSGFORWARD:
  627.          SetUseronRecord ("Message editor");
  628.          if (Message != NULL)
  629.             Message->ReadNext ();
  630.          break;
  631.       case MNU_MSGBACKWARD:
  632.          SetUseronRecord ("Reading messages");
  633.          if (Message != NULL)
  634.             Message->ReadPrevious ();
  635.          break;
  636.       case MNU_MSGREADREPLY:
  637.          SetUseronRecord ("Reading messages");
  638.          if (Message != NULL)
  639.             Message->ReadReply ();
  640.          break;
  641.       case MNU_MSGREADORIGINAL:
  642.          SetUseronRecord ("Reading messages");
  643.          if (Message != NULL)
  644.             Message->ReadOriginal ();
  645.          break;
  646.       case MNU_MSGINDIVIDUAL: {
  647.          ULONG Number;
  648.  
  649.          SetUseronRecord ("Reading messages");
  650.          Number = atol (Cmd);
  651.          if (Message != NULL && Message->Msg != NULL)
  652.             Message->Read (Message->Msg->MsgnToUid (Number));
  653.          break;
  654.       }
  655.       case MNU_MSGLISTNEWAREAS:
  656.          if (Message != NULL)
  657.             Message->SelectNewArea (Menu->Argument);
  658.          break;
  659.       case MNU_MSGREAD:
  660.          SetUseronRecord ("Reading messages");
  661.          if (Message != NULL)
  662.             Message->ReadMessages ();
  663.          break;
  664.       case MNU_MSGREADCURRENT:
  665.          SetUseronRecord ("Reading messages");
  666.          if (Message != NULL)
  667.             Message->DisplayCurrent ();
  668.          break;
  669.       case MNU_MSGREPLY:
  670.          SetUseronRecord ("Message editor");
  671.          if (Message != NULL)
  672.             Message->Reply ();
  673.          break;
  674.       case MNU_MSGSELECT:
  675.          if (Message != NULL)
  676.             Message->SelectArea (Menu->Argument);
  677.          break;
  678.       case MNU_MSGREADNONSTOP:
  679.          SetUseronRecord ("Reading messages");
  680.          if (Message != NULL)
  681.             Message->ReadNonStop ();
  682.          break;
  683.       case MNU_MSGTITLELIST:
  684.          if (Message != NULL)
  685.             Message->TitleList ();
  686.          break;
  687.       case MNU_MSGWRITE:
  688.          SetUseronRecord ("Message editor");
  689.          if (Message != NULL)
  690.             Message->Write ();
  691.          break;
  692.       case MNU_MSGUNRECEIVE:
  693.          if (Message != NULL)
  694.             Message->Unreceive ();
  695.          break;
  696.       case MNU_OLRDOWNLOADASCII:
  697.       case MNU_OLRDOWNLOADBW:
  698.       case MNU_OLRDOWNLOADPNT:
  699.       case MNU_OLRDOWNLOADQWK: {
  700.          class TOffline *Olr = NULL;
  701.  
  702.          SetUseronRecord ("Offline reader");
  703.          if (Menu->Command == MNU_OLRDOWNLOADASCII)
  704.             Olr = new TAscii;
  705.          else if (Menu->Command == MNU_OLRDOWNLOADBW)
  706.             Olr = new TBlueWave;
  707.          else if (Menu->Command == MNU_OLRDOWNLOADPNT)
  708.             Olr = new TPoint;
  709.          else if (Menu->Command == MNU_OLRDOWNLOADQWK)
  710.             Olr = new TQWK;
  711.  
  712.          if (Olr != NULL) {
  713.             Olr->Cfg = Cfg;
  714.             Olr->Embedded = Embedded;
  715.             Olr->Log = Log;
  716.             Olr->User = User;
  717.             Olr->Language = Language;
  718.             Olr->Progress = Progress;
  719.             strcpy (Olr->Id, Cfg->OLRPacketName);
  720.             Olr->Limit = Cfg->OLRMaxMessages;
  721.             if (Olr->Prescan () == TRUE)
  722.                Olr->Create ();
  723.             delete Olr;
  724.          }
  725.          break;
  726.       }
  727.       case MNU_OLRRESTRICTDATE: {
  728.          class TOffline *Olr;
  729.  
  730.          SetUseronRecord ("Offline reader");
  731.          if ((Olr = new TOffline) != NULL) {
  732.             Olr->Cfg = Cfg;
  733.             Olr->Embedded = Embedded;
  734.             Olr->User = User;
  735.             Olr->Language = Language;
  736.             Olr->RestrictDate ();
  737.             delete Olr;
  738.          }
  739.          break;
  740.       }
  741.       case MNU_OLRREMOVEAREA: {
  742.          class TOffline *Olr;
  743.  
  744.          SetUseronRecord ("Offline reader");
  745.          if ((Olr = new TOffline) != NULL) {
  746.             Olr->Cfg = Cfg;
  747.             Olr->Embedded = Embedded;
  748.             Olr->User = User;
  749.             Olr->Language = Language;
  750.             Olr->RemoveArea ();
  751.             delete Olr;
  752.          }
  753.          break;
  754.       }
  755.       case MNU_OLRTAGAREA: {
  756.          class TOffline *Olr;
  757.  
  758.          SetUseronRecord ("Offline reader");
  759.          if ((Olr = new TOffline) != NULL) {
  760.             Olr->Cfg = Cfg;
  761.             Olr->Embedded = Embedded;
  762.             Olr->User = User;
  763.             Olr->Language = Language;
  764.             Olr->ManageTagged ();
  765.             delete Olr;
  766.          }
  767.          break;
  768.       }
  769.       case MNU_OLRUPLOAD: {
  770.          class TOffline *Olr;
  771.  
  772.          SetUseronRecord ("Offline reader");
  773.          if ((Olr = new TBlueWave) != NULL) {
  774.             Olr->Cfg = Cfg;
  775.             Olr->Embedded = Embedded;
  776.             Olr->Log = Log;
  777.             Olr->User = User;
  778.             Olr->Language = Language;
  779.             Olr->Progress = Progress;
  780.             strcpy (Olr->Id, Cfg->OLRPacketName);
  781.             Olr->Limit = Cfg->OLRMaxMessages;
  782.             Olr->Upload ();
  783.             Olr->FetchReply ();
  784.             delete Olr;
  785.          }
  786.          if ((Olr = new TQWK) != NULL) {
  787.             Olr->Cfg = Cfg;
  788.             Olr->Embedded = Embedded;
  789.             Olr->Log = Log;
  790.             Olr->User = User;
  791.             Olr->Language = Language;
  792.             Olr->Progress = Progress;
  793.             strcpy (Olr->Id, Cfg->OLRPacketName);
  794.             Olr->Limit = Cfg->OLRMaxMessages;
  795.             Olr->FetchReply ();
  796.             delete Olr;
  797.          }
  798.          if ((Olr = new TPoint) != NULL) {
  799.             Olr->Cfg = Cfg;
  800.             Olr->Embedded = Embedded;
  801.             Olr->Log = Log;
  802.             Olr->User = User;
  803.             Olr->Language = Language;
  804.             Olr->Progress = Progress;
  805.             strcpy (Olr->Id, Cfg->OLRPacketName);
  806.             Olr->Limit = Cfg->OLRMaxMessages;
  807.             Olr->FetchReply ();
  808.             delete Olr;
  809.          }
  810.          break;
  811.       }
  812.       case MNU_OLRVIEWTAGGED: {
  813.          class TOffline *Olr;
  814.  
  815.          SetUseronRecord ("Offline reader");
  816.          if ((Olr = new TOffline) != NULL) {
  817.             Olr->Cfg = Cfg;
  818.             Olr->Embedded = Embedded;
  819.             Olr->User = User;
  820.             Olr->Language = Language;
  821.             Olr->Display ();
  822.             delete Olr;
  823.          }
  824.          break;
  825.       }
  826.       case MNU_PRESSENTER:
  827.          Embedded->PressEnter ();
  828.          break;
  829.       case MNU_RETURN:
  830.          if (Stack.Last () != NULL) {
  831.             strcpy (MenuName, (PSZ)Stack.Value ());
  832.             Reload = TRUE;
  833.             Stack.Remove ();
  834.          }
  835.          break;
  836.       case MNU_RETURNMAIN:
  837.          Stack.Clear ();
  838.          strcpy (MenuName, Cfg->MainMenu);
  839.          Reload = TRUE;
  840.          break;
  841.       case MNU_RUNEXTERNAL:
  842.          SetUseronRecord ("External door");
  843.          Embedded->RunExternal (Menu->Argument);
  844.          break;
  845.       case MNU_SEARCHFILENAME:
  846.          if (Library != NULL)
  847.             Library->SearchFileName ();
  848.          break;
  849.       case MNU_SETCOMPANY:
  850.          do {
  851.             Embedded->Printf (Language->Text(LNG_ASKCOMPANYNAME));
  852.             Embedded->Input (User->Company, (USHORT)(sizeof (User->Company) - 1), INP_FIELD);
  853.          } while (User->Company[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->AskCompanyName == REQUIRED);
  854.          break;
  855.       case MNU_SETADDRESS:
  856.          do {
  857.             Embedded->Printf (Language->Text(LNG_ASKADDRESS));
  858.             Embedded->Input (User->Address, (USHORT)(sizeof (User->Address) - 1), INP_FIELD);
  859.          } while (User->Address[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->AskAddress == REQUIRED);
  860.          break;
  861.       case MNU_SETCITY:
  862.          do {
  863.             Embedded->Printf (Language->Text(LNG_ASKCITY));
  864.             Embedded->Input (User->City, (USHORT)(sizeof (User->City) - 1), 0);
  865.          } while (User->City[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->AskCity == REQUIRED);
  866.          break;
  867.       case MNU_SETPHONE:
  868.          do {
  869.             Embedded->Printf (Language->Text(LNG_ASKDAYPHONE));
  870.             Embedded->Input (User->DayPhone, (USHORT)(sizeof (User->DayPhone) - 1), INP_FIELD);
  871.          } while (User->DayPhone[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->AskPhoneNumber == REQUIRED);
  872.          break;
  873.       case MNU_SETBIRTHDATE:
  874.          SetBirthDate ();
  875.          break;
  876.       case MNU_SETGENDER:
  877.          do {
  878.             Embedded->Printf (Language->Text(LNG_ASKSEX));
  879.             Embedded->Input (Temp, 1, INP_FIELD);
  880.             User->Sex = (UCHAR)toupper (Temp[0]);
  881.          } while (User->Sex != Language->Male && User->Sex != Language->Female && Embedded->AbortSession () == FALSE && Cfg->AskGender == REQUIRED);
  882.  
  883.          if (User->Sex == Language->Female)
  884.             User->Sex = 1;
  885.          else if (User->Sex == Language->Male)
  886.             User->Sex = 0;
  887.          else
  888.             User->Sex = 0;
  889.          break;
  890.       case MNU_SETLANGUAGE:
  891.          if (Language->Load (Menu->Argument) == TRUE) {
  892.             Log->Write (":Loaded language %s", Menu->Argument);
  893.             strcpy (Menu->AltPath, Language->MenuPath);
  894.             strcpy (Embedded->AltPath, Language->TextFiles);
  895.             Reload = TRUE;
  896.             if (Menu->AltPath[0] != '\0')
  897.                Log->Write ("   Language Menu Path = %s", Menu->AltPath);
  898.             if (Embedded->AltPath[0] != '\0')
  899.                Log->Write ("   Language Text Files Path = %s", Embedded->AltPath);
  900.             strcpy (User->Language, Menu->Argument);
  901.          }
  902.          else
  903.             Log->Write ("!Failed to load language %s", Menu->Argument);
  904.          break;
  905.       case MNU_SETPASSWORD: {
  906.          CHAR Temp[48];
  907.  
  908.          Embedded->Printf (Language->Text (LNG_CURRENTPASSWORD));
  909.          Embedded->Input (Temp, (USHORT)(sizeof (Password) - 1), INP_PWD);
  910.  
  911.          if (User->CheckPassword (Temp) == TRUE) {
  912.             if (Embedded->AbortSession () == FALSE)
  913.                do {
  914.                   Embedded->Printf (Language->Text (LNG_ASKPASSWORD));
  915.                   Embedded->Input (Password, (USHORT)(sizeof (Password) - 1), INP_PWD);
  916.                   if (strlen (Password) < 4)
  917.                      Embedded->Printf (Language->Text (LNG_WHYPASSWORD), sizeof (Password) - 1);
  918.                } while (strlen (Password) < 4 && Embedded->AbortSession () == FALSE);
  919.             if (Embedded->AbortSession () == FALSE)
  920.                do {
  921.                   Embedded->Printf (Language->Text (LNG_REENTERPASSWORD));
  922.                   Embedded->Input (Temp, (USHORT)(sizeof (Password) - 1), INP_FIELD|INP_PWD);
  923.                } while (Temp[0] == '\0' && Embedded->AbortSession () == FALSE);
  924.             if (Embedded->AbortSession () == FALSE) {
  925.                if (stricmp (Temp, Password))
  926.                   Embedded->Printf (Language->Text (LNG_PASSWORDNOMATCH));
  927.                else {
  928.                   User->SetPassword (Password);
  929.                   User->Update ();
  930.                }
  931.             }
  932.          }
  933.          else {
  934.             if (Log != NULL)
  935.                Log->Write ("!Invalid current pwd \"%s\"", Temp);
  936.             Embedded->Printf (Language->Text (LNG_WRONGPASSWORD));
  937.          }
  938.          break;
  939.       }
  940.       case MNU_SETSCREENLENGTH:
  941.          do {
  942.             Embedded->Printf (Language->Text (LNG_ASKLINES));
  943.             Embedded->Input (Temp, 2, INP_FIELD);
  944.          } while ((atoi (Temp) < 10 || atoi (Temp) > 66) && Embedded->AbortSession () == FALSE);
  945.          User->ScreenHeight = (USHORT)atoi (Temp);
  946.          break;
  947.       case MNU_TELNET: {
  948.          class TInternet *Inet;
  949.  
  950.          SetUseronRecord ("Telnet");
  951.          if ((Inet = new TInternet) != NULL) {
  952.             Inet->Cfg = Cfg;
  953.             Inet->Com = Com;
  954.             Inet->Snoop = Snoop;
  955.             Inet->Log = Log;
  956.             Inet->Embedded = Embedded;
  957.             Inet->Telnet (Menu->Argument);
  958.             delete Inet;
  959.          }
  960.          break;
  961.       }
  962.       case MNU_TOGGLEKLUDGES:
  963.          User->Kludges = (User->Kludges == TRUE) ? FALSE : TRUE;
  964.          Message->ShowKludges = User->Kludges;
  965.          break;
  966.       case MNU_TOGGLEFULLED:
  967.          User->FullEd = (User->FullEd == TRUE) ? FALSE : TRUE;
  968.          break;
  969.       case MNU_TOGGLEMAILCHECK:
  970.          User->MailCheck = (User->MailCheck == TRUE) ? FALSE : TRUE;
  971.          break;
  972.       case MNU_TOGGLEFILECHECK:
  973.          User->NewFileCheck = (User->NewFileCheck == TRUE) ? FALSE : TRUE;
  974.          break;
  975.       case MNU_TOGGLEFULLREAD:
  976.          User->FullReader = (User->FullReader == TRUE) ? FALSE : TRUE;
  977.          break;
  978.       case MNU_TOGGLENODISTURB:
  979.          User->NoDisturb = (User->NoDisturb == TRUE) ? FALSE : TRUE;
  980.          break;
  981.       case MNU_TOGGLEMOREPROMPT:
  982.          User->MorePrompt = (User->MorePrompt == TRUE) ? FALSE : TRUE;
  983.          break;
  984.       case MNU_TOGGLEFULLSCREEN:
  985.          User->FullScreen = (User->FullScreen == TRUE) ? FALSE : TRUE;
  986.          break;
  987.       case MNU_TOGGLEIBMCHARS:
  988.          User->IBMChars = (User->IBMChars == TRUE) ? FALSE : TRUE;
  989.          break;
  990.       case MNU_TOGGLERIP:
  991.          Embedded->Rip = (Embedded->Rip == TRUE) ? FALSE : TRUE;
  992.          break;
  993.       case MNU_TOGGLESCREENCLEAR:
  994.          User->ScreenClear = (User->ScreenClear == TRUE) ? FALSE : TRUE;
  995.          break;
  996.       case MNU_TOGGLEINUSERLIST:
  997.          User->InUserList = (User->InUserList == TRUE) ? FALSE : TRUE;
  998.          break;
  999.       case MNU_TOGGLECOLOR:
  1000.          User->Color = (User->Color == TRUE) ? FALSE : TRUE;
  1001.          Embedded->Color = User->Color;
  1002.          if (User->Color == FALSE)
  1003.             Embedded->Printf ("\nColor codes will NOT be used.\n\006\007\006\007");
  1004.          else
  1005.             Embedded->Printf ("\n\026\001\015Color codes now active.\n\006\007\006\007");
  1006.          break;
  1007.       case MNU_TOGGLEANSI:
  1008.          User->Ansi = (User->Ansi == TRUE) ? FALSE : TRUE;
  1009.          if (User->Ansi == TRUE)
  1010.             User->Avatar = FALSE;
  1011.          if (User->Ansi == FALSE && User->Avatar == FALSE)
  1012.             User->Color = FALSE;
  1013.          Embedded->Ansi = User->Ansi;
  1014.          Embedded->Avatar = User->Avatar;
  1015.          Embedded->Color = User->Color;
  1016.          if (User->Ansi == FALSE)
  1017.             Embedded->Printf ("\nANSI Color/Graphics will NOT be used.\n\006\007\006\007");
  1018.          else {
  1019.             if (User->Color == TRUE)
  1020.                Embedded->Printf ("\n\026\001\015ANSI Color/Graphics now active.\n\006\007\006\007");
  1021.             else
  1022.                Embedded->Printf ("\nANSI Graphics now active.\n\006\007\006\007");
  1023.          }
  1024.          break;
  1025.       case MNU_TOGGLEAVATAR:
  1026.          User->Avatar = (User->Avatar == TRUE) ? FALSE : TRUE;
  1027.          if (User->Avatar == TRUE)
  1028.             User->Ansi = FALSE;
  1029.          if (User->Ansi == FALSE && User->Avatar == FALSE)
  1030.             User->Color = FALSE;
  1031.          Embedded->Ansi = User->Ansi;
  1032.          Embedded->Avatar = User->Avatar;
  1033.          Embedded->Color = User->Color;
  1034.          if (User->Avatar == FALSE)
  1035.             Embedded->Printf ("\nAVATAR Color/Graphics will NOT be used.\n\006\007\006\007");
  1036.          else {
  1037.             if (User->Color == TRUE)
  1038.                Embedded->Printf ("\n\026\001\015AVATAR Color/Graphics now active.\n\006\007\006\007");
  1039.             else
  1040.                Embedded->Printf ("\nAVATAR Graphics now active.\n\006\007\006\007");
  1041.          }
  1042.          break;
  1043.       case MNU_TOGGLEHOTKEY:
  1044.          User->HotKey = (User->HotKey == TRUE) ? FALSE : TRUE;
  1045.          Embedded->HotKey = User->HotKey;
  1046.          if (User->HotKey == FALSE)
  1047.             Embedded->Printf ("\nHot keys will NOT be used.\n\006\007\006\007");
  1048.          else
  1049.             Embedded->Printf ("\n\026\001\015Hot keys now active.\n\006\007\006\007");
  1050.          break;
  1051.       case MNU_SETVIDEOMODE:
  1052.          if (!stricmp (Menu->Argument, "ANSI")) {
  1053.             User->Avatar = FALSE;
  1054.             User->Ansi = User->Color = TRUE;
  1055.          }
  1056.          else if (!stricmp (Menu->Argument, "AVATAR")) {
  1057.             User->Ansi = FALSE;
  1058.             User->Avatar = User->Color = TRUE;
  1059.          }
  1060.          else if (!stricmp (Menu->Argument, "TTY"))
  1061.             User->Avatar = User->Ansi = User->Color = FALSE;
  1062.          Embedded->Ansi = User->Ansi;
  1063.          Embedded->Avatar = User->Avatar;
  1064.          Embedded->Color = User->Color;
  1065.          break;
  1066.       case MNU_VERSION: {
  1067. #if defined(__OS2__)
  1068.          CHAR Temp[16];
  1069.          ULONG Value[3];
  1070. #elif defined(__NT__)
  1071.          CHAR *Processor;
  1072.          OSVERSIONINFO OsInfo;
  1073.          SYSTEM_INFO SysInfo;
  1074. #elif defined(__BORLANDC__) || defined(_MSC_VER)
  1075.          union REGS inregs, outregs;
  1076. #endif
  1077.  
  1078.          Embedded->Printf (" \nì%s Professional Edition - Version %s\n", NAME, VERSION);
  1079.          Embedded->Printf ("Copyright (c) 1996-97 by Marco Maccaferri. All rights reserved.\n");
  1080.          Embedded->Printf ("\026\001\013BlueWave Offline Mail System. Copyright 1990-94 by Cutting Edge Computing\n\n");
  1081.  
  1082.          Embedded->Printf ("ìDesign and Development by Marco Maccaferri.\n\n");
  1083.  
  1084.          Embedded->Printf ("\026\001\014For technical support or for more informations on LoraBBS, send mail\nto macca@arci02.bo.cnr.it or \"Marco Maccaferri\" at 2:332/402.\n\n");
  1085.  
  1086. #if defined(__BORLANDC__)
  1087.          Embedded->Printf ("\x16\x01\x0A Version: Compiled on %s at %s (Borland C++ v%d.%02X)\n", __DATE__, __TIME__, __BCPLUSPLUS__ / 0x100, __BCPLUSPLUS__ % 0x100);
  1088. #elif defined(__LINUX__)
  1089.          Embedded->Printf ("\x16\x01\x0A Version: Compiled on %s at %s (GCC/32 v%s)\n", __DATE__, __TIME__, "2.7.2");
  1090. #else
  1091.          Embedded->Printf ("\x16\x01\x0A Version: Compiled on %s at %s (WATCOM C/32 v%d.%d)\n", __DATE__, __TIME__, __WATCOMC__ / 100, (__WATCOMC__ % 100) / 10);
  1092. #endif
  1093. #if !defined(__NT__)
  1094.          Embedded->Printf ("Computer: AT-class\n");
  1095. #endif
  1096.  
  1097. #if defined(__OS2__)
  1098.          DosQuerySysInfo (11, 13, (UCHAR *)Value, sizeof (Value));
  1099.          if (Value[0] == 20L && Value[1] >= 30L)
  1100.             Embedded->Printf ("      OS: OS/2 Warp v%lu.%lu\n", Value[1] / 10L, Value[1] % 10L);
  1101.          else
  1102.             Embedded->Printf ("      OS: OS/2 Version %lu.%lu\n", Value[0], Value[1]);
  1103.  
  1104.          Value[0] = 0L;
  1105.          DosQuerySysInfo (17, 17, (UCHAR *)Value, sizeof (Value));
  1106.          if (Value[0] >= 1000000L)
  1107.             sprintf (Temp, "%lu,%03lu,%03lu", Value[0] / 1000000L, (Value[0] % 1000000L) / 1000L, (Value[0] % 1000000L) % 1000L);
  1108.          else if (Value[0] >= 1000L)
  1109.             sprintf (Temp, "%lu,%03lu", Value[0] / 1000L, Value[0] % 1000L);
  1110.          else
  1111.             sprintf (Temp, "%lu", Value[0]);
  1112.          Embedded->Printf ("  Memory: %s bytes of physical memory\n", Temp);
  1113.  
  1114.          Value[0] = 0L;
  1115.          DosQuerySysInfo (20, 20, (UCHAR *)Value, sizeof (Value));
  1116.          if (Value[0] >= 1000000L)
  1117.             sprintf (Temp, "%lu,%03lu,%03lu", Value[0] / 1000000L, (Value[0] % 1000000L) / 1000L, (Value[0] % 1000000L) % 1000L);
  1118.          else if (Value[0] >= 1000L)
  1119.             sprintf (Temp, "%lu,%03lu", Value[0] / 1000L, Value[0] % 1000L);
  1120.          else
  1121.             sprintf (Temp, "%lu", Value[0]);
  1122.          Embedded->Printf ("          %s bytes remain in heap\n\n\026\001\017", Temp);
  1123. #elif defined(__NT__)
  1124.          OsInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
  1125.          GetVersionEx (&OsInfo);
  1126.          GetSystemInfo (&SysInfo);
  1127.  
  1128.          Processor = "Unknown";
  1129.          switch (SysInfo.dwProcessorType) {
  1130.             case PROCESSOR_INTEL_386:
  1131.                Processor = "i386";
  1132.                break;
  1133.             case PROCESSOR_INTEL_486:
  1134.                Processor = "i486";
  1135.                break;
  1136.             case PROCESSOR_INTEL_PENTIUM:
  1137.                Processor = "Pentium(r)";
  1138.                break;
  1139.             case PROCESSOR_MIPS_R4000:
  1140.                Processor = "MIPS R4000";
  1141.                break;
  1142.             case PROCESSOR_ALPHA_21064:
  1143.                Processor = "Alpha 21064";
  1144.                break;
  1145.          }
  1146.          switch (SysInfo.wProcessorArchitecture) {
  1147.             case PROCESSOR_ARCHITECTURE_INTEL:
  1148.                if (SysInfo.wProcessorLevel == 3)
  1149.                   Processor = "i386";
  1150.                else if (SysInfo.wProcessorLevel == 4)
  1151.                   Processor = "i486";
  1152.                else if (SysInfo.wProcessorLevel == 5)
  1153.                   Processor = "Pentium(r)";
  1154.                break;
  1155.             case PROCESSOR_ARCHITECTURE_MIPS:
  1156.                if (SysInfo.wProcessorLevel == 0x0004)
  1157.                   Processor = "MIPS R4000";
  1158.                break;
  1159.             case PROCESSOR_ARCHITECTURE_ALPHA:
  1160.                if (SysInfo.wProcessorLevel == 21064)
  1161.                   Processor = "Alpha 21046";
  1162.                else if (SysInfo.wProcessorLevel == 21066)
  1163.                   Processor = "Alpha 21066";
  1164.                else if (SysInfo.wProcessorLevel == 21164)
  1165.                   Processor = "Alpha 21164";
  1166.                break;
  1167.             case PROCESSOR_ARCHITECTURE_PPC:
  1168.                if (SysInfo.wProcessorLevel == 1)
  1169.                   Processor = "PPC 601";
  1170.                else if (SysInfo.wProcessorLevel == 3)
  1171.                   Processor = "PPC 603";
  1172.                else if (SysInfo.wProcessorLevel == 4)
  1173.                   Processor = "PPC 604";
  1174.                else if (SysInfo.wProcessorLevel == 6)
  1175.                   Processor = "PPC 603+";
  1176.                else if (SysInfo.wProcessorLevel == 9)
  1177.                   Processor = "PPC 604+";
  1178.                else if (SysInfo.wProcessorLevel == 20)
  1179.                   Processor = "PPC 620";
  1180.                break;
  1181.          }
  1182.          Embedded->Printf ("Computer: %s (%d processors detected)\n", Processor, SysInfo.dwNumberOfProcessors);
  1183.  
  1184.          if (OsInfo.dwPlatformId == VER_PLATFORM_WIN32s)
  1185.             Embedded->Printf ("      OS: Windows %ld.%02ld w/Win32s\n", OsInfo.dwMajorVersion, OsInfo.dwMinorVersion);
  1186.          else if (OsInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
  1187.             Embedded->Printf ("      OS: Windows 95 %ld.%02ld (build %d)\n", OsInfo.dwMajorVersion, OsInfo.dwMinorVersion, LOWORD (OsInfo.dwBuildNumber));
  1188.          else if (OsInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  1189.             Embedded->Printf ("      OS: Windows NT %ld.%02ld (build %d)\n", OsInfo.dwMajorVersion, OsInfo.dwMinorVersion, LOWORD (OsInfo.dwBuildNumber));
  1190.          else
  1191.             Embedded->Printf ("      OS: Windows 95/NT\n");
  1192.  
  1193.          Embedded->Printf ("  Memory: %lu bytes remain in heap\n\n\026\001\017", GetFreeSpace (0));
  1194. #elif defined(__LINUX__)
  1195.          Embedded->Printf ("      OS: Linux (ELF)\n\n");
  1196. #elif defined(__BORLANDC__) || defined(_MSC_VER)
  1197.          inregs.h.ah = 0x30;
  1198.          intdos (&inregs, &outregs);
  1199.          if (outregs.h.al >= 20)
  1200.             Embedded->Printf ("      OS: OS/2 %d.%02d DOS Box (16 bit)\n", outregs.h.ah / 10, outregs.h.ah % 10);
  1201.          else
  1202.             Embedded->Printf ("      OS: DOS %d.%02d (16 bit)\n", outregs.h.al, outregs.h.ah);
  1203.          Embedded->Printf ("  Memory: %lu bytes remain in heap\n\n\026\001\017", coreleft ());
  1204. #else
  1205.          Embedded->Printf ("      OS: DOS/32\n\n");
  1206. #endif
  1207.  
  1208.          Embedded->DisplayFile ("version");
  1209.          break;
  1210.       }
  1211.    }
  1212. }
  1213.  
  1214. USHORT TBbs::FileExist (PSZ FileName)
  1215. {
  1216.    USHORT RetVal = FALSE;
  1217.    struct stat statbuf;
  1218.  
  1219.    if (stat (FileName, &statbuf) == 0)
  1220.       RetVal = TRUE;
  1221.  
  1222.    return (RetVal);
  1223. }
  1224.  
  1225. USHORT TBbs::Login (VOID)
  1226. {
  1227.    USHORT RetVal = FALSE, Counter, Flags, Answer;
  1228.    CHAR Temp[48], *p;
  1229.  
  1230.    Counter = 0;
  1231.    Flags = (USHORT)((FancyNames == TRUE) ? INP_FANCY|INP_FIELD : INP_FIELD);
  1232.  
  1233.    while (RetVal == FALSE && Embedded->AbortSession () == FALSE && Counter < 3) {
  1234.       if (Cfg->LoginType != 0) {
  1235.          Embedded->Printf (Language->Text(LNG_ENTERNAMEORNEW));
  1236.          Embedded->Input (Name, (USHORT)(sizeof (Name) - 1), Flags);
  1237.          if (Embedded->AbortSession () == TRUE)
  1238.             break;
  1239.          if (stricmp (Name, "New")) {
  1240.             Log->Write ("+%s is calling", Name);
  1241.             if (Status != NULL)
  1242.                Status->SetLine (0, "%s", Name);
  1243.          }
  1244.       }
  1245.       else {
  1246.          do {
  1247.             Embedded->Printf (Language->Text(LNG_ENTERNAME));
  1248.             Embedded->Input (Name, (USHORT)(sizeof (Name) - 1), Flags);
  1249.          } while (strlen (Name) < 3 && Embedded->AbortSession () == FALSE);
  1250.          if (Embedded->AbortSession () == FALSE) {
  1251.             Log->Write ("+%s is calling", Name);
  1252.             if (Status != NULL)
  1253.                Status->SetLine (0, "%s", Name);
  1254.          }
  1255.       }
  1256.  
  1257.       if (Snoop != NULL)
  1258.          Snoop->SetName (Name);
  1259.       else if (Com != NULL)
  1260.          Com->SetName (Name);
  1261.  
  1262.       RetVal = FALSE;
  1263.       if (Embedded->AbortSession () == FALSE && (Cfg->LoginType != 0 && !stricmp (Name, "New")) || (Cfg->LoginType == 0 && User->GetData (Name) == FALSE)) {
  1264.          if (Cfg->LoginType == 0 && Name[0] != '\0') {
  1265.             Log->Write ("+%s isn't in user list", Name);
  1266.             if (Status != NULL)
  1267.                Status->SetLine (0, "%s (New user)", Name);
  1268.          }
  1269.  
  1270.          if (Embedded->DisplayFile ("notfound") == FALSE)
  1271.             Embedded->Printf (Language->Text (LNG_NAMENOTFOUND), Name);
  1272.          Embedded->Printf (Language->Text (LNG_CONTINUEASNEW));
  1273.          if (Embedded->GetAnswer (ASK_DEFNO) == ANSWER_NO)
  1274.             continue;
  1275.  
  1276.          User->Clear ();
  1277.          strcpy (User->Name, Name);
  1278.          strcpy (User->RealName, Name);
  1279.          User->CreationDate = time (NULL);
  1280.          User->HotKey = FALSE;
  1281.          User->Level = Cfg->NewUserLevel;
  1282.          User->AccessFlags = Cfg->NewUserFlags;
  1283.          User->DenyFlags = Cfg->NewUserDenyFlags;
  1284.          strcpy (User->LimitClass, Cfg->NewUserLimits);
  1285.          User->ScreenWidth = 80;
  1286.          User->ScreenHeight = 24;
  1287.          User->Ansi = (UCHAR)Embedded->Ansi;
  1288.          User->Avatar = (UCHAR)Embedded->Avatar;
  1289.          User->Color = (UCHAR)Embedded->Color;
  1290.          User->InUserList = TRUE;
  1291.  
  1292.          strcpy (Temp, User->Name);
  1293.          if ((p = strtok (strlwr (Temp), " ")) != NULL) {
  1294.             User->MailBox[0] = *p;                 // La prima lettera della mailbox e'
  1295.             User->MailBox[1] = '\0';               // la prima lettera del nome
  1296.             if ((p = strtok (NULL, " ")) == NULL)  // Cerca il cognome
  1297.                p = &Temp[1];
  1298.             if (strlen (p) > 7)                    // Se la mailbox risultasse piu' di
  1299.                p[7] = '\0';                        // otto caratteri, forza gli otto caratteri
  1300.             strcat (User->MailBox, p);
  1301.          }
  1302.  
  1303.          SetUseronRecord ("New User");
  1304.          Embedded->DisplayFile ("applic");
  1305.  
  1306.          if (Embedded->AbortSession () == FALSE && Cfg->AskCity != NO)
  1307.             do {
  1308.                Embedded->Printf (Language->Text (LNG_ASKCITY));
  1309.                Embedded->Input (User->City, (USHORT)(sizeof (User->City) - 1), INP_FIELD);
  1310.             } while (User->City[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->AskCity == REQUIRED);
  1311.          if (Snoop != NULL)
  1312.             Snoop->SetCity (User->City);
  1313.          else if (Com != NULL)
  1314.             Com->SetCity (User->City);
  1315.  
  1316.          if (Embedded->AbortSession () == FALSE && Cfg->AskCompanyName != NO)
  1317.             do {
  1318.                Embedded->Printf (Language->Text(LNG_ASKCOMPANYNAME));
  1319.                Embedded->Input (User->Company, (USHORT)(sizeof (User->Company) - 1), INP_FIELD);
  1320.             } while (User->Company[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->AskCompanyName == REQUIRED);
  1321.  
  1322.          if (Embedded->AbortSession () == FALSE && Cfg->AskAddress != NO)
  1323.             do {
  1324.                Embedded->Printf (Language->Text(LNG_ASKADDRESS));
  1325.                Embedded->Input (User->Address, (USHORT)(sizeof (User->Address) - 1), INP_FIELD);
  1326.             } while (User->Address[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->AskAddress == REQUIRED);
  1327.  
  1328.          if (Embedded->AbortSession () == FALSE && Cfg->AskPhoneNumber != NO)
  1329.             do {
  1330.                Embedded->Printf (Language->Text (LNG_ASKDAYPHONE));
  1331.                Embedded->Input (User->DayPhone, (USHORT)(sizeof (User->DayPhone) - 1), INP_FIELD);
  1332.             } while (User->DayPhone[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->AskPhoneNumber == REQUIRED);
  1333.  
  1334.          if (Embedded->AbortSession () == FALSE)
  1335.             Embedded->DisplayFile ("newuser1");
  1336.  
  1337.          do {
  1338.             if (Embedded->AbortSession () == FALSE)
  1339.                do {
  1340.                   Embedded->Printf (Language->Text(LNG_ASKPASSWORD));
  1341.                   Embedded->Input (Password, (USHORT)(sizeof (Password) - 1), INP_FIELD|INP_PWD);
  1342.                } while (Password[0] == '\0' && Embedded->AbortSession () == FALSE);
  1343.  
  1344.             if (Embedded->AbortSession () == FALSE)
  1345.                do {
  1346.                   Embedded->Printf (Language->Text (LNG_REENTERPASSWORD));
  1347.                   Embedded->Input (Temp, (USHORT)(sizeof (Password) - 1), INP_FIELD|INP_PWD);
  1348.                } while (Temp[0] == '\0' && Embedded->AbortSession () == FALSE);
  1349.             if (stricmp (Temp, Password))
  1350.                Embedded->Printf (Language->Text (LNG_PASSWORDNOMATCH));
  1351.          } while (Embedded->AbortSession () == FALSE && stricmp (Temp, Password));
  1352.  
  1353.          if (Embedded->AbortSession () == FALSE) {
  1354.             User->SetPassword (Password);
  1355.             User->Add ();
  1356.             RetVal = TRUE;
  1357.          }
  1358.  
  1359.          if (Cfg->UseAnsi == YES) {
  1360.             User->Ansi = User->Color = TRUE;
  1361.             Embedded->Ansi = User->Ansi;
  1362.             Embedded->Color = User->Color;
  1363.          }
  1364.          else if (Cfg->UseAnsi == NO) {
  1365.             User->Ansi = User->Color = FALSE;
  1366.             Embedded->Ansi = User->Ansi;
  1367.             Embedded->Color = User->Color;
  1368.          }
  1369.          else if (Embedded->AbortSession () == FALSE && Cfg->UseAnsi == ASK)
  1370.             do {
  1371.                Embedded->Printf (Language->Text (LNG_ASKANSI));
  1372.                if ((Answer = Embedded->GetAnswer (ASK_DEFNO|ASK_HELP)) == ANSWER_YES) {
  1373.                   User->Ansi = User->Color = TRUE;
  1374.                   Embedded->Ansi = User->Ansi;
  1375.                   Embedded->Color = User->Color;
  1376.                }
  1377.                else if (Answer == ANSWER_HELP)
  1378.                   Embedded->DisplayFile ("why_ansi");
  1379.             } while (Answer == ANSWER_HELP && Embedded->AbortSession () == FALSE);
  1380.  
  1381.          if (User->Ansi == FALSE) {
  1382.             if (Cfg->UseAvatar == YES) {
  1383.                User->Avatar = User->Color = TRUE;
  1384.                Embedded->Avatar = User->Avatar;
  1385.                Embedded->Color = User->Color;
  1386.             }
  1387.             else if (Cfg->UseAvatar == NO) {
  1388.                User->Avatar = User->Color = FALSE;
  1389.                Embedded->Avatar = User->Avatar;
  1390.                Embedded->Color = User->Color;
  1391.             }
  1392.             else if (Embedded->AbortSession () == FALSE && Cfg->UseAvatar == ASK)
  1393.                do {
  1394.                   Embedded->Printf (Language->Text (LNG_ASKAVATAR));
  1395.                   if ((Answer = Embedded->GetAnswer (ASK_DEFNO|ASK_HELP)) == ANSWER_YES) {
  1396.                      User->Avatar = User->Color = TRUE;
  1397.                      Embedded->Avatar = User->Avatar;
  1398.                      Embedded->Color = User->Color;
  1399.                   }
  1400.                   else if (Answer == ANSWER_HELP)
  1401.                      Embedded->DisplayFile ("why_avt");
  1402.                } while (Answer == ANSWER_HELP && Embedded->AbortSession () == FALSE);
  1403.          }
  1404.  
  1405.          if (User->Ansi == TRUE || User->Avatar == TRUE) {
  1406.             if (Cfg->UseColor == YES)
  1407.                User->Color = TRUE;
  1408.             else if (Cfg->UseColor == NO)
  1409.                User->Color = FALSE;
  1410.             else if (Embedded->AbortSession () == FALSE && Cfg->UseColor == ASK)
  1411.                do {
  1412.                   Embedded->Printf (Language->Text (LNG_ASKCOLOR));
  1413.                   if ((Answer = Embedded->GetAnswer (ASK_DEFYES|ASK_HELP)) == ANSWER_YES)
  1414.                      User->Color = TRUE;
  1415.                   else if (Answer == ANSWER_HELP)
  1416.                      Embedded->DisplayFile ("why_col");
  1417.                } while (Answer == ANSWER_HELP && Embedded->AbortSession () == FALSE);
  1418.             Embedded->Color = User->Color;
  1419.  
  1420.             if (Cfg->UseFullScreenEditor == YES)
  1421.                User->FullEd = TRUE;
  1422.             else if (Cfg->UseFullScreenEditor == NO)
  1423.                User->FullEd = FALSE;
  1424.             else if (Embedded->AbortSession () == FALSE && Cfg->UseFullScreenEditor == ASK)
  1425.                do {
  1426.                   Embedded->Printf ("\n\026\001\012Do you want to use the full-screen editor");
  1427.                   if ((Answer = Embedded->GetAnswer (ASK_DEFYES|ASK_HELP)) == ANSWER_YES)
  1428.                      User->FullEd = TRUE;
  1429.                   else if (Answer == ANSWER_HELP)
  1430.                      Embedded->DisplayFile ("why_fsed");
  1431.                } while (Answer == ANSWER_HELP && Embedded->AbortSession () == FALSE);
  1432.  
  1433.             if (Cfg->UseFullScreenReader == YES)
  1434.                User->FullReader = TRUE;
  1435.             else if (Cfg->UseFullScreenReader == NO)
  1436.                User->FullReader = FALSE;
  1437.             else if (Embedded->AbortSession () == FALSE && Cfg->UseFullScreenReader == ASK)
  1438.                do {
  1439.                   Embedded->Printf ("\n\026\001\012Do you want to use the full-screen reader");
  1440.                   if ((Answer = Embedded->GetAnswer (ASK_DEFYES|ASK_HELP)) == ANSWER_YES)
  1441.                      User->FullReader = TRUE;
  1442.                   else if (Answer == ANSWER_HELP)
  1443.                      Embedded->DisplayFile ("why_fsrd");
  1444.                } while (Answer == ANSWER_HELP && Embedded->AbortSession () == FALSE);
  1445.  
  1446.             if (Cfg->UseFullScreenLists == YES)
  1447.                User->FullScreen = TRUE;
  1448.             else if (Cfg->UseFullScreenLists == NO)
  1449.                User->FullScreen = FALSE;
  1450.             if (Embedded->AbortSession () == FALSE && Cfg->UseFullScreenLists == ASK)
  1451.                do {
  1452.                   Embedded->Printf ("\n\026\001\012Do you want to use the full-screen lists");
  1453.                   if ((Answer = Embedded->GetAnswer (ASK_DEFYES|ASK_HELP)) == ANSWER_YES)
  1454.                      User->FullScreen = TRUE;
  1455.                   else if (Answer == ANSWER_HELP)
  1456.                      Embedded->DisplayFile ("why_fsls");
  1457.                } while (Answer == ANSWER_HELP && Embedded->AbortSession () == FALSE);
  1458.          }
  1459.  
  1460.          if (Embedded->AbortSession () == FALSE && Cfg->AskAlias != NO) {
  1461.             do {
  1462.                Embedded->Printf (Language->Text (LNG_ASKALIAS));
  1463.                Embedded->Input (User->RealName, (USHORT)(sizeof (User->RealName) - 1), INP_FIELD);
  1464.             } while (strlen (User->RealName) < 3 && Embedded->AbortSession () == FALSE && Cfg->AskAlias == REQUIRED);
  1465.             if (User->RealName[0] == '\0')
  1466.                strcpy (User->RealName, User->Name);
  1467.          }
  1468.  
  1469.          if (Cfg->UseHotKey == YES)
  1470.             User->HotKey = TRUE;
  1471.          else if (Cfg->UseHotKey == NO)
  1472.             User->HotKey = FALSE;
  1473.          else if (Embedded->AbortSession () == FALSE && Cfg->UseHotKey == ASK)
  1474.             do {
  1475.                Embedded->Printf (Language->Text (LNG_ASKHOTKEY));
  1476.                if ((Answer = Embedded->GetAnswer (ASK_DEFYES|ASK_HELP)) == ANSWER_YES)
  1477.                   User->HotKey = TRUE;
  1478.                else if (Answer == ANSWER_HELP)
  1479.                   Embedded->DisplayFile ("why_hot");
  1480.             } while (Answer == ANSWER_HELP && Embedded->AbortSession () == FALSE);
  1481.  
  1482.          if (Cfg->UseIBMChars == YES)
  1483.             User->IBMChars = TRUE;
  1484.          else if (Cfg->UseIBMChars == NO)
  1485.             User->IBMChars = FALSE;
  1486.          else if (Embedded->AbortSession () == FALSE && Cfg->UseIBMChars == ASK)
  1487.             do {
  1488.                Embedded->Printf (Language->Text (LNG_ASKIBMCHARS));
  1489.                if ((Answer = Embedded->GetAnswer (ASK_DEFYES|ASK_HELP)) == ANSWER_YES)
  1490.                   User->IBMChars = TRUE;
  1491.                else if (Answer == ANSWER_HELP)
  1492.                   Embedded->DisplayFile ("why_ibm");
  1493.             } while (Answer == ANSWER_HELP && Embedded->AbortSession () == FALSE);
  1494.  
  1495.          if (Embedded->AbortSession () == FALSE && Cfg->AskLines == YES)
  1496.             do {
  1497.                Embedded->Printf (Language->Text (LNG_ASKLINES));
  1498.                Embedded->Input (Temp, 2, INP_FIELD);
  1499.             } while ((atoi (Temp) < 10 || atoi (Temp) > 66) && Embedded->AbortSession () == FALSE);
  1500.          User->ScreenHeight = (USHORT)atoi (Temp);
  1501.  
  1502.          if (Cfg->UsePause == YES)
  1503.             User->MorePrompt = TRUE;
  1504.          else if (Cfg->UsePause == NO)
  1505.             User->MorePrompt = FALSE;
  1506.          else if (Embedded->AbortSession () == FALSE && Cfg->UsePause == ASK) {
  1507.             Embedded->Printf (Language->Text (LNG_ASKPAUSE));
  1508.             if ((Answer = Embedded->GetAnswer (ASK_DEFYES)) == ANSWER_YES)
  1509.                User->MorePrompt = TRUE;
  1510.          }
  1511.  
  1512.          if (Cfg->UseScreenClear == YES)
  1513.             User->ScreenClear = TRUE;
  1514.          else if (Cfg->UseScreenClear == NO)
  1515.             User->ScreenClear = FALSE;
  1516.          else if (Embedded->AbortSession () == FALSE && Cfg->UseScreenClear == ASK) {
  1517.             Embedded->Printf (Language->Text (LNG_ASKSCREENCLEAR));
  1518.             if ((Answer = Embedded->GetAnswer (ASK_DEFYES)) == ANSWER_YES)
  1519.                User->ScreenClear = TRUE;
  1520.          }
  1521.  
  1522.          if (Embedded->AbortSession () == FALSE && Cfg->AskBirthDate == YES)
  1523.             SetBirthDate ();
  1524.  
  1525.          User->MailCheck = Cfg->AskMailCheck;
  1526.          if (Embedded->AbortSession () == FALSE && Cfg->AskMailCheck == ASK) {
  1527.             Embedded->Printf (Language->Text (LNG_ASKMAILCHECK));
  1528.             if ((Answer = Embedded->GetAnswer (ASK_DEFYES)) == ANSWER_YES)
  1529.                User->MailCheck = TRUE;
  1530.          }
  1531.  
  1532.          User->NewFileCheck = Cfg->AskFileCheck;
  1533.          if (Embedded->AbortSession () == FALSE && Cfg->AskFileCheck == YES) {
  1534.             Embedded->Printf (Language->Text (LNG_ASKFILECHECK));
  1535.             if ((Answer = Embedded->GetAnswer (ASK_DEFYES)) == ANSWER_YES)
  1536.                User->NewFileCheck = TRUE;
  1537.          }
  1538.  
  1539.          if (Embedded->AbortSession () == FALSE && Cfg->AskGender != NO) {
  1540.             do {
  1541.                Embedded->Printf (Language->Text(LNG_ASKSEX));
  1542.                Embedded->Input (Cmd, 1, INP_FIELD);
  1543.                User->Sex = (UCHAR)toupper (Cmd[0]);
  1544.             } while (User->Sex != Language->Male && User->Sex != Language->Female && Embedded->AbortSession () == FALSE && Cfg->AskGender == REQUIRED);
  1545.  
  1546.             if (User->Sex == Language->Female)
  1547.                User->Sex = 1;
  1548.             else if (User->Sex == Language->Male)
  1549.                User->Sex = 0;
  1550.             else
  1551.                User->Sex = 0;
  1552.          }
  1553.  
  1554.  
  1555. /*
  1556.          if (Embedded->AbortSession () == FALSE && Cfg->CheckAnsi == YES) {
  1557.             Embedded->Printf (Language->Text(LNG_ASKANSI));
  1558.             if (Embedded->GetAnswer (ASK_DEFYES) == ANSWER_YES)
  1559.                User->Ansi = User->Color = TRUE;
  1560.          }
  1561.  
  1562.          if (Cfg->LoginType != 0 && Embedded->AbortSession () == FALSE)
  1563.             do {
  1564.                Embedded->Printf (Language->Text(LNG_ENTERNAME));
  1565.                Embedded->Input (Name, (USHORT)(sizeof (Name) - 1), Flags);
  1566.                if (Embedded->AbortSession () == FALSE && strlen (Name) >= 2) {
  1567.                   Log->Write ("+%s is calling", Name);
  1568.                   Log->Write ("+%s isn't in user list", Name);
  1569.                }
  1570.             } while (Embedded->AbortSession () == FALSE && strlen (Name) < 3);
  1571.  
  1572.          strcpy (User->Name, Name);
  1573.  
  1574.          Embedded->DisplayFile ("applic");
  1575.  
  1576.          if (Embedded->AbortSession () == FALSE && Cfg->RealName != NO) {
  1577.             do {
  1578.                Embedded->Printf (Language->Text(LNG_ASKREALNAME));
  1579.                Embedded->Input (User->RealName, (USHORT)(sizeof (User->RealName) - 1), INP_FIELD|INP_FANCY);
  1580.             } while (strlen (User->RealName) < 3 && Embedded->AbortSession () == FALSE && Cfg->RealName == REQUIRED);
  1581.             if (User->RealName[0] == '\0')
  1582.                strcpy (User->RealName, User->Name);
  1583.          }
  1584.  
  1585.          if (Embedded->AbortSession () == FALSE && Cfg->CompanyName != NO)
  1586.             do {
  1587.                Embedded->Printf (Language->Text(LNG_ASKCOMPANYNAME));
  1588.                Embedded->Input (User->Company, (USHORT)(sizeof (User->Company) - 1), INP_FIELD);
  1589.             } while (User->Company[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->CompanyName == REQUIRED);
  1590.  
  1591.          if (Embedded->AbortSession () == FALSE && Cfg->Address != NO)
  1592.             do {
  1593.                Embedded->Printf (Language->Text(LNG_ASKADDRESS));
  1594.                Embedded->Input (User->Address, (USHORT)(sizeof (User->Address) - 1), INP_FIELD);
  1595.             } while (User->Address[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->Address == REQUIRED);
  1596.  
  1597.          if (Embedded->AbortSession () == FALSE && Cfg->City != NO)
  1598.             do {
  1599.                Embedded->Printf (Language->Text(LNG_ASKCITY));
  1600.                Embedded->Input (User->City, (USHORT)(sizeof (User->City) - 1), INP_FIELD);
  1601.             } while (User->City[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->City == REQUIRED);
  1602.          if (Snoop != NULL)
  1603.             Snoop->SetCity (User->City);
  1604.          else if (Com != NULL)
  1605.             Com->SetCity (User->City);
  1606.  
  1607.          if (Embedded->AbortSession () == FALSE && Cfg->PhoneNumber != NO)
  1608.             do {
  1609.                Embedded->Printf (Language->Text(LNG_ASKDAYPHONE));
  1610.                Embedded->Input (User->DayPhone, (USHORT)(sizeof (User->DayPhone) - 1), INP_FIELD);
  1611.             } while (User->DayPhone[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->PhoneNumber == REQUIRED);
  1612.  
  1613.          if (Embedded->AbortSession () == FALSE && Cfg->Gender != NO) {
  1614.             do {
  1615.                Embedded->Printf (Language->Text(LNG_ASKSEX));
  1616.                Embedded->Input (Cmd, 1, INP_FIELD);
  1617.                User->Sex = (UCHAR)toupper (Cmd[0]);
  1618.             } while (User->Sex != Language->Male && User->Sex != Language->Female && Embedded->AbortSession () == FALSE && Cfg->Gender == REQUIRED);
  1619.  
  1620.             if (User->Sex == Language->Female)
  1621.                User->Sex = 1;
  1622.             else if (User->Sex == Language->Male)
  1623.                User->Sex = 0;
  1624.             else
  1625.                User->Sex = 0;
  1626.          }
  1627. */
  1628.  
  1629.          User->Update ();
  1630.          if (Embedded->AbortSession () == FALSE)
  1631.             Embedded->DisplayFile ("newuser2");
  1632.       }
  1633.       else {
  1634.          if (Snoop != NULL)
  1635.             Snoop->SetCity (User->City);
  1636.          else if (Com != NULL)
  1637.             Com->SetCity (User->City);
  1638.  
  1639.          SetUseronRecord ("Login");
  1640.  
  1641.          if (User->Language[0] != '\0') {
  1642.             if (Language->Load (User->Language) == TRUE) {
  1643.                Log->Write (":Loaded language %s", User->Language);
  1644.                strcpy (Menu->AltPath, Language->MenuPath);
  1645.                strcpy (Embedded->AltPath, Language->TextFiles);
  1646.                Reload = TRUE;
  1647.                if (Menu->AltPath[0] != '\0')
  1648.                   Log->Write ("   Language Menu Path = %s", Menu->AltPath);
  1649.                if (Embedded->AltPath[0] != '\0')
  1650.                   Log->Write ("   Language Text Files Path = %s", Embedded->AltPath);
  1651.             }
  1652.             else {
  1653.                Log->Write ("!Failed to load language %s", User->Language);
  1654.                Language->Load ("default.lng");
  1655.                strcpy (Menu->AltPath, Language->MenuPath);
  1656.                strcpy (Embedded->AltPath, Language->TextFiles);
  1657.             }
  1658.          }
  1659.  
  1660.          if (Cfg->LoginType == 0) {
  1661.             Embedded->Printf (Language->Text(LNG_USERFROMCITY), Name, User->City);
  1662.             Embedded->Printf (Language->Text(LNG_DEFYESNO));
  1663.             Embedded->Input (Cmd, 1, INP_FIELD);
  1664.             if (toupper (Cmd[0]) == 'N' && Log != NULL)
  1665.                Log->Write ("!User temporarily brain-lapsed");
  1666.          }
  1667.  
  1668.          Password[0] = '\0';
  1669.          if (Cfg->LoginType != 0 || toupper (Cmd[0]) != 'N') {
  1670.             Embedded->Printf (Language->Text(LNG_ENTERPASSWORD));
  1671.             Embedded->Input (Password, (USHORT)(sizeof (Password) - 1), INP_FIELD|INP_PWD);
  1672.          }
  1673.       }
  1674.  
  1675.       if (Embedded->AbortSession () == FALSE && Password[0] != '\0') {
  1676.          if (User->CheckPassword (Password) == FALSE) {
  1677.             Embedded->Printf (Language->Text(LNG_INVALIDPASSWORD));
  1678.             Log->Write ("!Invalid Password (%s)", strlwr (Password));
  1679.             Counter++;
  1680.          }
  1681.          else
  1682.             RetVal = TRUE;
  1683.       }
  1684.    }
  1685.  
  1686.    if (RetVal == TRUE && Status != NULL)
  1687.       Status->SetLine (0, "%s from %s", User->Name, User->City);
  1688.  
  1689.    return (RetVal);
  1690. }
  1691.  
  1692. VOID TBbs::IEMSILogin (VOID)
  1693. {
  1694.    CHAR Temp[48], *p;
  1695.  
  1696.    User->CreationDate = time (NULL);
  1697.    User->HotKey = FALSE;
  1698.    User->Level = Cfg->NewUserLevel;
  1699.    User->AccessFlags = Cfg->NewUserFlags;
  1700.    User->DenyFlags = Cfg->NewUserDenyFlags;
  1701.    strcpy (User->LimitClass, Cfg->NewUserLimits);
  1702.    User->ScreenWidth = 80;
  1703.    User->ScreenHeight = 24;
  1704.    if (User->Ansi == TRUE || User->Avatar == TRUE)
  1705.       User->Color = TRUE;
  1706.  
  1707.    Embedded->DisplayFile ("applic");
  1708.  
  1709.    if (Embedded->AbortSession () == FALSE && Cfg->AskCity != NO)
  1710.       do {
  1711.          Embedded->Printf (Language->Text (LNG_ASKCITY));
  1712.          Embedded->Input (User->City, (USHORT)(sizeof (User->City) - 1), INP_FIELD);
  1713.       } while (User->City[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->AskCity == REQUIRED);
  1714.    if (Snoop != NULL)
  1715.       Snoop->SetCity (User->City);
  1716.    else if (Com != NULL)
  1717.       Com->SetCity (User->City);
  1718.  
  1719.    if (Embedded->AbortSession () == FALSE && Cfg->AskCompanyName != NO)
  1720.       do {
  1721.          Embedded->Printf (Language->Text(LNG_ASKCOMPANYNAME));
  1722.          Embedded->Input (User->Company, (USHORT)(sizeof (User->Company) - 1), INP_FIELD);
  1723.       } while (User->Company[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->AskCompanyName == REQUIRED);
  1724.  
  1725.    if (Embedded->AbortSession () == FALSE && Cfg->AskAddress != NO)
  1726.       do {
  1727.          Embedded->Printf (Language->Text(LNG_ASKADDRESS));
  1728.          Embedded->Input (User->Address, (USHORT)(sizeof (User->Address) - 1), INP_FIELD);
  1729.       } while (User->Address[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->AskAddress == REQUIRED);
  1730.  
  1731.    if (Embedded->AbortSession () == FALSE && Cfg->AskPhoneNumber != NO)
  1732.       do {
  1733.          Embedded->Printf (Language->Text (LNG_ASKDAYPHONE));
  1734.          Embedded->Input (User->DayPhone, (USHORT)(sizeof (User->DayPhone) - 1), INP_FIELD);
  1735.       } while (User->DayPhone[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->AskPhoneNumber == REQUIRED);
  1736.  
  1737.    if (Embedded->AbortSession () == FALSE && Cfg->AskAlias != NO) {
  1738.       do {
  1739.          Embedded->Printf (Language->Text (LNG_ASKALIAS));
  1740.          Embedded->Input (User->RealName, (USHORT)(sizeof (User->RealName) - 1), INP_FIELD);
  1741.       } while (strlen (User->RealName) < 3 && Embedded->AbortSession () == FALSE && Cfg->AskAlias == REQUIRED);
  1742.       if (User->RealName[0] == '\0')
  1743.          strcpy (User->RealName, User->Name);
  1744.    }
  1745.  
  1746. /*
  1747.    if (Embedded->AbortSession () == FALSE && Cfg->CompanyName != NO)
  1748.       do {
  1749.          Embedded->Printf (Language->Text(LNG_ASKCOMPANYNAME));
  1750.          Embedded->Input (User->Company, (USHORT)(sizeof (User->Company) - 1), INP_FIELD);
  1751.       } while (User->Company[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->CompanyName == REQUIRED);
  1752.  
  1753.    if (Embedded->AbortSession () == FALSE && Cfg->Address != NO)
  1754.       do {
  1755.          Embedded->Printf (Language->Text(LNG_ASKADDRESS));
  1756.          Embedded->Input (User->Address, (USHORT)(sizeof (User->Address) - 1), INP_FIELD);
  1757.       } while (User->Address[0] == '\0' && Embedded->AbortSession () == FALSE && Cfg->Address == REQUIRED);
  1758.  
  1759.    if (Embedded->AbortSession () == FALSE && Cfg->Gender != NO) {
  1760.       do {
  1761.          Embedded->Printf (Language->Text(LNG_ASKSEX));
  1762.          Embedded->Input (Cmd, 1, INP_FIELD);
  1763.          User->Sex = (UCHAR)toupper (Cmd[0]);
  1764.       } while (User->Sex != Language->Male && User->Sex != Language->Female && Embedded->AbortSession () == FALSE && Cfg->Gender == REQUIRED);
  1765.  
  1766.       if (User->Sex == Language->Female)
  1767.          User->Sex = 1;
  1768.       else if (User->Sex == Language->Male)
  1769.          User->Sex = 0;
  1770.       else
  1771.          User->Sex = 0;
  1772.    }
  1773. */
  1774.  
  1775.    strcpy (Temp, User->Name);
  1776.    if ((p = strtok (strlwr (Temp), " ")) != NULL) {
  1777.       User->MailBox[0] = *p;                 // La prima lettera della mailbox e'
  1778.       User->MailBox[1] = '\0';               // la prima lettera del nome
  1779.       if ((p = strtok (NULL, " ")) == NULL)  // Cerca il cognome
  1780.          p = &Temp[1];
  1781.       if (strlen (p) > 7)                    // Se la mailbox risultasse piu' di
  1782.          p[7] = '\0';                        // otto caratteri, forza gli otto caratteri
  1783.       strcat (User->MailBox, p);
  1784.    }
  1785. }
  1786.  
  1787. VOID TBbs::CheckBirthday (VOID)
  1788. {
  1789.    struct dosdate_t d_date;
  1790.  
  1791.    _dos_getdate (&d_date);
  1792.    if (User->BirthDay == d_date.day && User->BirthMonth == d_date.month)
  1793.       Embedded->DisplayFile ("birthday");
  1794. }
  1795.  
  1796. VOID TBbs::Run (VOID)
  1797. {
  1798.    USHORT Logged, Executed, Manual, Hangup;
  1799.    USHORT FirstTime, DoTimeWarn, Flags;
  1800.    ULONG CallLen;
  1801.    class TStatistics *Stats;
  1802.    class TDetect *Detect;
  1803.    class TEvents *Events;
  1804.    class TLimits *Limits;
  1805.  
  1806.    Hangup = FALSE;
  1807.    Logged = Manual = FALSE;
  1808.    StartCall = time (NULL);
  1809.    User = new TUser (Cfg->UserFile);
  1810. //   Task = Cfg->TaskNumber;
  1811.    SetUseronRecord ("Login");
  1812.  
  1813.    Language->Load ("default.lng");
  1814.    strcpy (Embedded->AltPath, Language->TextFiles);
  1815.  
  1816.    if (Status != NULL)
  1817.       Status->Clear ();
  1818.  
  1819.    Pause (50);
  1820.  
  1821.    if (User != NULL && Language != NULL && Embedded != NULL) {
  1822.       Embedded->Task = Task;
  1823.       Embedded->Com = Com;
  1824.       Embedded->Snoop = Snoop;
  1825.       Embedded->User = User;
  1826.       Embedded->Language = Language;
  1827.       Embedded->Cfg = Cfg;
  1828.       Embedded->Log = Log;
  1829.       strcpy (Embedded->Path, Cfg->TextFiles);
  1830.       Embedded->StartCall = StartCall;
  1831.       Embedded->CarrierSpeed = Speed;
  1832.  
  1833.       if (Local == FALSE) {
  1834.          if ((Detect = new TDetect) != NULL) {
  1835.             Detect->Task = Task;
  1836.             Detect->Com = Com;
  1837.             Detect->Cfg = Cfg;
  1838.             Detect->Log = Log;
  1839.             Detect->Events = Events;
  1840.             Detect->Speed = Speed;
  1841.             Detect->Progress = Progress;
  1842.             Detect->MailerStatus = MailerStatus;
  1843.             Detect->Status = Status;
  1844.  
  1845.             Detect->Terminal ();
  1846.             if (Embedded->AbortSession () == TRUE && Log != NULL)
  1847.                Log->Write ("!Carrier lost");
  1848.  
  1849.             Embedded->Ansi = Detect->Ansi;
  1850.             Embedded->Avatar = Detect->Avatar;
  1851.             Embedded->Rip = Detect->Rip;
  1852.             if (Embedded->Ansi == TRUE || Embedded->Avatar == TRUE)
  1853.                Embedded->Color = TRUE;
  1854.             Remote = Detect->Remote;
  1855.  
  1856.             if (Detect->IEMSI == TRUE) {
  1857.                Log->Write ("*Detected IEMSI login");
  1858.                Log->Write (":  %s from %s", Detect->Name, Detect->City);
  1859.                strcpy (Name, Detect->Name);
  1860.  
  1861.                Log->Write ("+%s is calling", Name);
  1862.                if (Status != NULL)
  1863.                   Status->SetLine (0, "%s from %s", Detect->Name, Detect->City);
  1864.  
  1865.                if (User->GetData (Name) == FALSE) {
  1866.                   Log->Write ("+%s isn't in user list", Name);
  1867.                   User->Clear ();
  1868.                   strcpy (User->Name, Name);
  1869.                   strcpy (User->RealName, Detect->RealName);
  1870.                   strcpy (User->City, Detect->City);
  1871.  
  1872.                   User->Ansi = Detect->Ansi;
  1873.                   User->Avatar = Detect->Avatar;
  1874.                   if (User->Ansi == TRUE && User->Avatar == TRUE)
  1875.                      User->Color = TRUE;
  1876.                   User->SetPassword (Detect->Password);
  1877.                   User->Add ();
  1878.  
  1879.                   Embedded->DisplayFile ("Logo");
  1880.                   IEMSILogin ();
  1881.                   if (Embedded->AbortSession () == TRUE && Log != NULL)
  1882.                      Log->Write ("!Carrier lost");
  1883.  
  1884.                   User->Update ();
  1885.                   Logged = TRUE;
  1886.                }
  1887.                else {
  1888.                   Logged = TRUE;
  1889.                   if (User->Language[0] != '\0') {
  1890.                      if (Language->Load (User->Language) == TRUE) {
  1891.                         Log->Write (":Loaded language %s", User->Language);
  1892.                         strcpy (Menu->AltPath, Language->MenuPath);
  1893.                         strcpy (Embedded->AltPath, Language->TextFiles);
  1894.                         Reload = TRUE;
  1895.                         if (Menu->AltPath[0] != '\0')
  1896.                            Log->Write ("   Language Menu Path = %s", Menu->AltPath);
  1897.                         if (Embedded->AltPath[0] != '\0')
  1898.                            Log->Write ("   Language Text Files Path = %s", Embedded->AltPath);
  1899.                      }
  1900.                      else {
  1901.                         Log->Write ("!Failed to load language %s", User->Language);
  1902.                         Language->Load ("default.lng");
  1903.                         strcpy (Menu->AltPath, Language->MenuPath);
  1904.                         strcpy (Embedded->AltPath, Language->TextFiles);
  1905.                      }
  1906.                   }
  1907.                   if (User->CheckPassword (Detect->Password) == FALSE) {
  1908.                      Log->Write ("!Invalid Password (%s)", strlwr (Detect->Password));
  1909.                      Logged = Manual = FALSE;
  1910.                   }
  1911.                   else
  1912.                      Embedded->DisplayFile ("logo");
  1913.                }
  1914.  
  1915.                User->Ansi = Detect->Ansi;
  1916.                User->Avatar = Detect->Avatar;
  1917.                if (User->Ansi == TRUE && User->Avatar == TRUE)
  1918.                   User->Color = TRUE;
  1919.                User->FullEd = Detect->FullEd;
  1920.                User->IBMChars = Detect->IBMChars;
  1921.                User->MorePrompt = Detect->MorePrompt;
  1922.                User->HotKey = Detect->HotKeys;
  1923.                User->ScreenClear = Detect->ScreenClear;
  1924.                User->MailCheck = Detect->MailCheck;
  1925.                User->NewFileCheck = Detect->FileCheck;
  1926.             }
  1927.             else if (Detect->Remote != REMOTE_USER)
  1928.                Hangup = TRUE;
  1929.             delete Detect;
  1930.          }
  1931.       }
  1932.       else {
  1933.          // In locale viene forzata l'emulazione ANSI, visto che tutti i componenti
  1934.          // locali possono visualizzare i codici ANSI senza problemi.
  1935.          Embedded->Ansi = Embedded->Color = TRUE;
  1936.          Remote = REMOTE_USER;
  1937.       }
  1938.  
  1939.       if (Hangup == FALSE && Remote == REMOTE_USER) {
  1940.          Embedded->TimeLimit = 10;
  1941.          if ((Events = new TEvents (Cfg->SchedulerFile)) != NULL) {
  1942.             Events->Load ();
  1943.             Events->TimeToNext ();
  1944.             if (Embedded->TimeLimit > Events->TimeRemain)
  1945.                Embedded->TimeLimit = Events->TimeRemain;
  1946.             delete Events;
  1947.          }
  1948.  
  1949.          if (Logged == FALSE && Manual == FALSE) {
  1950.             Embedded->DisplayFile ("logo");
  1951.             Logged = Login ();
  1952.             if (Embedded->AbortSession () == TRUE && Log != NULL)
  1953.                Log->Write ("!Carrier lost");
  1954.             Manual = TRUE;
  1955.          }
  1956.  
  1957.          if (Logged == TRUE) {
  1958.             Embedded->Ansi = User->Ansi;
  1959.             Embedded->Avatar = User->Avatar;
  1960.             Embedded->Color = User->Color;
  1961.             Embedded->HotKey = User->HotKey;
  1962.  
  1963.             if (Snoop != NULL) {
  1964.                Snoop->SetName (User->Name);
  1965.                Snoop->SetCity (User->City);
  1966.             }
  1967.             else if (Com != NULL) {
  1968.                Com->SetName (User->Name);
  1969.                Com->SetCity (User->City);
  1970.             }
  1971.  
  1972.             // Determina se e' passato un giorno calcolando quanti giorni
  1973.             // sono passati secondo la unix date, se il numero di giorni
  1974.             // dell'ultima chiamata e' diverso da oggi significa che si deve
  1975.             // azzerare tutto.
  1976.             if ((User->LastCall / 86400L) != (time (NULL) / 86400L)) {
  1977.                User->TodayTime = 0;
  1978.                User->FilesToday = 0;
  1979.                User->BytesToday = 0L;
  1980.                Log->Write (":Daily Time/DL Zeroed");
  1981.             }
  1982.  
  1983.             SetUseronRecord ("Login");
  1984.             User->TotalCalls++;
  1985.             User->Update ();
  1986.  
  1987. //            if ((Limits = new TLimits (Cfg->SystemPath)) != NULL) {
  1988. //               if (Limits->Read (User->LimitClass) == TRUE) {
  1989. //                  if (Limits->CallTimeLimit != 0 && Embedded->TimeLimit > Limits->CallTimeLimit)
  1990. //                     Embedded->TimeLimit = Limits->CallTimeLimit;
  1991. //                  if (Limits->DayTimeLimit != 0 && (Embedded->TimeLimit + User->TodayTime) > Limits->DayTimeLimit)
  1992. //                     Embedded->TimeLimit = (USHORT)(Limits->DayTimeLimit - User->TodayTime);
  1993. //               }
  1994. //               delete Limits;
  1995. //            }
  1996.             DoTimeWarn = FALSE;
  1997.             if ((Limits = new TLimits (Cfg->SystemPath)) != NULL) {
  1998.                if (Limits->Read (User->LimitClass) == TRUE) {
  1999.                   User->Level = Limits->Level;
  2000.                   User->AccessFlags = Limits->Flags;
  2001.                   User->DenyFlags = Limits->DenyFlags;
  2002.                   Embedded->TimeLimit = Limits->CallTimeLimit;
  2003.                   if (Limits->DayTimeLimit != 0 && (Embedded->TimeLimit + User->TodayTime) > Limits->DayTimeLimit)
  2004.                      Embedded->TimeLimit = (USHORT)(Limits->DayTimeLimit - User->TodayTime);
  2005.                }
  2006.                delete Limits;
  2007.             }
  2008.             if (TimeLimit != 0) {
  2009.                if (Embedded->TimeLimit > TimeLimit) {
  2010.                   DoTimeWarn = TRUE;
  2011.                   Embedded->TimeLimit = TimeLimit;
  2012.                }
  2013.             }
  2014.             else if ((Events = new TEvents (Cfg->SchedulerFile)) != NULL) {
  2015.                Events->Load ();
  2016.                Events->TimeToNext ();
  2017.                if (Embedded->TimeLimit > Events->TimeRemain) {
  2018.                   DoTimeWarn = TRUE;
  2019.                   Embedded->TimeLimit = Events->TimeRemain;
  2020.                }
  2021.                delete Events;
  2022.             }
  2023.  
  2024.             if (Log != NULL && Embedded->TimeLimit != 0)
  2025.                Log->Write ("#Given %u mins (%s)", Embedded->TimeLimit, User->LimitClass);
  2026.  
  2027.             if (Status != NULL)
  2028.                Status->SetLine (1, "Level: %u (%s)  Time: %lu", User->Level, User->LimitClass, Embedded->TimeRemain ());
  2029.  
  2030.             if ((EMail = new TEMail) != NULL) {
  2031.                EMail->Cfg = Cfg;
  2032.                EMail->Embedded = Embedded;
  2033.                EMail->Language = Language;
  2034.                EMail->Log = Log;
  2035.                EMail->User = User;
  2036.                EMail->Storage = Cfg->MailStorage;
  2037.                if (Cfg->MailPath[0] != '\0')
  2038.                   strcpy (EMail->BasePath, Cfg->MailPath);
  2039.             }
  2040.  
  2041.             if ((Message = new TMessage (Cfg->SystemPath)) != NULL) {
  2042.                Message->Cfg = Cfg;
  2043.                Message->Embedded = Embedded;
  2044.                Message->Language = Language;
  2045.                Message->Log = Log;
  2046.                Message->User = User;
  2047.                Message->ShowKludges = User->Kludges;
  2048.                Message->OpenArea (User->LastMsgArea);
  2049.                Embedded->MsgArea = Message->Current;
  2050.             }
  2051.  
  2052.             if ((Library = new TLibrary (Cfg->SystemPath)) != NULL) {
  2053.                Library->Task = Task;
  2054.                Library->Cfg = Cfg;
  2055.                Library->Embedded = Embedded;
  2056.                Library->Log = Log;
  2057.                Library->User = User;
  2058.                Library->CarrierSpeed = Speed;
  2059.                Library->Progress = Progress;
  2060.                Library->Language = Language;
  2061.                if (Library->Current != NULL) {
  2062.                   if (Library->Current->Read (User->LastFileArea) == FALSE) {
  2063.                      if (Library->Current->First () == FALSE)
  2064.                         Library->Current->New ();
  2065.                   }
  2066.                   if (Library->Current->Key[0] != '\0') {
  2067.                      Log->Write (":File Area: %s - %s", Library->Current->Key, Library->Current->Display);
  2068.                      if (Library->Current->Download[strlen (Library->Current->Download) - 1] != '\\')
  2069.                         strcat (Library->Current->Download, "\\");
  2070.                      if (Library->Current->Upload[strlen (Library->Current->Upload) - 1] != '\\')
  2071.                         strcat (Library->Current->Upload, "\\");
  2072.                   }
  2073.                }
  2074.                Embedded->FileArea = Library->Current;
  2075.             }
  2076.  
  2077.             if ((Stats = new TStatistics (Cfg->SystemPath)) != NULL) {
  2078.                Stats->Read (Task);
  2079.                Stats->Calls++;
  2080.                Stats->TodayCalls++;
  2081.                Stats->TotalCalls++;
  2082.                Stats->Update ();
  2083.                delete Stats;
  2084.             }
  2085.  
  2086.             Embedded->DisplayFile ("welcome");
  2087.  
  2088.             if (EMail != NULL && User->MailCheck == TRUE)
  2089.                EMail->CheckUnread ();
  2090.  
  2091.             CheckBirthday ();
  2092.             Embedded->DisplayFile ("news");
  2093.             if (DoTimeWarn == TRUE)
  2094.                Embedded->DisplayFile ("timewarn");
  2095.  
  2096.             FirstTime = TRUE;
  2097.             if (Menu != NULL) {
  2098.                strcpy (Menu->Path, Cfg->MenuPath);
  2099.                Reload = TRUE;
  2100.                strcpy (MenuName, Cfg->MainMenu);
  2101.  
  2102.                strcpy (Menu->AltPath, Language->MenuPath);
  2103.                strcpy (Embedded->AltPath, Language->TextFiles);
  2104.  
  2105.                while (Embedded->AbortSession () == FALSE && Logoff == FALSE) {
  2106.                   SetUseronRecord ("Browsing");
  2107.  
  2108.                   if (Reload == TRUE) {
  2109.                      FirstTime = TRUE;
  2110.                      if (Menu->Load (MenuName) == FALSE) {
  2111.                         Log->Write ("!Can't load menu: %s", MenuName);
  2112.                         if (!stricmp (MenuName, Cfg->MainMenu))
  2113.                            Logoff = TRUE;
  2114.                         if (Stack.Last () != NULL) {
  2115.                            if (!strcmp (MenuName, (PSZ)Stack.Value ()))
  2116.                               Stack.Remove ();
  2117.                         }
  2118.                      }
  2119.                      Reload = FALSE;
  2120.                   }
  2121.  
  2122.                   if (Logoff == FALSE) {
  2123.                      // Imposta di default il modo hotkey normale
  2124.                      Flags = INP_HOTKEY;
  2125.  
  2126.                      // Esegue il loop per la visualizzazione del menu' correntemente
  2127.                      // caricato in memoria.
  2128.                      if (Menu->First () == TRUE)
  2129.                         do {
  2130.                            if (User->Level >= Menu->Level) {
  2131.                               if ((User->AccessFlags & Menu->AccessFlags) == Menu->AccessFlags) {
  2132.                                  if (Menu->FirstTime == FALSE || FirstTime == TRUE) {
  2133.                                     if (Menu->Display[0] != '\0')
  2134.                                        Embedded->DisplayPrompt (Menu->Display, Menu->Color, Menu->Hilight, FALSE);
  2135.                                  }
  2136.                                  if (Menu->Command == MNU_APPENDMENU)
  2137.                                     Menu->Automatic = Menu->FirstTime = TRUE;
  2138.                                  if (Menu->Automatic == TRUE && (Menu->FirstTime == FALSE || FirstTime == TRUE)) {
  2139.                                     if (Com != NULL)
  2140.                                        Com->UnbufferBytes ();
  2141.                                     if (Snoop != NULL)
  2142.                                        Snoop->UnbufferBytes ();
  2143.                                     ExecuteCommand (Menu);
  2144.                                  }
  2145.                                  // Verifica se c'e' il comando di lettura di messaggi
  2146.                                  // individuali associato ad un numero, nel qual caso
  2147.                                  // disabilita l'hotkey per gli input numerici.
  2148.                                  if ((Menu->Command == MNU_MSGINDIVIDUAL || Menu->Command == MNU_MAILINDIVIDUAL) && isdigit (Menu->Key[0]))
  2149.                                     Flags |= INP_NONUMHOT;
  2150.                               }
  2151.                            }
  2152.                         } while (Menu->Next () == TRUE);
  2153.  
  2154.                      // Se il tempo rimasto e' minore di 3 minuti, visualizza un
  2155.                      // avvertimento per l'utente.
  2156.                      if (Embedded->TimeRemain () <= 3)
  2157.                         Embedded->Printf ("\n\026\001\015You only have %lu minute(s) left\n", Embedded->TimeRemain ());
  2158.  
  2159.                      FirstTime = FALSE;
  2160.                      if (Status != NULL) {
  2161.                         Status->SetLine (0, "%s from %s", User->Name, User->City);
  2162.                         Status->SetLine (1, "Level: %u (%s)  Time: %lu", User->Level, User->LimitClass, Embedded->TimeRemain ());
  2163.                      }
  2164.  
  2165.                      Embedded->DisplayPrompt (Menu->Prompt, Menu->PromptColor, Menu->PromptHilight, TRUE);
  2166.                      Embedded->Input (Cmd, (USHORT)(sizeof (Cmd) - 1), Flags);
  2167.  
  2168.                      if (Embedded->AbortSession () == FALSE) {
  2169.                         Executed = FALSE;
  2170.                         if (Menu->First () == TRUE)
  2171.                            do {
  2172.                               if (User->Level >= Menu->Level && Menu->Key[0] != '\0') {
  2173.                                  if ((User->AccessFlags & Menu->AccessFlags) == Menu->AccessFlags) {
  2174.                                     if (!stricmp (Menu->Key, Cmd) || (Cmd[0] == '\0' && !strcmp (Menu->Key, "|")) || Menu->Key[0] == Cmd[0]) {
  2175.                                        ExecuteCommand (Menu);
  2176.                                        Executed = TRUE;
  2177.                                     }
  2178.                                  }
  2179.                               }
  2180.                            } while (Menu->Next () == TRUE);
  2181.  
  2182.                         if (Executed == FALSE)
  2183.                            Embedded->Printf (Language->Text(LNG_MENUERROR));
  2184.                      }
  2185.                   }
  2186.                }
  2187.                if (Embedded->AbortSession () == TRUE && Log != NULL)
  2188.                   Log->Write ("!Carrier lost");
  2189.             }
  2190.  
  2191.             if (Embedded->AbortSession () == FALSE && Logoff == TRUE) {
  2192.                if (Embedded->DisplayFile ("logoff") == FALSE)
  2193.                   Embedded->DisplayFile ("byebye");
  2194.             }
  2195.  
  2196.             if (Library != NULL) {
  2197.                delete Library;
  2198.                Embedded->FileArea = NULL;
  2199.             }
  2200.             if (Message != NULL) {
  2201.                delete Message;
  2202.                Embedded->MsgArea = NULL;
  2203.             }
  2204.          }
  2205.  
  2206.          if (Name[0] != '\0') {
  2207.             CallLen = (time (NULL) - StartCall) / 60L;
  2208.  
  2209.             User->LastCall = time (NULL);
  2210.             User->TodayTime += CallLen;
  2211.             User->WeekTime += CallLen;
  2212.             User->MonthTime += CallLen;
  2213.             User->YearTime += CallLen;
  2214.  
  2215.             if (User->Update () == FALSE)
  2216.                Log->Write ("|Can't update user's record");
  2217.             Log->Write ("+%s off-line. Calls=%ld, Len=%ld", Name, User->TotalCalls, CallLen);
  2218.          }
  2219.       }
  2220.    }
  2221.  
  2222.    DisableUseronRecord ();
  2223. }
  2224.  
  2225. // ----------------------------------------------------------------------
  2226.  
  2227. TListings::TListings (void)
  2228. {
  2229. }
  2230.  
  2231. TListings::~TListings (void)
  2232. {
  2233. }
  2234.  
  2235. VOID TListings::Begin (VOID)
  2236. {
  2237. }
  2238.  
  2239. USHORT TListings::DrawScreen (VOID)
  2240. {
  2241.    USHORT i;
  2242.  
  2243.    i = 0;
  2244.    do {
  2245.       pld = (LISTDATA *)Data.Value ();
  2246.       PrintLine ();
  2247.       i++;
  2248.    } while (Data.Next () != NULL && i < (User->ScreenHeight - 6));
  2249.  
  2250.    return (i);
  2251. }
  2252.  
  2253. VOID TListings::Down (VOID)
  2254. {
  2255.    USHORT i;
  2256.  
  2257.    if (List.Next () != NULL) {
  2258.       List.Previous ();
  2259.       RemoveCursor (y);
  2260.       List.Next ();
  2261.       PrintCursor (++y);
  2262.       Data.Next ();
  2263.    }
  2264.    else if (Data.Next () != NULL) {
  2265.       Embedded->PrintfAt (4, 1, "");
  2266.       for (i = 0; i < (User->ScreenHeight - 6); i++)
  2267.          Embedded->Printf ("\x1B[K\n");
  2268.       List.Clear ();
  2269.       Embedded->PrintfAt (4, 1, "");
  2270.       i = 0;
  2271.       do {
  2272.          pld = (LISTDATA *)Data.Value ();
  2273.          PrintLine ();
  2274.          List.Add (pld->Key, (USHORT)(strlen (pld->Key) + 1));
  2275.       } while (Data.Next () != NULL && ++i < (User->ScreenHeight - 6));
  2276.       for (y = 0; y < i; y++)
  2277.          Data.Previous ();
  2278.       y = 4;
  2279.       List.First ();
  2280.       PrintCursor (y);
  2281.    }
  2282. }
  2283.  
  2284. VOID TListings::PageDown (VOID)
  2285. {
  2286.    USHORT i;
  2287.  
  2288.    RemoveCursor (y);
  2289.    while (List.Next () != NULL) {
  2290.       Data.Next ();
  2291.       y++;
  2292.    }
  2293.  
  2294.    if (Data.Next () != NULL) {
  2295.       Embedded->PrintfAt (4, 1, "");
  2296.       for (i = 0; i < (User->ScreenHeight - 6); i++)
  2297.          Embedded->Printf ("\x1B[K\n");
  2298.       List.Clear ();
  2299.       Embedded->PrintfAt (4, 1, "");
  2300.       i = 0;
  2301.       do {
  2302.          pld = (LISTDATA *)Data.Value ();
  2303.          PrintLine ();
  2304.          List.Add (pld->Key, (USHORT)(strlen (pld->Key) + 1));
  2305.       } while (Data.Next () != NULL && ++i < (User->ScreenHeight - 6));
  2306.       for (y = 0; y < i; y++)
  2307.          Data.Previous ();
  2308.       y = 4;
  2309.       List.First ();
  2310.    }
  2311.  
  2312.    PrintCursor (y);
  2313. }
  2314.  
  2315. VOID TListings::DownloadTag (VOID)
  2316. {
  2317. }
  2318.  
  2319. VOID TListings::Exit (VOID)
  2320. {
  2321.    End = TRUE;
  2322. }
  2323.  
  2324. VOID TListings::Tag (VOID)
  2325. {
  2326. }
  2327.  
  2328. VOID TListings::PageUp (VOID)
  2329. {
  2330.    USHORT i;
  2331.  
  2332.    RemoveCursor (y);
  2333.    while (List.Previous () != NULL) {
  2334.       Data.Previous ();
  2335.       y--;
  2336.    }
  2337.    if (Data.Previous () != NULL) {
  2338.       Embedded->PrintfAt (4, 1, "");
  2339.       for (i = 0; i < (User->ScreenHeight - 6); i++)
  2340.          Embedded->Printf ("\x1B[K\n");
  2341.       for (i = 0; i < (User->ScreenHeight - 6 - 1); i++)
  2342.          Data.Previous ();
  2343.       List.Clear ();
  2344.       Embedded->PrintfAt (4, 1, "");
  2345.       i = 0;
  2346.       do {
  2347.          pld = (LISTDATA *)Data.Value ();
  2348.          PrintLine ();
  2349.          List.Add (pld->Key, (USHORT)(strlen (pld->Key) + 1));
  2350.          i++;
  2351.       } while (Data.Next () != NULL && i < (User->ScreenHeight - 6));
  2352.       Data.Previous ();
  2353.       y = (USHORT)(4 + User->ScreenHeight - 6 - 1);
  2354.       List.Last ();
  2355.    }
  2356.  
  2357.    PrintCursor (y);
  2358. }
  2359.  
  2360. VOID TListings::PrintTitles (VOID)
  2361. {
  2362. }
  2363.  
  2364. VOID TListings::PrintLine (VOID)
  2365. {
  2366. }
  2367.  
  2368. VOID TListings::PrintCursor (USHORT y)
  2369. {
  2370.    y = y;
  2371. }
  2372.  
  2373. VOID TListings::RemoveCursor (USHORT y)
  2374. {
  2375.    y = y;
  2376. }
  2377.  
  2378. VOID TListings::Select (VOID)
  2379. {
  2380.    RetVal = End = TRUE;
  2381. }
  2382.  
  2383. USHORT TListings::Run (VOID)
  2384. {
  2385.    USHORT i, t;
  2386.  
  2387.    RetVal = FALSE;
  2388.    Found = FALSE;
  2389.    y = 4;
  2390.  
  2391.    Begin ();
  2392.  
  2393.    if ((pld = (LISTDATA *)Data.Value ()) != NULL) {
  2394.       End = FALSE;
  2395.       Titles = Redraw = TRUE;
  2396.  
  2397.       while (End == FALSE && Embedded->AbortSession () == FALSE) {
  2398.          if (Redraw == TRUE) {
  2399.             while (List.Previous () != NULL)
  2400.                Data.Previous ();
  2401.  
  2402.             if (Titles == TRUE) {
  2403.                PrintTitles ();
  2404.                Titles = FALSE;
  2405.             }
  2406.  
  2407.             i = DrawScreen ();
  2408.  
  2409.             for (t = (USHORT)(i + 4 - 1); t > y; t--) {
  2410.                List.Previous ();
  2411.                Data.Previous ();
  2412.             }
  2413.  
  2414.             if (i < (User->ScreenHeight - 6)) {
  2415.                do {
  2416.                   Embedded->Printf ("\n");
  2417.                   i++;
  2418.                } while (i < (User->ScreenHeight - 6));
  2419.             }
  2420.             else
  2421.                Data.Previous ();
  2422.  
  2423.             PrintCursor (y);
  2424.             Redraw = Titles = FALSE;
  2425.          }
  2426.  
  2427.          if (Embedded->KBHit () == TRUE) {
  2428.             if ((i = Embedded->Getch ()) == 0)
  2429.                i = (USHORT)(Embedded->Getch () << 8);
  2430.             else
  2431.                i = (USHORT)toupper (i);
  2432.  
  2433.             if (i == ESC) {
  2434.                if ((i = Embedded->Getch ()) == '[') {
  2435.                   while ((i = Embedded->Getch ()) == ';' || isdigit (i))
  2436.                      ;
  2437.                   if (i == 'A')
  2438.                      i = CTRLE;
  2439.                   else if (i == 'B')
  2440.                      i = CTRLX;
  2441.                }
  2442.             }
  2443.  
  2444.             switch (i) {
  2445.                case CTRLY:
  2446.                   PageUp ();
  2447.                   break;
  2448.  
  2449.                case CTRLE:
  2450.                case 0x4800:
  2451.                   Up ();
  2452.                   break;
  2453.  
  2454.                case '\r':
  2455.                   Select ();
  2456.                   break;
  2457.  
  2458.                case ' ':
  2459.                   Tag ();
  2460.                   break;
  2461.  
  2462.                case CTRLV:
  2463.                   PageDown ();
  2464.                   break;
  2465.  
  2466.                case CTRLX:
  2467.                case 0x5000:
  2468.                   Down ();
  2469.                   break;
  2470.  
  2471.                case 'X':
  2472.                   Exit ();
  2473.                   break;
  2474.             }
  2475.          }
  2476.       }
  2477.  
  2478.       Embedded->Printf ("\x0C");
  2479.    }
  2480.  
  2481.    return (RetVal);
  2482. }
  2483.  
  2484. VOID TListings::Up (VOID)
  2485. {
  2486.    USHORT i;
  2487.  
  2488.    if (List.Previous () != NULL) {
  2489.       List.Next ();
  2490.       RemoveCursor (y);
  2491.       List.Previous ();
  2492.       PrintCursor (--y);
  2493.       Data.Previous ();
  2494.    }
  2495.    else if (Data.Previous () != NULL) {
  2496.       Embedded->PrintfAt (4, 1, "");
  2497.       for (i = 0; i < (User->ScreenHeight - 6); i++)
  2498.          Embedded->Printf ("\x1B[K\n");
  2499.       for (i = 0; i < (User->ScreenHeight - 6 - 1); i++)
  2500.          Data.Previous ();
  2501.       List.Clear ();
  2502.       Embedded->PrintfAt (4, 1, "");
  2503.       i = 0;
  2504.       do {
  2505.          pld = (LISTDATA *)Data.Value ();
  2506.          PrintLine ();
  2507.          List.Add (pld->Key, (USHORT)(strlen (pld->Key) + 1));
  2508.          i++;
  2509.       } while (Data.Next () != NULL && i < (User->ScreenHeight - 6));
  2510.       Data.Previous ();
  2511.       y = (USHORT)(4 + User->ScreenHeight - 6 - 1);
  2512.       List.Last ();
  2513.       PrintCursor (y);
  2514.    }
  2515. }
  2516.  
  2517. // ----------------------------------------------------------------------
  2518.  
  2519. TStatus::TStatus (void)
  2520. {
  2521. }
  2522.  
  2523. TStatus::~TStatus (void)
  2524. {
  2525. }
  2526.  
  2527. VOID TStatus::Clear (VOID)
  2528. {
  2529. }
  2530.  
  2531. VOID TStatus::SetLine (USHORT line, PSZ text, ...)
  2532. {
  2533.    line = line;
  2534.    text = text;
  2535. }
  2536.  
  2537. // ----------------------------------------------------------------------
  2538.  
  2539. VOID ParseAddress (PSZ text, PSZ name, PSZ address)
  2540. {
  2541.    CHAR Temp[128], *p, *a;
  2542.  
  2543.    strcpy (Temp, text);
  2544.    if (strchr (Temp, '(') != NULL) {
  2545.       if ((p = strtok (Temp, " ")) != NULL) {
  2546.          p = strtok (NULL, "");
  2547.          while (*p == ' ')
  2548.             p++;
  2549.          if (*p == '(') {
  2550.             strcpy (Temp, ++p);
  2551.             p = strchr (Temp, '\0');
  2552.             while (--p > Temp) {
  2553.                if (*p == ')') {
  2554.                   *p = '\0';
  2555.                   break;
  2556.                }
  2557.             }
  2558.             strcpy (name, Temp);
  2559.             strcpy (Temp, text);
  2560.             if ((p = strtok (Temp, " ")) != NULL)
  2561.                strcpy (address, p);
  2562.          }
  2563.          else {
  2564.             strcpy (Temp, text);
  2565.             if ((p = strtok (Temp, " ")) != NULL)
  2566.                strcpy (name, p);
  2567.          }
  2568.       }
  2569.    }
  2570.    else if ((p = strchr (Temp, '<')) != NULL) {
  2571.       *p++ = '\0';
  2572.       if ((a = strchr (p, '>')) != NULL)
  2573.          *a = '\0';
  2574.       strcpy (address, p);
  2575.       p = Temp;
  2576.       while (*p == ' ')
  2577.          p++;
  2578.       if (*p == '"')
  2579.          strcpy (Temp, ++p);
  2580.       p = strchr (Temp, '\0');
  2581.       while (--p > Temp) {
  2582.          if (*p != ' ' && *p != '"')
  2583.             break;
  2584.          *p = '\0';
  2585.       }
  2586.       strcpy (name, Temp);
  2587.    }
  2588.    else if (strchr (Temp, '@') != NULL) {
  2589.       if ((p = strtok (Temp, " ,")) != NULL) {
  2590.          if (address != NULL)
  2591.             strcpy (address, p);
  2592.       }
  2593.    }
  2594. }
  2595.  
  2596.