home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / LORATXT.CPP < prev    next >
C/C++ Source or Header  |  1997-05-23  |  81KB  |  2,442 lines

  1.  
  2. // ----------------------------------------------------------------------
  3. // LoraBBS Professional Edition - Version 2.99.20
  4. // Copyright (c) 1996 by Marco Maccaferri. All rights reserved.
  5. //
  6. // History:
  7. //    03/10/95 - Initial coding.
  8. // ----------------------------------------------------------------------
  9.  
  10. #include "_ldefs.h"
  11. #include "msgbase.h"
  12. #include "lorawin.h"
  13.  
  14. #define MAIL_IMPORTKNOWN         0x0001L
  15. #define MAIL_IMPORTPROTECTED     0x0002L
  16. #define MAIL_IMPORTNORMAL        0x0004L
  17. #define MAIL_EXPORT              0x0008L
  18. #define MAIL_PACK                0x0010L
  19. #define MAIL_NEWSGROUP           0x0020L
  20. #define MAIL_TIC                 0x0040L
  21. #define MAIL_EMAIL               0x0080L
  22. #define MAIL_NOEXTERNAL          0x2000L
  23. #define MAIL_STARTTIMER          0x4000L
  24. #define MAIL_POSTQUIT            0x8000L
  25.  
  26. #if defined(__OS2__)
  27. #define IDOK            1
  28. #define IDCANCEL        2
  29. #endif
  30.  
  31. #define INITIALIZE         1
  32. #define WAITFOROK          2
  33. #define WAITFORCALL        3
  34. #define ANSWERING          4
  35. #define HANGUP             5
  36. #define WAITFORCONNECT     6
  37.  
  38. #define MODEM_DELAY        200
  39. #define EVENTS_DELAY       10000
  40.  
  41. short  last_sel = 100;
  42. USHORT Status, Current, Daemon = FALSE;
  43. CHAR   PollNode[64], ExternalProgram[128];
  44. LONG   TimeOut, CallDelay = 0L, ModemT, EventsT;
  45. class  TConfig *Cfg;
  46. class  TModem *Modem;
  47. class  TPMLog *Log;
  48. class  TEvents *Events;
  49. class  TOutbound *Outbound;
  50.  
  51. VOID DisplayScreen (VOID)
  52. {
  53.    CHAR Temp[128];
  54.  
  55.    videoinit ();
  56.  
  57.    if (Daemon == FALSE) {
  58.       hidecur ();
  59.       if (wopen (0, 0, 24, 79, 5, LGREY|_BLACK, LGREY|_BLACK) != 0) {
  60.          box_ (1, 0, 24, 79, 0, LGREY|_BLACK);
  61.          whline (12, 0, 80, 0, LGREY|_BLACK);
  62.          whline (21, 0, 80, 0, LGREY|_BLACK);
  63.          wvline (1, 48, 12, 0, LGREY|_BLACK);
  64.          if (Cfg->MailAddress.First () == TRUE)
  65.             prints (0, 1, LGREEN|_BLACK, Cfg->MailAddress.String);
  66.          sprintf (Temp, "%s v%s", NAME, VERSION);
  67.          prints (0, (USHORT)(78 - strlen (Temp)), LGREEN|_BLACK, Temp);
  68.          prints (1, 2, LCYAN|_BLACK, "LOG");
  69.          prints (1, 50, LCYAN|_BLACK, "MODEM");
  70.          prints (12, 2, LCYAN|_BLACK, "OUTBOUND / REMOTE");
  71.          prints (21, 2, LCYAN|_BLACK, "STATUS");
  72.       }
  73.  
  74.       videoupdate ();
  75.    }
  76. }
  77.  
  78. VOID RefreshOutbound (VOID)
  79. {
  80.    USHORT i;
  81.    CHAR Flags[16], Temp[128], Status[32];
  82.  
  83.    if (Daemon == FALSE) {
  84.       i = 13;
  85.       fill_ (13, 1, 20, 78, ' ', LGREY|_BLACK);
  86.  
  87.       if (Outbound->FirstNode () == TRUE) {
  88.          prints (i++, 2, YELLOW|_BLACK, "Node               Try/Con  Type       Size     Status");
  89.          do {
  90.             Flags[0] = (Outbound->Normal == TRUE) ? 'N' : ' ';
  91.             Flags[1] = (Outbound->Crash == TRUE) ? 'C' : ' ';
  92.             Flags[2] = (Outbound->Direct == TRUE) ? 'D' : ' ';
  93.             Flags[3] = (Outbound->Hold == TRUE) ? 'H' : ' ';
  94.             Flags[4] = (Outbound->Immediate == TRUE) ? 'I' : ' ';
  95.             Flags[5] = '\0';
  96.             if (Outbound->Normal == FALSE && Outbound->Crash == FALSE && Outbound->Direct == FALSE && Outbound->Immediate == FALSE)
  97.                strcpy (Status, "Hold");
  98.             else {
  99.                strcpy (Status, "Temporary Hold");
  100.                if (Outbound->Normal == TRUE && Events->SendNormal == TRUE)
  101.                   strcpy (Status, Outbound->LastCall);
  102.                else if (Outbound->Crash == TRUE && Events->SendCrash == TRUE)
  103.                   strcpy (Status, Outbound->LastCall);
  104.                else if (Outbound->Direct == TRUE && Events->SendDirect == TRUE)
  105.                   strcpy (Status, Outbound->LastCall);
  106.                else if (Outbound->Immediate == TRUE && Events->SendImmediate == TRUE)
  107.                   strcpy (Status, Outbound->LastCall);
  108.             }
  109.             if (Events != NULL) {
  110.                if (Events->MaxCalls != 0 && Outbound->Attempts >= Events->MaxCalls)
  111.                   strcpy (Status, "Undialable (Attempts)");
  112.                else if (Events->MaxConnects != 0 && Outbound->Failed >= Events->MaxConnects)
  113.                   strcpy (Status, "Undialable (Failures)");
  114.             }
  115.             sprintf (Temp, "%-16.16s  %3d %3d   %s  %8lub    %s", Outbound->Address, Outbound->Attempts, Outbound->Failed, Flags, Outbound->Size, Status);
  116.             prints (i++, 2, LCYAN|_BLACK, Temp);
  117.          } while (i < 21 && Outbound->NextNode () == TRUE);
  118.       }
  119.       else
  120.          prints (17, 2, YELLOW|_BLACK, "                      Nothing in outbound area");
  121.  
  122.       videoupdate ();
  123.    }
  124. }
  125.  
  126. VOID ClearScreen (VOID)
  127. {
  128.    wcloseall ();
  129.    showcur ();
  130.    videoupdate ();
  131.    closevideo ();
  132. }
  133.  
  134. USHORT CPollDlg (VOID)
  135. {
  136.    short i;
  137.    CHAR Temp[64], String[128], Flag[8];
  138.    class TAddress Addr;
  139.    class TNodes *Nodes;
  140.  
  141.    Flag[0] = Temp[0] = '\0';
  142.    if (wopen (10, 15, 12, 65, 1, WHITE|_LGREY, WHITE|_LGREY) > 0) {
  143.       wshadow (DGREY|_BLACK);
  144.       wtitle (" Forced Poll ", TCENTER, WHITE|_LGREY);
  145.  
  146.       wprints (0, 1, WHITE|_GREEN, " Address ");
  147.       winpbeg (WHITE|_BLUE, WHITE|_BLUE);
  148.       winpdef (0, 11, Temp, "?????????????????????????????????????", 0, 2, NULL, 0);
  149.       if (winpread () == W_ESCPRESS)
  150.          Temp[0] = '\0';
  151.       hidecur ();
  152.       wclose ();
  153.    }
  154.  
  155.    if (Temp[0] != '\0') {
  156.       Cfg->MailAddress.First ();
  157.       Addr.Parse (Temp);
  158.       if (Addr.Zone == 0)
  159.          Addr.Zone = Cfg->MailAddress.Zone;
  160.       if (Addr.Net == 0)
  161.          Addr.Net = Cfg->MailAddress.Net;
  162.       Addr.Add ();
  163.       Addr.First ();
  164.  
  165.       if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  166.          if (Nodes->Read (Addr) == TRUE) {
  167.             wopen (9, 10, 14, 68, 0, WHITE|_LGREY, WHITE|_LGREY);
  168.             wshadow (DGREY|_BLACK);
  169.             wtitle (" Forced Poll ", TCENTER, WHITE|_LGREY);
  170.             whline (2, 0, 58, 0, WHITE|_LGREY);
  171.             wprints (0, 1, BLUE|_LGREY, Nodes->SystemName);
  172.             wprints (0, (short)(56 - strlen (Nodes->Address)), BLUE|_LGREY, Nodes->Address);
  173.             wprints (1, 1, BLUE|_LGREY, Nodes->Location);
  174.             wprints (1, (short)(56 - strlen (Nodes->SysopName)), BLUE|_LGREY, Nodes->SysopName);
  175.  
  176.             wprints (3, 1, WHITE|_LGREY, "Priority:   (Normal/Crash/Direct/Immediate)");
  177.             strcpy (Flag, "i");
  178.             do {
  179.                winpbeg (WHITE|_BLUE, WHITE|_BLUE);
  180.                winpdef (3, 11, Flag, "?", 0, 2, NULL, 0);
  181.                i = winpread ();
  182.                Flag[0] = (CHAR)tolower (Flag[0]);
  183.             } while (Flag[0] != 'i' && Flag[0] != 'n' && Flag[0] != 'c' && Flag[0] != 'd');
  184.  
  185.             hidecur ();
  186.             wclose ();
  187.  
  188.             if (i == W_ESCPRESS)
  189.                Temp[0] = '\0';
  190.          }
  191.          else {
  192.             sprintf (String, "Node %s not found !", Addr.String);
  193.             MessageBox (" Forced Poll ", String);
  194.             Temp[0] = '\0';
  195.          }
  196.          delete Nodes;
  197.       }
  198.    }
  199.  
  200.    if (Temp[0] != '\0') {
  201.       if (Outbound != NULL) {
  202.          Outbound->PollNode (Addr.String, Flag[0]);
  203.  
  204.          if (Log != NULL)
  205.             Log->Write ("+Building the outbound queue");
  206.          Outbound->BuildQueue (Cfg->Outbound);
  207.          unlink ("rescan.now");
  208.          if (Log != NULL)
  209.             Log->Write ("+%u queue record(s) in database", Outbound->TotalNodes);
  210.  
  211.          RefreshOutbound ();
  212.       }
  213.    }
  214.  
  215.    return (FALSE);
  216. }
  217.  
  218. USHORT CRequestDlg (VOID)
  219. {
  220.    FILE *fp;
  221.    short i;
  222.    CHAR Temp[64], String[128], File[128], Flag[8], *p;
  223.    class TAddress Addr;
  224.    class TNodes *Nodes;
  225.  
  226.    Flag[0] = Temp[0] = '\0';
  227.    String[0] = '\0';
  228.  
  229.    if (wopen (10, 15, 12, 65, 1, WHITE|_LGREY, WHITE|_LGREY) > 0) {
  230.       wshadow (DGREY|_BLACK);
  231.       wtitle (" Request File(s) ", TCENTER, WHITE|_LGREY);
  232.  
  233.       wprints (0, 1, WHITE|_GREEN, " Address ");
  234.       winpbeg (WHITE|_BLUE, WHITE|_BLUE);
  235.       winpdef (0, 11, Temp, "?????????????????????????????????????", 0, 2, NULL, 0);
  236.       if (winpread () == W_ESCPRESS)
  237.          Temp[0] = '\0';
  238.       hidecur ();
  239.       wclose ();
  240.    }
  241.  
  242.    if (Temp[0] != '\0') {
  243.       Cfg->MailAddress.First ();
  244.       Addr.Parse (Temp);
  245.       if (Addr.Zone == 0)
  246.          Addr.Zone = Cfg->MailAddress.Zone;
  247.       if (Addr.Net == 0)
  248.          Addr.Net = Cfg->MailAddress.Net;
  249.       Addr.Add ();
  250.       Addr.First ();
  251.  
  252.       if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  253.          if (Nodes->Read (Addr) == TRUE) {
  254.             wopen (9, 10, 15, 68, 0, WHITE|_LGREY, WHITE|_LGREY);
  255.             wshadow (DGREY|_BLACK);
  256.             wtitle (" Request File(s) ", TCENTER, WHITE|_LGREY);
  257.             whline (2, 0, 58, 0, WHITE|_LGREY);
  258.             wprints (0, 1, BLUE|_LGREY, Nodes->SystemName);
  259.             wprints (0, (short)(56 - strlen (Nodes->Address)), BLUE|_LGREY, Nodes->Address);
  260.             wprints (1, 1, BLUE|_LGREY, Nodes->Location);
  261.             wprints (1, (short)(56 - strlen (Nodes->SysopName)), BLUE|_LGREY, Nodes->SysopName);
  262.  
  263.             wprints (3, 1, WHITE|_LGREY, "File(s):");
  264.             wprints (4, 1, WHITE|_LGREY, "Priority:   (Normal/Crash/Direct/Immediate)");
  265.  
  266.             String[0] = '\0';
  267.             winpbeg (WHITE|_BLUE, WHITE|_BLUE);
  268.             winpdef (3, 11, String, "?????????????????????????????????????", 0, 2, NULL, 0);
  269.             i = winpread ();
  270.             strtrim (String);
  271.  
  272.             if (String[0] != '\0' && i != W_ESCPRESS) {
  273.                strcpy (Flag, "i");
  274.                do {
  275.                   winpbeg (WHITE|_BLUE, WHITE|_BLUE);
  276.                   winpdef (4, 11, Flag, "?", 0, 2, NULL, 0);
  277.                   i = winpread ();
  278.                   Flag[0] = (CHAR)tolower (Flag[0]);
  279.                } while (Flag[0] != 'i' && Flag[0] != 'n' && Flag[0] != 'c' && Flag[0] != 'd');
  280.             }
  281.  
  282.             hidecur ();
  283.             wclose ();
  284.  
  285.             if (i == W_ESCPRESS)
  286.                String[0] = '\0';
  287.          }
  288.          else {
  289.             sprintf (Temp, "Node %s not found !", Addr.String);
  290.             MessageBox (" Request File(s) ", Temp);
  291.             String[0] = '\0';
  292.          }
  293.          delete Nodes;
  294.       }
  295.    }
  296.  
  297.    if (String[0] != '\0') {
  298.       strcpy (Temp, Cfg->Outbound);
  299.       Temp[strlen (Temp) - 1] = '\0';
  300.  
  301.       if (Cfg->MailAddress.Zone != Addr.Zone) {
  302.          sprintf (File, "%s.%03x", Temp, Addr.Zone);
  303. #if defined(__LINUX__)
  304.          mkdir (File, 0666);
  305. #else
  306.          mkdir (File);
  307. #endif
  308.          if (Addr.Point != 0) {
  309. #if defined(__LINUX__)
  310.             sprintf (File, "%s.%03x/%04x%04x.pnt", Temp, Addr.Zone, Addr.Net, Addr.Node);
  311.             mkdir (File, 0666);
  312.             sprintf (File, "%s.%03x/%04x%04x.pnt/%08x.req", Temp, Addr.Zone, Addr.Net, Addr.Node, Addr.Point);
  313. #else
  314.             sprintf (File, "%s.%03x\\%04x%04x.pnt", Temp, Addr.Zone, Addr.Net, Addr.Node);
  315.             mkdir (File);
  316.             sprintf (File, "%s.%03x\\%04x%04x.pnt\\%08x.req", Temp, Addr.Zone, Addr.Net, Addr.Node, Addr.Point);
  317. #endif
  318.          }
  319.          else
  320. #if defined(__LINUX__)
  321.             sprintf (File, "%s.%03x/%04x%04x.req", Temp, Addr.Zone, Addr.Net, Addr.Node);
  322. #else
  323.             sprintf (File, "%s.%03x\\%04x%04x.req", Temp, Addr.Zone, Addr.Net, Addr.Node);
  324. #endif
  325.       }
  326.       else {
  327.          if (Addr.Point != 0) {
  328. #if defined(__LINUX__)
  329.             sprintf (File, "%s/%04x%04x.pnt", Temp, Addr.Net, Addr.Node);
  330.             mkdir (File, 0666);
  331.             sprintf (File, "%s/%04x%04x.pnt/%08x.req", Temp, Addr.Net, Addr.Node, Addr.Point);
  332. #else
  333.             sprintf (File, "%s\\%04x%04x.pnt", Temp, Addr.Net, Addr.Node);
  334.             mkdir (File);
  335.             sprintf (File, "%s\\%04x%04x.pnt\\%08x.req", Temp, Addr.Net, Addr.Node, Addr.Point);
  336. #endif
  337.          }
  338.          else
  339. #if defined(__LINUX__)
  340.             sprintf (File, "%s/%04x%04x.req", Temp, Addr.Net, Addr.Node);
  341. #else
  342.             sprintf (File, "%s\\%04x%04x.req", Temp, Addr.Net, Addr.Node);
  343. #endif
  344.       }
  345.  
  346.       if ((fp = fopen (File, "at")) != NULL) {
  347.          if ((p = strtok (String, " ")) != NULL)
  348.             do {
  349.                fprintf (fp, "%s\n", p);
  350.             } while ((p = strtok (NULL, " ")) != NULL);
  351.          fclose (fp);
  352.       }
  353.  
  354.       if (Outbound != NULL) {
  355.          Outbound->PollNode (Addr.String, Flag[0]);
  356.  
  357.          if (Log != NULL)
  358.             Log->Write ("+Building the outbound queue");
  359.          Outbound->BuildQueue (Cfg->Outbound);
  360.          unlink ("rescan.now");
  361.          if (Log != NULL)
  362.             Log->Write ("+%u queue record(s) in database", Outbound->TotalNodes);
  363.  
  364.          RefreshOutbound ();
  365.       }
  366.    }
  367.  
  368.    return (FALSE);
  369. }
  370.  
  371. USHORT CAttachDlg (VOID)
  372. {
  373.    FILE *fp;
  374.    short i;
  375.    CHAR Temp[64], String[128], File[128], Flag[8], *p;
  376.    class TAddress Addr;
  377.    class TNodes *Nodes;
  378.  
  379.    Flag[0] = Temp[0] = '\0';
  380.    String[0] = '\0';
  381.  
  382.    if (wopen (10, 15, 12, 65, 1, WHITE|_LGREY, WHITE|_LGREY) > 0) {
  383.       wshadow (DGREY|_BLACK);
  384.       wtitle (" File Attach ", TCENTER, WHITE|_LGREY);
  385.  
  386.       wprints (0, 1, WHITE|_GREEN, " Address ");
  387.       winpbeg (WHITE|_BLUE, WHITE|_BLUE);
  388.       winpdef (0, 11, Temp, "?????????????????????????????????????", 0, 2, NULL, 0);
  389.       if (winpread () == W_ESCPRESS)
  390.          Temp[0] = '\0';
  391.       hidecur ();
  392.       wclose ();
  393.    }
  394.  
  395.    if (Temp[0] != '\0') {
  396.       Cfg->MailAddress.First ();
  397.       Addr.Parse (Temp);
  398.       if (Addr.Zone == 0)
  399.          Addr.Zone = Cfg->MailAddress.Zone;
  400.       if (Addr.Net == 0)
  401.          Addr.Net = Cfg->MailAddress.Net;
  402.       Addr.Add ();
  403.       Addr.First ();
  404.  
  405.       if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  406.          if (Nodes->Read (Addr) == TRUE) {
  407.             wopen (9, 10, 15, 68, 0, WHITE|_LGREY, WHITE|_LGREY);
  408.             wshadow (DGREY|_BLACK);
  409.             wtitle (" File Attach ", TCENTER, WHITE|_LGREY);
  410.             whline (2, 0, 58, 0, WHITE|_LGREY);
  411.             wprints (0, 1, BLUE|_LGREY, Nodes->SystemName);
  412.             wprints (0, (short)(56 - strlen (Nodes->Address)), BLUE|_LGREY, Nodes->Address);
  413.             wprints (1, 1, BLUE|_LGREY, Nodes->Location);
  414.             wprints (1, (short)(56 - strlen (Nodes->SysopName)), BLUE|_LGREY, Nodes->SysopName);
  415.  
  416.             wprints (3, 1, WHITE|_LGREY, "File(s):");
  417.             wprints (4, 1, WHITE|_LGREY, "Priority:   (Normal/Crash/Direct/Hold)");
  418.  
  419.             String[0] = '\0';
  420.             winpbeg (WHITE|_BLUE, WHITE|_BLUE);
  421.             winpdef (3, 11, String, "?????????????????????????????????????", 0, 2, NULL, 0);
  422.             i = winpread ();
  423.             strtrim (String);
  424.  
  425.             if (String[0] != '\0' && i != W_ESCPRESS) {
  426.                strcpy (Flag, "h");
  427.                do {
  428.                   winpbeg (WHITE|_BLUE, WHITE|_BLUE);
  429.                   winpdef (4, 11, Flag, "?", 0, 2, NULL, 0);
  430.                   i = winpread ();
  431.                   Flag[0] = (CHAR)tolower (Flag[0]);
  432.                } while (Flag[0] != 'h' && Flag[0] != 'n' && Flag[0] != 'c' && Flag[0] != 'd');
  433.                if (Flag[0] == 'n')
  434.                   Flag[0] = 'f';
  435.             }
  436.  
  437.             hidecur ();
  438.             wclose ();
  439.  
  440.             if (i == W_ESCPRESS)
  441.                String[0] = '\0';
  442.          }
  443.          else {
  444.             sprintf (Temp, "Node %s not found !", Addr.String);
  445.             MessageBox (" File Attach ", Temp);
  446.             String[0] = '\0';
  447.          }
  448.          delete Nodes;
  449.       }
  450.    }
  451.  
  452.    if (String[0] != '\0') {
  453.       strcpy (Temp, Cfg->Outbound);
  454.       Temp[strlen (Temp) - 1] = '\0';
  455.  
  456.       if (Cfg->MailAddress.Zone != Addr.Zone) {
  457.          sprintf (File, "%s.%03x", Temp, Addr.Zone);
  458. #if defined(__LINUX__)
  459.          mkdir (File, 0666);
  460.          if (Addr.Point != 0) {
  461.             sprintf (File, "%s.%03x/%04x%04x.pnt", Temp, Addr.Zone, Addr.Net, Addr.Node);
  462.             mkdir (File, 0666);
  463.             sprintf (File, "%s.%03x/%04x%04x.pnt/%08x.%clo", Temp, Addr.Zone, Addr.Net, Addr.Node, Addr.Point, Flag[0]);
  464.          }
  465.          else
  466.             sprintf (File, "%s.%03x/%04x%04x.%clo", Temp, Addr.Zone, Addr.Net, Addr.Node, Flag[0]);
  467.       }
  468.       else {
  469.          if (Addr.Point != 0) {
  470.             sprintf (File, "%s/%04x%04x.pnt", Temp, Addr.Net, Addr.Node);
  471.             mkdir (File, 0666);
  472.             sprintf (File, "%s/%04x%04x.pnt/%08x.%clo", Temp, Addr.Net, Addr.Node, Addr.Point, Flag[0]);
  473.          }
  474.          else
  475.             sprintf (File, "%s/%04x%04x.%clo", Temp, Addr.Net, Addr.Node, Flag[0]);
  476. #else
  477.          mkdir (File);
  478.          if (Addr.Point != 0) {
  479.             sprintf (File, "%s.%03x\\%04x%04x.pnt", Temp, Addr.Zone, Addr.Net, Addr.Node);
  480.             mkdir (File);
  481.             sprintf (File, "%s.%03x\\%04x%04x.pnt\\%08x.%clo", Temp, Addr.Zone, Addr.Net, Addr.Node, Addr.Point, Flag[0]);
  482.          }
  483.          else
  484.             sprintf (File, "%s.%03x\\%04x%04x.%clo", Temp, Addr.Zone, Addr.Net, Addr.Node, Flag[0]);
  485.       }
  486.       else {
  487.          if (Addr.Point != 0) {
  488.             sprintf (File, "%s\\%04x%04x.pnt", Temp, Addr.Net, Addr.Node);
  489.             mkdir (File);
  490.             sprintf (File, "%s\\%04x%04x.pnt\\%08x.%clo", Temp, Addr.Net, Addr.Node, Addr.Point, Flag[0]);
  491.          }
  492.          else
  493.             sprintf (File, "%s\\%04x%04x.%clo", Temp, Addr.Net, Addr.Node, Flag[0]);
  494. #endif
  495.       }
  496.  
  497.       if ((fp = fopen (File, "at")) != NULL) {
  498.          if ((p = strtok (String, " ")) != NULL)
  499.             do {
  500.                fprintf (fp, "%s\n", p);
  501.             } while ((p = strtok (NULL, " ")) != NULL);
  502.          fclose (fp);
  503.       }
  504.  
  505.       if (Outbound != NULL) {
  506.          Outbound->PollNode (Addr.String, Flag[0]);
  507.  
  508.          if (Log != NULL)
  509.             Log->Write ("+Building the outbound queue");
  510.          Outbound->BuildQueue (Cfg->Outbound);
  511.          unlink ("rescan.now");
  512.          if (Log != NULL)
  513.             Log->Write ("+%u queue record(s) in database", Outbound->TotalNodes);
  514.  
  515.          RefreshOutbound ();
  516.       }
  517.    }
  518.  
  519.    return (FALSE);
  520. }
  521.  
  522. USHORT CRescanDlg (VOID)
  523. {
  524.    short i;
  525.    CHAR Temp[64], String[128], *t, *p;
  526.    class TAddress Addr;
  527.    class TNodes *Nodes;
  528.    class TAreaManager *AreaMgr;
  529.  
  530.    Temp[0] = '\0';
  531.    String[0] = '\0';
  532.  
  533.    if (wopen (10, 15, 12, 65, 1, WHITE|_LGREY, WHITE|_LGREY) > 0) {
  534.       wshadow (DGREY|_BLACK);
  535.       wtitle (" Rescan Area(s) ", TCENTER, WHITE|_LGREY);
  536.  
  537.       wprints (0, 1, WHITE|_GREEN, " Address ");
  538.       winpbeg (WHITE|_BLUE, WHITE|_BLUE);
  539.       winpdef (0, 11, Temp, "?????????????????????????????????????", 0, 2, NULL, 0);
  540.       if (winpread () == W_ESCPRESS)
  541.          Temp[0] = '\0';
  542.       hidecur ();
  543.       wclose ();
  544.    }
  545.  
  546.    if (Temp[0] != '\0') {
  547.       Cfg->MailAddress.First ();
  548.       Addr.Parse (Temp);
  549.       if (Addr.Zone == 0)
  550.          Addr.Zone = Cfg->MailAddress.Zone;
  551.       if (Addr.Net == 0)
  552.          Addr.Net = Cfg->MailAddress.Net;
  553.       Addr.Add ();
  554.       Addr.First ();
  555.  
  556.       if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  557.          if (Nodes->Read (Addr) == TRUE) {
  558.             wopen (9, 10, 14, 68, 0, WHITE|_LGREY, WHITE|_LGREY);
  559.             wshadow (DGREY|_BLACK);
  560.             wtitle (" Rescan Area(s) ", TCENTER, WHITE|_LGREY);
  561.             whline (2, 0, 58, 0, WHITE|_LGREY);
  562.             wprints (0, 1, BLUE|_LGREY, Nodes->SystemName);
  563.             wprints (0, (short)(56 - strlen (Nodes->Address)), BLUE|_LGREY, Nodes->Address);
  564.             wprints (1, 1, BLUE|_LGREY, Nodes->Location);
  565.             wprints (1, (short)(56 - strlen (Nodes->SysopName)), BLUE|_LGREY, Nodes->SysopName);
  566.  
  567.             wprints (3, 1, WHITE|_LGREY, "Area(s):");
  568.  
  569.             String[0] = '\0';
  570.             winpbeg (WHITE|_BLUE, WHITE|_BLUE);
  571.             winpdef (3, 11, String, "?????????????????????????????????????", 0, 2, NULL, 0);
  572.             i = winpread ();
  573.             strtrim (String);
  574.  
  575.             hidecur ();
  576.             wclose ();
  577.  
  578.             if (i == W_ESCPRESS)
  579.                String[0] = '\0';
  580.          }
  581.          else {
  582.             sprintf (Temp, "Node %s not found !", Addr.String);
  583.             MessageBox (" Rescan Area(s) ", Temp);
  584.             String[0] = '\0';
  585.          }
  586.          delete Nodes;
  587.       }
  588.    }
  589.  
  590.    if (String[0] != '\0') {
  591.       if ((AreaMgr = new TAreaManager) != NULL) {
  592.          AreaMgr->Cfg = Cfg;
  593.          AreaMgr->Log = Log;
  594.  
  595.          t = String;
  596.          while ((p = strtok (t, " ")) != NULL) {
  597.             t = strtok (NULL, "");
  598.             AreaMgr->Rescan (p, Addr.String);
  599.          }
  600.  
  601.          delete AreaMgr;
  602.       }
  603.    }
  604.  
  605.    return (FALSE);
  606. }
  607.  
  608. USHORT CNewEcholinkDlg (VOID)
  609. {
  610.    short i;
  611.    CHAR Temp[64], String[128], *t, *p;
  612.    class TAddress Addr;
  613.    class TNodes *Nodes;
  614.    class TAreaManager *AreaMgr;
  615.  
  616.    Temp[0] = '\0';
  617.    String[0] = '\0';
  618.  
  619.    if (wopen (10, 15, 12, 65, 1, WHITE|_LGREY, WHITE|_LGREY) > 0) {
  620.       wshadow (DGREY|_BLACK);
  621.       wtitle (" New Echomail Link ", TCENTER, WHITE|_LGREY);
  622.  
  623.       wprints (0, 1, WHITE|_GREEN, " Address ");
  624.       winpbeg (WHITE|_BLUE, WHITE|_BLUE);
  625.       winpdef (0, 11, Temp, "?????????????????????????????????????", 0, 2, NULL, 0);
  626.       if (winpread () == W_ESCPRESS)
  627.          Temp[0] = '\0';
  628.       hidecur ();
  629.       wclose ();
  630.    }
  631.  
  632.    if (Temp[0] != '\0') {
  633.       Cfg->MailAddress.First ();
  634.       Addr.Parse (Temp);
  635.       if (Addr.Zone == 0)
  636.          Addr.Zone = Cfg->MailAddress.Zone;
  637.       if (Addr.Net == 0)
  638.          Addr.Net = Cfg->MailAddress.Net;
  639.       Addr.Add ();
  640.       Addr.First ();
  641.  
  642.       if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  643.          if (Nodes->Read (Addr) == TRUE) {
  644.             wopen (9, 10, 14, 68, 0, WHITE|_LGREY, WHITE|_LGREY);
  645.             wshadow (DGREY|_BLACK);
  646.             wtitle (" New Echomail Link ", TCENTER, WHITE|_LGREY);
  647.             whline (2, 0, 58, 0, WHITE|_LGREY);
  648.             wprints (0, 1, BLUE|_LGREY, Nodes->SystemName);
  649.             wprints (0, (short)(56 - strlen (Nodes->Address)), BLUE|_LGREY, Nodes->Address);
  650.             wprints (1, 1, BLUE|_LGREY, Nodes->Location);
  651.             wprints (1, (short)(56 - strlen (Nodes->SysopName)), BLUE|_LGREY, Nodes->SysopName);
  652.  
  653.             wprints (3, 1, WHITE|_LGREY, "Area(s):");
  654.  
  655.             String[0] = '\0';
  656.             winpbeg (WHITE|_BLUE, WHITE|_BLUE);
  657.             winpdef (3, 11, String, "?????????????????????????????????????", 0, 2, NULL, 0);
  658.             i = winpread ();
  659.             strtrim (String);
  660.  
  661.             hidecur ();
  662.             wclose ();
  663.  
  664.             if (i == W_ESCPRESS)
  665.                String[0] = '\0';
  666.          }
  667.          else {
  668.             sprintf (Temp, "Node %s not found !", Addr.String);
  669.             MessageBox (" New Echomail Link ", Temp);
  670.             String[0] = '\0';
  671.          }
  672.          delete Nodes;
  673.       }
  674.    }
  675.  
  676.    if (String[0] != '\0') {
  677.       if ((AreaMgr = new TAreaManager) != NULL) {
  678.          AreaMgr->Cfg = Cfg;
  679.          AreaMgr->Log = Log;
  680.  
  681.          t = String;
  682.          while ((p = strtok (t, " ")) != NULL) {
  683.             t = strtok (NULL, "");
  684.             if (!stricmp (p, "%-ALL"))
  685.                AreaMgr->RemoveAll (Addr.String);
  686.             else if (*p == '-')
  687.                AreaMgr->RemoveArea (Addr.String, ++p);
  688.             else {
  689.                if (*p == '+')
  690.                   p++;
  691.                AreaMgr->AddArea (Addr.String, p);
  692.             }
  693.          }
  694.  
  695.          delete AreaMgr;
  696.       }
  697.    }
  698.  
  699.    return (FALSE);
  700. }
  701.  
  702. // ----------------------------------------------------------------------
  703. // Product informations dialog
  704. // ----------------------------------------------------------------------
  705.  
  706. USHORT CProductDlg (VOID)
  707. {
  708.    int menu_sel = 996;
  709.    CHAR Temp[128], RegName[64], RegNumber[32];
  710.    USHORT RetVal = FALSE;
  711.  
  712.    wopen (6, 13, 18, 67, 1, WHITE|_LGREY, WHITE|_LGREY);
  713.    wshadow (DGREY|_BLACK);
  714.  
  715.    DisplayButton (9, 22, "   Ok   ");
  716.  
  717.    sprintf (Temp, "%s v%s", NAME, VERSION);
  718.    wcenters (0, BLUE|_LGREY, Temp);
  719. #if defined(__DOS__)
  720.    wcenters (1, BLUE|_LGREY, "Professional Edition for DOS");
  721. #elif defined(__LINUX__)
  722.    wcenters (1, BLUE|_LGREY, "Professional Edition for Linux");
  723. #endif
  724.    if (ValidateKey ("bbs", RegName, RegNumber) != KEY_UNREGISTERED) {
  725.       sprintf (Temp, "Registered to %s", RegName);
  726.       wcenters (3, BLACK|_LGREY, Temp);
  727.       sprintf (Temp, "Serial Number %s", RegNumber);
  728.       wcenters (4, BLACK|_LGREY, Temp);
  729.    }
  730.    else
  731.       wcenters (3, BLACK|_LGREY, "- Unregistered Evaluation Copy -");
  732.    wcenters (6, WHITE|_LGREY, "Copyright (c) 1996-97 by Marco Maccaferri");
  733.    wcenters (7, WHITE|_LGREY, "All rights reserved");
  734.  
  735.    do {
  736.       wmenubegc ();
  737.       wmenuitem (9, 22, "   Ok   ", 'O', 996, 0, NULL, 0, 0);
  738.       wmenuend ((short)menu_sel, M_OMNI|M_SAVE, 0, 0, BLACK|_GREEN, YELLOW|_GREEN, DGREY|_GREEN, WHITE|_GREEN);
  739.  
  740.       switch (menu_sel = wmenuget ()) {
  741.          case 996:
  742.             RetVal = TRUE;
  743.             break;
  744.       }
  745.    } while (menu_sel != -1 && menu_sel != 996 && menu_sel != 997);
  746.  
  747.    wclose ();
  748.  
  749.    return (RetVal);
  750. }
  751.  
  752. // ---------------------------------------------------------------------------
  753. // Windowed log file display
  754. // ---------------------------------------------------------------------------
  755.  
  756. TPMLog::TPMLog (void)
  757. {
  758.    if (Daemon == FALSE) {
  759.       if ((window = wopen (2, 1, 11, 47, 5, LGREY|_BLACK, WHITE|_BLACK)) != 0)
  760.          wprintf ("\n\n\n\n\n\n\n\n\n\n\n\n");
  761.       videoupdate ();
  762.    }
  763.    Display = TRUE;
  764. }
  765.  
  766. TPMLog::~TPMLog (void)
  767. {
  768.    if (window != 0) {
  769.       wactiv (window);
  770.       wclose ();
  771.    }
  772. }
  773.  
  774. VOID TPMLog::Write (PSZ pszFormat, ...)
  775. {
  776.    va_list arglist;
  777.    time_t t;
  778.    struct tm *timep;
  779.  
  780.    va_start (arglist, pszFormat);
  781.    vsprintf (Buffer, pszFormat, arglist);
  782.    va_end (arglist);
  783.  
  784.    t = time (NULL);
  785.    timep = localtime (&t);
  786.    sprintf (Temp, "%c %02d %3s %02d:%02d:%02d %s %s", Buffer[0], timep->tm_mday, Months[timep->tm_mon], timep->tm_hour, timep->tm_min, timep->tm_sec, "LORA", &Buffer[1]);
  787.  
  788.    if (fp != NULL) {
  789.       fprintf (fp, "%s\n", Temp);
  790. #if !defined(__NT__)
  791.       fflush (fp);
  792. #endif
  793.    }
  794.  
  795.    if (window != 0 && Display == TRUE && Daemon == FALSE) {
  796.       wactiv (window);
  797.       sprintf (Temp, "%c %02d:%02d %s", Buffer[0], timep->tm_hour, timep->tm_min, &Buffer[1]);
  798.       wprintf ("\n%.46s", Temp);
  799.       videoupdate ();
  800.    }
  801. }
  802.  
  803. // ----------------------------------------------------------------------------
  804. // Status window manager
  805. // ----------------------------------------------------------------------------
  806.  
  807. TPMStatus::TPMStatus (void)
  808. {
  809. }
  810.  
  811. TPMStatus::~TPMStatus (void)
  812. {
  813. }
  814.  
  815. VOID TPMStatus::Clear (VOID)
  816. {
  817.    fill_ (22, 1, 23, 78, ' ', LGREY|_BLACK);
  818.    videoupdate ();
  819. }
  820.  
  821. VOID TPMStatus::SetLine (USHORT line, PSZ text, ...)
  822. {
  823.    va_list arglist;
  824.    CHAR Temp[128];
  825.  
  826.    va_start (arglist, text);
  827.    vsprintf (Temp, text, arglist);
  828.    va_end (arglist);
  829.  
  830.    fill_ ((short)(22 + line), 1, (short)(22 + line), 78, ' ', LGREY|_BLACK);
  831.    prints ((short)(22 + line), 2, WHITE|_BLACK, Temp);
  832.    videoupdate ();
  833. }
  834.  
  835. // ----------------------------------------------------------------------------
  836. // File transfer progress indicator
  837. // ----------------------------------------------------------------------------
  838.  
  839. class TPMProgress : public TProgress
  840. {
  841. public:
  842.    TPMProgress (void);
  843.    ~TPMProgress (void);
  844.  
  845.    VOID   Begin (VOID);
  846.    VOID   End (VOID);
  847.    VOID   Update (VOID);
  848.  
  849. private:
  850. };
  851.  
  852. TPMProgress::TPMProgress (void)
  853. {
  854. }
  855.  
  856. TPMProgress::~TPMProgress (void)
  857. {
  858. }
  859.  
  860. VOID TPMProgress::Begin (VOID)
  861. {
  862.    CHAR Temp[128];
  863.  
  864.    if (Type == FILE_RECEIVING)
  865.       sprintf (Temp, "Receiving %s; %lu bytes", RxFileName, RxSize);
  866.    else if (Type == FILE_SENDING)
  867.       sprintf (Temp, "Sending %s; %lu bytes", TxFileName, TxSize);
  868.    fill_ (22, 1, 22, 78, ' ', LGREY|_BLACK);
  869.    prints (22, 2, WHITE|_BLACK, Temp);
  870.    videoupdate ();
  871. }
  872.  
  873. VOID TPMProgress::Update (VOID)
  874. {
  875.    CHAR Temp[128];
  876.  
  877.    if (Type == FILE_RECEIVING)
  878.       sprintf (Temp, "%8lu %5u", RxPosition, RxBlockSize);
  879.    else if (Type == FILE_SENDING)
  880.       sprintf (Temp, "%8lu %5u", TxPosition, TxBlockSize);
  881.    fill_ (23, 1, 23, 78, ' ', LGREY|_BLACK);
  882.    prints (23, 2, WHITE|_BLACK, Temp);
  883.    videoupdate ();
  884. }
  885.  
  886. VOID TPMProgress::End (VOID)
  887. {
  888.    fill_ (22, 1, 23, 78, ' ', LGREY|_BLACK);
  889.    videoupdate ();
  890. }
  891.  
  892. // ----------------------------------------------------------------------------
  893. // Mailer status
  894. // ----------------------------------------------------------------------------
  895.  
  896. #define CENTER_LINE     70
  897.  
  898. class TPMMailStatus : public TMailerStatus
  899. {
  900. public:
  901.    TPMMailStatus (void);
  902.    ~TPMMailStatus (void);
  903.  
  904.    VOID   Update (VOID);
  905.  
  906. private:
  907.    CHAR   Temp[128];
  908. };
  909.  
  910. TPMMailStatus::TPMMailStatus (void)
  911. {
  912. }
  913.  
  914. TPMMailStatus::~TPMMailStatus (void)
  915. {
  916. }
  917.  
  918. VOID TPMMailStatus::Update (VOID)
  919. {
  920.    CHAR Line[128], Num[16];
  921.  
  922.    fill_ (13, 1, 20, 78, ' ', LGREY|_BLACK);
  923.  
  924.    sprintf (Temp, "%s, %s, %s, %s", Address, SysopName, SystemName, Location);
  925.    if (strlen (Temp) > CENTER_LINE)
  926.       Temp[CENTER_LINE] = '\0';
  927.    memset (Line, ' ', sizeof (Line));
  928.    memcpy (&Line[(CENTER_LINE - strlen (Temp)) / 2], Temp, strlen (Temp) + 1);
  929.    prints (13, 4, LGREY|_BLACK, Line);
  930.  
  931.    sprintf (Temp, "Connected at %lu baud with %s", Speed, Program);
  932.    if (strlen (Temp) > CENTER_LINE)
  933.       Temp[CENTER_LINE] = '\0';
  934.    memset (Line, ' ', sizeof (Line));
  935.    memcpy (&Line[(CENTER_LINE - strlen (Temp)) / 2], Temp, strlen (Temp) + 1);
  936.    prints (14, 4, LGREY|_BLACK, Line);
  937.  
  938.    if (Akas[0] == '\0')
  939.       strcpy (Temp, "AKAs: No aka presented");
  940.    else
  941.       sprintf (Temp, "AKAs: %s", Akas);
  942.    if (strlen (Temp) > CENTER_LINE)
  943.       Temp[CENTER_LINE] = '\0';
  944.    memset (Line, ' ', sizeof (Line));
  945.    memcpy (&Line[(CENTER_LINE - strlen (Temp)) / 2], Temp, strlen (Temp) + 1);
  946.    prints (15, 4, LGREY|_BLACK, Line);
  947.  
  948.    strcpy (Temp, " ┌────MailPKT───────Data─────┐     ┌────MailPKT───────Data─────┐ ");
  949.    memset (Line, ' ', sizeof (Line));
  950.    memcpy (&Line[(CENTER_LINE - strlen (Temp)) / 2], Temp, strlen (Temp) + 1);
  951.    prints (17, 4, LCYAN|_BLACK, Line);
  952.  
  953.    strcpy (Temp, "·······························   ·······························");
  954.    if (InPktFiles == 0xFFFFU)
  955.       strcpy (Num, "N/A");
  956.    else
  957.       sprintf (Num, "%u", InPktFiles);
  958.    memcpy (&Temp[11 - strlen (Num) + 1], Num, strlen (Num));
  959.    if (InDataFiles == 0xFFFFU)
  960.       strcpy (Num, "N/A");
  961.    else
  962.       sprintf (Num, "%u", InDataFiles);
  963.    memcpy (&Temp[22 - strlen (Num) + 1], Num, strlen (Num));
  964.    if (OutPktFiles == 0xFFFFU)
  965.       strcpy (Num, "N/A");
  966.    else
  967.       sprintf (Num, "%u", OutPktFiles);
  968.    memcpy (&Temp[45 - strlen (Num) + 1], Num, strlen (Num));
  969.    if (OutDataFiles == 0xFFFFU)
  970.       strcpy (Num, "N/A");
  971.    else
  972.       sprintf (Num, "%u", OutDataFiles);
  973.    memcpy (&Temp[56 - strlen (Num) + 1], Num, strlen (Num));
  974.    memset (Line, ' ', sizeof (Line));
  975.    memcpy (&Line[(CENTER_LINE - strlen (Temp)) / 2], Temp, strlen (Temp) + 1);
  976.    prints (18, 4, LCYAN|_BLACK, Line);
  977.  
  978.    strcpy (Temp, "·······························   ·······························");
  979.    if (InPktFiles == 0xFFFFU)
  980.       strcpy (Num, "N/A");
  981.    else
  982.       sprintf (Num, "%lu", InPktBytes);
  983.    memcpy (&Temp[11 - strlen (Num) + 1], Num, strlen (Num));
  984.    if (InDataFiles == 0xFFFFU)
  985.       strcpy (Num, "N/A");
  986.    else
  987.       sprintf (Num, "%lu", InDataBytes);
  988.    memcpy (&Temp[22 - strlen (Num) + 1], Num, strlen (Num));
  989.    if (OutPktFiles == 0xFFFFU)
  990.       strcpy (Num, "N/A");
  991.    else
  992.       sprintf (Num, "%lu", OutPktBytes);
  993.    memcpy (&Temp[45 - strlen (Num) + 1], Num, strlen (Num));
  994.    if (OutDataFiles == 0xFFFFU)
  995.       strcpy (Num, "N/A");
  996.    else
  997.       sprintf (Num, "%lu", OutDataBytes);
  998.    memcpy (&Temp[56 - strlen (Num) + 1], Num, strlen (Num));
  999.    memset (Line, ' ', sizeof (Line));
  1000.    memcpy (&Line[(CENTER_LINE - strlen (Temp)) / 2], Temp, strlen (Temp) + 1);
  1001.    prints (19, 4, LCYAN|_BLACK, Line);
  1002.  
  1003.    strcpy (Temp, " └──────INBOUND TRAFFIC──────┘     └─────OUTBOUND TRAFFIC──────┘ ");
  1004.    memset (Line, ' ', sizeof (Line));
  1005.    memcpy (&Line[(CENTER_LINE - strlen (Temp)) / 2], Temp, strlen (Temp) + 1);
  1006.    prints (20, 4, LCYAN|_BLACK, Line);
  1007.  
  1008.    videoupdate ();
  1009. }
  1010.  
  1011. // ----------------------------------------------------------------------------
  1012. // Threads
  1013. // ----------------------------------------------------------------------------
  1014.  
  1015. void NodelistThread (PVOID *args)
  1016. {
  1017.    CompileNodelist ((USHORT)args);
  1018. }
  1019.  
  1020. VOID MailProcessorThread (PVOID Args)
  1021. {
  1022.    ULONG Actions = (ULONG)Args;
  1023.    CHAR Temp[128];
  1024.    class TMailProcessor *Processor;
  1025.    class TTicProcessor *Tic;
  1026.  
  1027.    Args = Args;
  1028.  
  1029.    if (Actions & MAIL_TIC) {
  1030.       if ((Tic = new TTicProcessor) != NULL) {
  1031.          Tic->Cfg = Cfg;
  1032.          Tic->Log = Log;
  1033.          if (Daemon == FALSE) {
  1034.             Tic->Output = new TPMList;
  1035.             if (Tic->Output != NULL)
  1036.                Tic->Output->Clear ();
  1037.          }
  1038.          if (Log != NULL)
  1039.             Log->Write ("+Processing inbound TICs");
  1040.          strcpy (Tic->Inbound, Cfg->NormalInbound);
  1041.          Tic->Import ();
  1042.          if (stricmp (Cfg->KnownInbound, Cfg->NormalInbound)) {
  1043.             strcpy (Tic->Inbound, Cfg->KnownInbound);
  1044.             Tic->Import ();
  1045.          }
  1046.          if (stricmp (Cfg->ProtectedInbound, Cfg->NormalInbound) && stricmp (Cfg->ProtectedInbound, Cfg->KnownInbound)) {
  1047.             strcpy (Tic->Inbound, Cfg->ProtectedInbound);
  1048.             Tic->Import ();
  1049.          }
  1050.  
  1051.          if (Tic->Output != NULL)
  1052.             delete Tic->Output;
  1053.          delete Tic;
  1054.       }
  1055.    }
  1056.  
  1057.    if ((Processor = new TMailProcessor) != NULL) {
  1058.       Processor->Cfg = Cfg;
  1059.       Processor->Log = Log;
  1060.       if (Daemon == FALSE) {
  1061.          Processor->Output = new TPMList;
  1062.          Processor->Status = new TPMStatus;
  1063.       }
  1064.  
  1065.       if (Actions & (MAIL_IMPORTNORMAL|MAIL_IMPORTKNOWN|MAIL_IMPORTPROTECTED)) {
  1066.          if (Cfg->ImportCmd[0] != '\0' && !(Actions & MAIL_NOEXTERNAL))
  1067.             RunExternal (Cfg->ImportCmd);
  1068.          else {
  1069.             if (Actions & MAIL_IMPORTNORMAL) {
  1070.                strcpy (Processor->Inbound, Cfg->NormalInbound);
  1071.                while (Processor->IsArcmail () == TRUE)
  1072.                   Processor->UnpackArcmail ();
  1073.                Processor->Import ();
  1074.             }
  1075.             if ((Actions & MAIL_IMPORTKNOWN) && stricmp (Cfg->KnownInbound, Cfg->NormalInbound)) {
  1076.                strcpy (Processor->Inbound, Cfg->KnownInbound);
  1077.                while (Processor->IsArcmail () == TRUE)
  1078.                   Processor->UnpackArcmail ();
  1079.                Processor->Import ();
  1080.             }
  1081.             if ((Actions & MAIL_IMPORTPROTECTED) && stricmp (Cfg->ProtectedInbound, Cfg->NormalInbound) && stricmp (Cfg->ProtectedInbound, Cfg->KnownInbound)) {
  1082.                strcpy (Processor->Inbound, Cfg->ProtectedInbound);
  1083.                while (Processor->IsArcmail () == TRUE)
  1084.                   Processor->UnpackArcmail ();
  1085.                Processor->Import ();
  1086.             }
  1087.  
  1088.             if (Processor->Packets == 0)
  1089.                Log->Write ("+No ECHOmail processed at this time");
  1090.             else
  1091.                Log->Write ("+%d packet(s): %lu NETmail, %lu ECHOmail, %lu Dupes, %lu Bad", Processor->Packets, Processor->NetMail, Processor->MsgTossed - Processor->NetMail, Processor->Duplicate, Processor->Bad);
  1092.          }
  1093.       }
  1094.  
  1095.       if (Actions & MAIL_NEWSGROUP) {
  1096.          Processor->News ();
  1097.          Log->Write ("+%lu message(s): %lu Sent, %lu Received", Processor->MsgSent, Processor->MsgTossed);
  1098.       }
  1099.  
  1100.       if (Actions & MAIL_EMAIL) {
  1101.          Processor->Mail ();
  1102.          Log->Write ("+%lu message(s): %lu Sent, %lu Received", Processor->MsgSent + Processor->MsgTossed, Processor->MsgSent, Processor->MsgTossed);
  1103.       }
  1104.  
  1105.       if ((Actions & MAIL_EXPORT) && (Actions & MAIL_PACK) && Cfg->SeparateNetMail == TRUE) {
  1106.          if (Cfg->PackCmd[0] != '\0' && !(Actions & MAIL_NOEXTERNAL))
  1107.             RunExternal (Cfg->PackCmd);
  1108.          else {
  1109.             Processor->ExportNetMail ();
  1110.             sprintf (Temp, "%sroute.cfg", Cfg->SystemPath);
  1111.             Processor->Pack (Temp);
  1112.          }
  1113.       }
  1114.  
  1115.       if (Actions & MAIL_EXPORT) {
  1116.          if (Cfg->ExportCmd[0] != '\0' && !(Actions & MAIL_NOEXTERNAL))
  1117.             RunExternal (Cfg->ExportCmd);
  1118.          else
  1119.             Processor->Export ();
  1120.       }
  1121.  
  1122.       if (Actions & MAIL_PACK) {
  1123.          if (Cfg->PackCmd[0] != '\0' && !(Actions & MAIL_NOEXTERNAL))
  1124.             RunExternal (Cfg->PackCmd);
  1125.          else {
  1126.             Processor->ExportNetMail ();
  1127.             sprintf (Temp, "%sroute.cfg", Cfg->SystemPath);
  1128.             Processor->Pack (Temp);
  1129.          }
  1130.       }
  1131.  
  1132.       if (Processor->Status != NULL)
  1133.          delete Processor->Status;
  1134.       if (Processor->Output != NULL)
  1135.          delete Processor->Output;
  1136.       delete Processor;
  1137.    }
  1138.  
  1139.    if ((Actions & MAIL_PACK) && Outbound != NULL) {
  1140.       if (Log != NULL)
  1141.          Log->Write ("+Building the outbound queue");
  1142.       Outbound->BuildQueue (Cfg->Outbound);
  1143.       unlink ("rescan.now");
  1144.       if (Log != NULL)
  1145.          Log->Write ("+%u queue record(s) in database", Outbound->TotalNodes);
  1146.    }
  1147.  
  1148.    if (!(Actions & MAIL_POSTQUIT)) {
  1149.       if (Log != NULL)
  1150.          Log->WriteBlank ();
  1151.  
  1152.       RefreshOutbound ();
  1153.    }
  1154. }
  1155.  
  1156. VOID BbsThread (PVOID Args)
  1157. {
  1158.    USHORT Remote;
  1159.    ULONG Flags;
  1160.    class TBbs *Bbs;
  1161.  
  1162.    Args = Args;
  1163.    Remote = REMOTE_NONE;
  1164.  
  1165.    if ((Bbs = new TBbs) != NULL) {
  1166.       Bbs->Log = Log;
  1167.       Bbs->Cfg = Cfg;
  1168.       Bbs->Events = Events;
  1169.       if (Daemon == FALSE) {
  1170.          Bbs->Progress = new TPMProgress;
  1171.          Bbs->MailerStatus = new TPMMailStatus;
  1172.          Bbs->Status = new TPMStatus;
  1173.       }
  1174.       if (Modem != NULL) {
  1175.          Bbs->Com = Modem->Serial;
  1176.          Bbs->Speed = Modem->Speed;
  1177.       }
  1178.       Bbs->Task = Cfg->TaskNumber;
  1179.       Bbs->Run ();
  1180.       Remote = Bbs->Remote;
  1181.  
  1182.       if (Bbs->Status != NULL) {
  1183.          Bbs->Status->Clear ();
  1184.          delete Bbs->Status;
  1185.       }
  1186.       if (Bbs->MailerStatus != NULL)
  1187.          delete Bbs->MailerStatus;
  1188.       if (Bbs->Progress != NULL)
  1189.          delete Bbs->Progress;
  1190.  
  1191.       delete Bbs;
  1192.    }
  1193.  
  1194.    Modem->SendCommand (Cfg->Hangup);
  1195.    if (Modem->Serial != NULL && Log != NULL) {
  1196.       if (Modem->Serial->Carrier () == TRUE)
  1197.          Log->Write ("!Unable to drop carrier");
  1198.    }
  1199.  
  1200.    if (Remote == REMOTE_MAILRECEIVED && Cfg->AfterMailCmd[0] != '\0') {
  1201.       if (Log != NULL)
  1202.          Log->Write (":Running %s", Cfg->AfterMailCmd);
  1203.       SpawnExternal (Cfg->AfterMailCmd);
  1204.    }
  1205.    else if (Remote == REMOTE_USER && Cfg->AfterCallerCmd[0] != '\0') {
  1206.       if (Log != NULL)
  1207.          Log->Write (":Running %s", Cfg->AfterCallerCmd);
  1208.       SpawnExternal (Cfg->AfterCallerCmd);
  1209.    }
  1210.  
  1211.    if ((Remote == REMOTE_MAILER || Remote == REMOTE_MAILRECEIVED) && Outbound != NULL) {
  1212.       if (Log != NULL)
  1213.          Log->Write ("+Building the outbound queue");
  1214.       Outbound->BuildQueue (Cfg->Outbound);
  1215.       Outbound->FirstNode ();
  1216.       if (Log != NULL)
  1217.          Log->Write ("+%u queue record(s) in database", Outbound->TotalNodes);
  1218.  
  1219.       RefreshOutbound ();
  1220.    }
  1221.  
  1222.    if (Log != NULL)
  1223.       Log->WriteBlank ();
  1224.  
  1225.    Flags = 0L;
  1226.    if (Remote == REMOTE_MAILRECEIVED && Events != NULL) {
  1227.       Flags |= MAIL_STARTTIMER;
  1228.       if (Events->ImportNormal == TRUE)
  1229.          Flags |= MAIL_IMPORTNORMAL;
  1230.       if (Events->ImportKnown == TRUE)
  1231.          Flags |= MAIL_IMPORTKNOWN;
  1232.       if (Events->ImportProtected == TRUE)
  1233.          Flags |= MAIL_IMPORTPROTECTED;
  1234.       if (Events->ExportMail == TRUE)
  1235.          Flags |= (MAIL_EXPORT|MAIL_PACK);
  1236.       MailProcessorThread ((PVOID)Flags);
  1237.    }
  1238. }
  1239.  
  1240. VOID LocalThread (PVOID Args)
  1241. {
  1242.    class TBbs *Bbs;
  1243.    class TScreen *Com;
  1244.  
  1245.    Args = Args;
  1246.    if (Log != NULL) {
  1247.       Log->Write ("+Connect Local");
  1248.       Log->Display = FALSE;
  1249.    }
  1250.  
  1251.    if ((Com = new TScreen) != NULL) {
  1252.       Com->Initialize ();
  1253.       if ((Bbs = new TBbs) != NULL) {
  1254.          Bbs->Com = Com;
  1255.          Bbs->Log = Log;
  1256.          Bbs->Cfg = Cfg;
  1257.          Bbs->Events = Events;
  1258.          Bbs->Task = Cfg->TaskNumber;
  1259.          Bbs->Local = TRUE;
  1260.          Bbs->Run ();
  1261.          delete Bbs;
  1262.       }
  1263.       delete Com;
  1264.    }
  1265.  
  1266.    if (Log != NULL) {
  1267.       Log->Display = TRUE;
  1268.       Log->WriteBlank ();
  1269.    }
  1270. }
  1271.  
  1272. VOID MailerThread (PVOID Args)
  1273. {
  1274.    USHORT RetVal = FALSE;
  1275.    ULONG Flags;
  1276.    class TDetect *Detect;
  1277.  
  1278.    Args = Args;
  1279.  
  1280.    if ((Detect = new TDetect) != NULL) {
  1281.       Detect->Log = Log;
  1282.       Detect->Cfg = Cfg;
  1283.       Detect->Events = Events;
  1284.       if (Daemon == FALSE) {
  1285.          Detect->Progress = new TPMProgress;
  1286.          Detect->MailerStatus = new TPMMailStatus;
  1287.          Detect->Status = new TPMStatus;
  1288.       }
  1289.       if (Modem != NULL) {
  1290.          Detect->Com = Modem->Serial;
  1291.          Detect->Speed = Modem->Speed;
  1292.       }
  1293.       if (strchr (PollNode, '/') != NULL || strchr (PollNode, ':') != NULL)
  1294.          Detect->Address.Add (PollNode);
  1295.       RetVal = Detect->RemoteMailer ();
  1296.  
  1297.       if (Detect->Status != NULL) {
  1298.          Detect->Status->Clear ();
  1299.          delete Detect->Status;
  1300.       }
  1301.       if (Detect->MailerStatus != NULL)
  1302.          delete Detect->MailerStatus;
  1303.       if (Detect->Progress != NULL)
  1304.          delete Detect->Progress;
  1305.  
  1306.       delete Detect;
  1307.    }
  1308.  
  1309.    Modem->SendCommand (Cfg->Hangup);
  1310.    if (Modem->Serial != NULL && Log != NULL) {
  1311.       if (Modem->Serial->Carrier () == TRUE)
  1312.          Log->Write ("!Unable to drop carrier");
  1313.    }
  1314.  
  1315.    if (RetVal == REMOTE_MAILRECEIVED && Cfg->AfterMailCmd[0] != '\0') {
  1316.       if (Log != NULL)
  1317.          Log->Write (":Running %s", Cfg->AfterMailCmd);
  1318.       SpawnExternal (Cfg->AfterMailCmd);
  1319.    }
  1320.  
  1321.    if ((RetVal == REMOTE_MAILER || RetVal == REMOTE_MAILRECEIVED) && Outbound != NULL) {
  1322.       if (Log != NULL)
  1323.          Log->Write ("+Building the outbound queue");
  1324.       Outbound->BuildQueue (Cfg->Outbound);
  1325.       Outbound->FirstNode ();
  1326.       if (Log != NULL)
  1327.          Log->Write ("+%u queue record(s) in database", Outbound->TotalNodes);
  1328.       RefreshOutbound ();
  1329.    }
  1330.  
  1331.    if (Log != NULL)
  1332.       Log->WriteBlank ();
  1333.  
  1334.    Flags = 0L;
  1335.    if (RetVal == REMOTE_MAILRECEIVED && Events != NULL) {
  1336.       Flags |= MAIL_STARTTIMER;
  1337.       if (Events->ImportNormal == TRUE)
  1338.          Flags |= MAIL_IMPORTNORMAL;
  1339.       if (Events->ImportKnown == TRUE)
  1340.          Flags |= MAIL_IMPORTKNOWN;
  1341.       if (Events->ImportProtected == TRUE)
  1342.          Flags |= MAIL_IMPORTPROTECTED;
  1343.       if (Events->ExportMail == TRUE)
  1344.          Flags |= (MAIL_EXPORT|MAIL_PACK);
  1345.       MailProcessorThread ((PVOID)Flags);
  1346.    }
  1347. }
  1348.  
  1349. VOID FaxReceiveThread (PVOID Args)
  1350. {
  1351.    CHAR Temp[128];
  1352.    class TFax *Fax;
  1353.  
  1354.    Args = Args;
  1355.  
  1356.    if (Cfg->FaxCommand[0] != '\0') {
  1357. #if defined(__LINUX__)
  1358.       sprintf (Temp, Cfg->FaxCommand, atoi (&Cfg->Device[3]), Cfg->Speed, Modem->Serial->hFile);
  1359. #elif defined(__DOS__)
  1360.       sprintf (Temp, Cfg->FaxCommand, atoi (&Cfg->Device[3]), Cfg->Speed, atoi (Cfg->Device) - 1);
  1361. #endif
  1362.  
  1363.       Log->Write ("+Spawning to %s", Temp);
  1364.       RunExternal (Temp);
  1365.       Log->Write (":Returned from %s", Temp);
  1366.    }
  1367.    else {
  1368.       if ((Fax = new TFax) != NULL) {
  1369.          Fax->Com = Modem->Serial;
  1370.          Fax->Log = Log;
  1371.          Fax->faxreceive ();
  1372.          delete Fax;
  1373.       }
  1374.    }
  1375.  
  1376.    Modem->SendCommand (Cfg->Hangup);
  1377.    if (Modem->Serial != NULL && Log != NULL) {
  1378.       if (Modem->Serial->Carrier () == TRUE)
  1379.          Log->Write ("!Unable to drop carrier");
  1380.    }
  1381. }
  1382.  
  1383. VOID SendInitThread (PVOID Args)
  1384. {
  1385.    Args = Args;
  1386.    Modem->SendCommand (Cfg->Initialize[Current]);
  1387. }
  1388.  
  1389. VOID ModemTimer (VOID)
  1390. {
  1391.    USHORT i;
  1392.  
  1393.    switch (Status) {
  1394.       case 0:
  1395.          if (Log != NULL && ValidateKey ("bbs", NULL, NULL) == KEY_UNREGISTERED) {
  1396.             Log->Write ("!WARNING: No license key found");
  1397.             Log->Write ("!Your system is limited to 2 lines");
  1398. /*
  1399.             if ((i = CheckExpiration ()) == 0) {
  1400.                Log->Write ("!This evaluation copy has expired");
  1401.                Status = 200;
  1402.             }
  1403.             else
  1404.                Log->Write ("!You have %d days left for evaluation", i);
  1405. */
  1406.          }
  1407.          switch (ValidateKey ("bbs", NULL, NULL)) {
  1408.             case KEY_UNREGISTERED:
  1409.             case KEY_BASIC:
  1410.                if (Cfg->TaskNumber > 2) {
  1411.                   Log->Write ("!Invalid line number (%d)", Cfg->TaskNumber);
  1412.                   Status = 200;
  1413.                }
  1414.                break;
  1415.             case KEY_ADVANCED:
  1416.                if (Cfg->TaskNumber > 5) {
  1417.                   Log->Write ("!Invalid line number (%d)", Cfg->TaskNumber);
  1418.                   Status = 200;
  1419.                }
  1420.                break;
  1421.          }
  1422.          if (Status != 200) {
  1423.             if (Modem == NULL && Cfg != NULL) {
  1424.                if ((Modem = new TModem) != NULL) {
  1425.                   Modem->Log = Log;
  1426.                   strcpy (Modem->Device, Cfg->Device);
  1427.                   Modem->Speed = Cfg->Speed;
  1428.                   Modem->LockSpeed = Cfg->LockSpeed;
  1429.                   if (Cfg->Ring[0] != '\0')
  1430.                      strcpy (Modem->Ring, Cfg->Ring);
  1431.                   Modem->Initialize ();
  1432.                   Status = INITIALIZE;
  1433.                   Current = 0;
  1434.                }
  1435.             }
  1436.             if (Outbound != NULL) {
  1437.                if (Log != NULL)
  1438.                   Log->Write ("+Building the outbound queue");
  1439.                Outbound->BuildQueue (Cfg->Outbound);
  1440.                if (Outbound->FirstNode () == FALSE)
  1441.                   Outbound->New ();
  1442.                if (Log != NULL)
  1443.                   Log->Write ("+%u queue record(s) in database", Outbound->TotalNodes);
  1444.                RefreshOutbound ();
  1445.             }
  1446.          }
  1447.          break;
  1448.  
  1449.       case INITIALIZE:
  1450.          if (Modem != NULL && Cfg != NULL) {
  1451.             while (Current < 3 && Cfg->Initialize[Current][0] == '\0')
  1452.                Current++;
  1453.             if (Current >= 3) {
  1454.                Status = WAITFORCALL;
  1455.                TimeOut = TimerSet (10L * 6000L);
  1456.                Modem->Terminal = TRUE;
  1457.             }
  1458.             else {
  1459.                Modem->Terminal = FALSE;
  1460.                SendInitThread (NULL);
  1461.                Status = WAITFOROK;
  1462.                TimeOut = TimerSet (500);
  1463.             }
  1464.          }
  1465.          break;
  1466.  
  1467.       case WAITFOROK:
  1468.          if (Modem->GetResponse () == OK) {
  1469.             while (++Current < 3 && Cfg->Initialize[Current][0] == '\0')
  1470.                ;
  1471.             if (Current >= 3) {
  1472.                Status = WAITFORCALL;
  1473.                TimeOut = TimerSet (10L * 6000L);
  1474.             }
  1475.             else
  1476.                Status = INITIALIZE;
  1477.          }
  1478.          else if (TimeUp (TimeOut) == TRUE) {
  1479.             if (Log != NULL)
  1480.                Log->Write ("!Modem doesn't report 'Ok'");
  1481.             Status = INITIALIZE;
  1482.          }
  1483.          break;
  1484.  
  1485.       case WAITFORCALL:
  1486.          if ((i = Modem->GetResponse ()) == RING && Cfg != NULL) {
  1487.             Modem->SendCommand (Cfg->Answer);
  1488.             Status = ANSWERING;
  1489.             TimeOut = TimerSet (4500L);
  1490.          }
  1491.          else if (i == CONNECT) {
  1492.             BbsThread (NULL);
  1493.             Status = HANGUP;
  1494.          }
  1495.          else if (i == FAX) {
  1496.             FaxReceiveThread (NULL);
  1497.             Status = HANGUP;
  1498.          }
  1499.          else if (TimeUp (TimeOut) == TRUE) {
  1500.             Status = INITIALIZE;
  1501.             Current = 0;
  1502.          }
  1503.          break;
  1504.  
  1505.       case ANSWERING:
  1506.          if ((i = Modem->GetResponse ()) == CONNECT) {
  1507.             BbsThread (NULL);
  1508.             Status = HANGUP;
  1509.          }
  1510.          else if (i == FAX) {
  1511.             FaxReceiveThread (NULL);
  1512.             Status = HANGUP;
  1513.          }
  1514.          else if (i != NO_RESPONSE && i != RING)
  1515.             Status = INITIALIZE;
  1516.          else if (TimeUp (TimeOut) == TRUE) {
  1517.             if (Log != NULL)
  1518.                Log->Write ("!Answer timer expired");
  1519.             Status = HANGUP;
  1520.          }
  1521.          break;
  1522.  
  1523.       case HANGUP:
  1524.          Modem->Speed = Cfg->Speed;
  1525.          Modem->Initialize ();
  1526.          Status = INITIALIZE;
  1527.          Current = 0;
  1528.          if (Events != NULL)
  1529.             CallDelay = TimerSet ((ULONG)Events->CallDelay * 100L);
  1530.          break;
  1531.  
  1532.       case WAITFORCONNECT:
  1533.          if ((i = Modem->GetResponse ()) == CONNECT) {
  1534.             MailerThread (NULL);
  1535.             Status = HANGUP;
  1536.          }
  1537.          else if (i != NO_RESPONSE) {
  1538.             Status = INITIALIZE;
  1539.             Current = 0;
  1540.             if (Events != NULL)
  1541.                CallDelay = TimerSet ((ULONG)Events->CallDelay * 100L);
  1542.          }
  1543.          else if (TimeUp (TimeOut) == TRUE) {
  1544.             if (Log != NULL)
  1545.                Log->Write ("!Dialing timer expired");
  1546.             Status = HANGUP;
  1547.          }
  1548.          break;
  1549.    }
  1550.  
  1551.    ModemT = TimerSet (MODEM_DELAY / 10L);
  1552. }
  1553.  
  1554. VOID EventsTimer (PVOID Args)
  1555. {
  1556.    USHORT i, DoCall = FALSE;
  1557.    CHAR *p;
  1558.    struct stat statbuf;
  1559.    class TAddress Address;
  1560.  
  1561.    Args = Args;
  1562.  
  1563.    Events->TimeToNext ();
  1564.    if (Events->NextNumber != 0) {
  1565.       if ((p = (CHAR *)malloc (128)) != NULL) {
  1566.          sprintf (p, "Event %d starts in %d minute(s)", Events->NextNumber, Events->TimeRemain);
  1567.          if (Daemon == FALSE)
  1568.             prints (22, 2, WHITE|_BLACK, p);
  1569.          free (p);
  1570.       }
  1571.  
  1572.       Events->First ();
  1573.       for (i = 1; i < Events->NextNumber; i++)
  1574.          Events->Next ();
  1575.  
  1576.       if ((p = (CHAR *)malloc (128)) != NULL) {
  1577.          strcpy (p, "Flags for next event:");
  1578.          if (Events->MailOnly == FALSE)
  1579.             strcat (p, " B");
  1580.          if (Events->SendNormal == FALSE && Events->SendCrash == FALSE && Events->SendDirect == FALSE && Events->SendImmediate == FALSE)
  1581.             strcat (p, " R");
  1582.          if (Events->Force == TRUE)
  1583.             strcat (p, " F");
  1584.          if (Events->SendCrash == TRUE)
  1585.             strcat (p, " C");
  1586.          if (Events->SendDirect == TRUE)
  1587.             strcat (p, " D");
  1588.          if (Events->SendImmediate == TRUE)
  1589.             strcat (p, " I");
  1590.          if (Events->AllowRequests == FALSE)
  1591.             strcat (p, " N");
  1592.          if (Events->Dynamic == TRUE)
  1593.             strcat (p, " Y");
  1594.          if (Events->ForceCall == TRUE) {
  1595.             strcat (p, " P=");
  1596.             strcat (p, Events->Address);
  1597.          }
  1598.          if (Daemon == FALSE)
  1599.             prints (23, 2, WHITE|_BLACK, p);
  1600.          free (p);
  1601.       }
  1602.    }
  1603.  
  1604.    if (Events->SetCurrent () == TRUE) {
  1605.       if (Events->Started == TRUE) {
  1606.          if (Log != NULL) {
  1607.             if (Events->Label[0] != '\0')
  1608.                Log->Write (":Starting Event %d - %s", Events->Number, Events->Label);
  1609.             else
  1610.                Log->Write (":Starting Event %d", Events->Number);
  1611.          }
  1612.  
  1613.          if (Events->Command[0] != '\0') {
  1614.             Log->Write ("#Executing %s", Events->Command);
  1615.             RunExternal (Events->Command);
  1616.          }
  1617.  
  1618.          if (Events->StartImport == TRUE && Events->StartExport == TRUE && Cfg->UseSinglePass == TRUE) {
  1619.             RunExternal (Cfg->SinglePassCmd);
  1620.             RunExternal (Cfg->PackCmd);
  1621.          }
  1622.          else {
  1623.             if (Events->StartImport == TRUE) {
  1624.                if (Events->ImportNormal == TRUE || Events->ImportProtected == TRUE || Events->ImportKnown == TRUE)
  1625.                   RunExternal (Cfg->ImportCmd);
  1626.             }
  1627.             if (Events->StartExport == TRUE) {
  1628.                if (Cfg->SeparateNetMail == TRUE)
  1629.                   RunExternal (Cfg->PackCmd);
  1630.                RunExternal (Cfg->ExportCmd);
  1631.                RunExternal (Cfg->PackCmd);
  1632.             }
  1633.          }
  1634.  
  1635.          if (Outbound != NULL) {
  1636.             if (Log != NULL)
  1637.                Log->Write ("+Building the outbound queue");
  1638.             Outbound->BuildQueue (Cfg->Outbound);
  1639.             unlink ("rescan.now");
  1640.  
  1641.             if (Events->ForceCall == TRUE && Events->Address[0] != '\0') {
  1642.                Outbound->New ();
  1643.                Address.Parse (Events->Address);
  1644.                if (Cfg->MailAddress.First () == TRUE) {
  1645.                   if (Address.Zone == 0)
  1646.                      Address.Zone = Cfg->MailAddress.Zone;
  1647.                   if (Address.Net == 0)
  1648.                      Address.Net = Cfg->MailAddress.Net;
  1649.                   Address.Add ();
  1650.                   Address.First ();
  1651.                }
  1652.                Outbound->Zone = Address.Zone;
  1653.                Outbound->Net = Address.Net;
  1654.                Outbound->Node = Address.Node;
  1655.                Outbound->Point = Address.Point;
  1656.                Outbound->Poll = TRUE;
  1657.                Outbound->Crash = Events->SendCrash;
  1658.                Outbound->Direct = Events->SendDirect;
  1659.                Outbound->Normal = Events->SendNormal;
  1660.                Outbound->Immediate = Events->SendImmediate;
  1661.                Outbound->Add ();
  1662.             }
  1663.             else
  1664.                Outbound->FirstNode ();
  1665.  
  1666.             if (Log != NULL)
  1667.                Log->Write ("+%u queue record(s) in database", Outbound->TotalNodes);
  1668.             RefreshOutbound ();
  1669.          }
  1670.  
  1671.          CallDelay = TimerSet ((ULONG)Events->CallDelay * 100L);
  1672.          Events->Save ();
  1673.       }
  1674.  
  1675.       if (CallDelay == 0L)
  1676.          CallDelay = TimerSet ((ULONG)Events->CallDelay * 100L);
  1677.  
  1678.       if (TimeUp (CallDelay) && Outbound != NULL && Outbound->TotalNodes > 0 && Status != WAITFORCONNECT) {
  1679.          if (Events->Address[0] != '\0') {
  1680.             Address.Parse (Events->Address);
  1681.             if (Cfg->MailAddress.First () == TRUE) {
  1682.                if (Address.Zone == 0)
  1683.                   Address.Zone = Cfg->MailAddress.Zone;
  1684.                if (Address.Net == 0)
  1685.                   Address.Net = Cfg->MailAddress.Net;
  1686.                Address.Add ();
  1687.                Address.First ();
  1688.             }
  1689.             DoCall = FALSE;
  1690.             if (Outbound->FirstNode () == TRUE)
  1691.                do {
  1692.                   if (Outbound->Zone == Address.Zone && Outbound->Net == Address.Net && Outbound->Node == Address.Node && Outbound->Point == Address.Point) {
  1693.                      DoCall = TRUE;
  1694.                      break;
  1695.                   }
  1696.                } while (Outbound->NextNode () == TRUE);
  1697.          }
  1698.  
  1699.          if (Events->Address[0] == '\0' || DoCall == TRUE) {
  1700.             DoCall = FALSE;
  1701.             if (Events->SendCrash == TRUE && Outbound->Crash == TRUE)
  1702.                DoCall = TRUE;
  1703.             if (Events->SendDirect == TRUE && Outbound->Direct == TRUE)
  1704.                DoCall = TRUE;
  1705.             if (Events->SendNormal == TRUE && Outbound->Normal == TRUE)
  1706.                DoCall = TRUE;
  1707.             if (Events->SendImmediate == TRUE && Outbound->Immediate == TRUE)
  1708.                DoCall = TRUE;
  1709.          }
  1710.  
  1711.          if (DoCall == TRUE) {
  1712.             strcpy (PollNode, Outbound->Address);
  1713.             Modem->Terminal = FALSE;
  1714.             strcpy (Modem->NodelistPath, Cfg->NodelistPath);
  1715.             strcpy (Modem->DialCmd, Cfg->Dial);
  1716.             Modem->Poll (PollNode);
  1717.             Status = WAITFORCONNECT;
  1718.             TimeOut = TimerSet ((ULONG)Cfg->DialTimeout * 100L);
  1719.          }
  1720.  
  1721.          DoCall = FALSE;
  1722.          if (Events->Address[0] == '\0') {
  1723.             while (Outbound->NextNode () == TRUE) {
  1724.                if (Events->SendCrash == TRUE && Outbound->Crash == TRUE) {
  1725.                   DoCall = TRUE;
  1726.                   break;
  1727.                }
  1728.                if (Events->SendDirect == TRUE && Outbound->Direct == TRUE) {
  1729.                   DoCall = TRUE;
  1730.                   break;
  1731.                }
  1732.                if (Events->SendNormal == TRUE && Outbound->Normal == TRUE) {
  1733.                   DoCall = TRUE;
  1734.                   break;
  1735.                }
  1736.                if (Events->SendImmediate == TRUE && Outbound->Immediate == TRUE) {
  1737.                   DoCall = TRUE;
  1738.                   break;
  1739.                }
  1740.             }
  1741.             if (DoCall == FALSE) {
  1742.                if (Outbound->FirstNode () == TRUE)
  1743.                   do {
  1744.                      if (Events->SendCrash == TRUE && Outbound->Crash == TRUE) {
  1745.                         DoCall = TRUE;
  1746.                         break;
  1747.                      }
  1748.                      if (Events->SendDirect == TRUE && Outbound->Direct == TRUE) {
  1749.                         DoCall = TRUE;
  1750.                         break;
  1751.                      }
  1752.                      if (Events->SendNormal == TRUE && Outbound->Normal == TRUE) {
  1753.                         DoCall = TRUE;
  1754.                         break;
  1755.                      }
  1756.                      if (Events->SendImmediate == TRUE && Outbound->Immediate == TRUE) {
  1757.                         DoCall = TRUE;
  1758.                         break;
  1759.                      }
  1760.                   } while (Outbound->NextNode () == TRUE);
  1761.             }
  1762.          }
  1763.       }
  1764.    }
  1765.  
  1766.    if (stat ("rescan.now", &statbuf) == 0) {
  1767.       if (Log != NULL)
  1768.          Log->Write ("+Building the outbound queue");
  1769.       Outbound->BuildQueue (Cfg->Outbound);
  1770.       unlink ("rescan.now");
  1771.       if (Log != NULL)
  1772.          Log->Write ("+%u queue record(s) in database", Outbound->TotalNodes);
  1773.    }
  1774.  
  1775.    EventsT = TimerSet (EVENTS_DELAY / 10L);
  1776.    if (Daemon == FALSE)
  1777.       videoupdate ();
  1778. }
  1779.  
  1780. VOID AddShadow (VOID)
  1781. {
  1782.    wshadow (DGREY|_BLACK);
  1783. }
  1784.  
  1785. VOID AddFileShadow (VOID)
  1786. {
  1787.    whline (2, 0, 27, 3, RED|_LGREY);
  1788.    whline (4, 0, 27, 3, RED|_LGREY);
  1789.    wshadow (DGREY|_BLACK);
  1790. }
  1791.  
  1792. VOID AddUtilityShadow (VOID)
  1793. {
  1794.    whline (1, 0, 31, 3, RED|_LGREY);
  1795.    whline (5, 0, 31, 3, RED|_LGREY);
  1796.    whline (7, 0, 31, 3, RED|_LGREY);
  1797.    wshadow (DGREY|_BLACK);
  1798. }
  1799.  
  1800. VOID AddMailShadow (VOID)
  1801. {
  1802.    whline (3, 0, 31, 3, RED|_LGREY);
  1803.    whline (5, 0, 31, 3, RED|_LGREY);
  1804.    whline (9, 0, 31, 3, RED|_LGREY);
  1805.    wshadow (DGREY|_BLACK);
  1806. }
  1807.  
  1808. VOID AddConfigureShadow (VOID)
  1809. {
  1810.    whline (4, 0, 31, 3, RED|_LGREY);
  1811.    wshadow (DGREY|_BLACK);
  1812. }
  1813.  
  1814. VOID AddBBSShadow (VOID)
  1815. {
  1816.    whline (1, 0, 31, 3, RED|_LGREY);
  1817.    wshadow (DGREY|_BLACK);
  1818. }
  1819.  
  1820. VOID AddHelpShadow (VOID)
  1821. {
  1822.    whline (4, 0, 31, 3, RED|_LGREY);
  1823.    wshadow (DGREY|_BLACK);
  1824. }
  1825.  
  1826. VOID ProcessSelection (VOID)
  1827. {
  1828.    struct _item_t *item;
  1829.  
  1830.    item = wmenuicurr ();
  1831.    last_sel = item->tagid;
  1832. }
  1833.  
  1834. VOID ProcessMenu (VOID)
  1835. {
  1836.    USHORT RetVal = FALSE;
  1837.  
  1838.    wmenubeg (0, 0, 0, 79, 5, BLACK|_LGREY, BLACK|_LGREY, NULL);
  1839.    wmenuitem (0,  1, " File ", 0, 100, M_HASPD, NULL, 0, 0);
  1840.       wmenubeg (1, 1, 9, 28, 3, RED|_LGREY, BLUE|_LGREY, AddFileShadow);
  1841.       wmenuitem ( 0, 0, " Request file(s)    Alt-R ", 0, 107, M_CLALL, ProcessSelection, 0, 0);
  1842.       wmenuitem ( 1, 0, " Send file(s)       Alt-S ", 0, 108, M_CLALL, ProcessSelection, 0, 0);
  1843.       wmenuitem ( 3, 0, " Rebuild Outbound   Alt-Q ", 0, 106, M_CLALL, ProcessSelection, 0, 0);
  1844.       wmenuitem ( 5, 0, " Import AREAS.BBS         ", 0, 121, M_CLALL, ProcessSelection, 0, 0);
  1845.       wmenuitem ( 6, 0, " Write AREAS.BBS          ", 0, 117, M_CLALL, ProcessSelection, 0, 0);
  1846.       wmenuend (107, M_PD|M_SAVE, 0, 0, BLUE|_LGREY, WHITE|_LGREY, DGREY|_LGREY, YELLOW|_BLACK);
  1847.    wmenuitem (0,  7, " Utility ", 0, 200, M_HASPD, NULL, 0, 0);
  1848.       wmenubeg (1, 7, 11, 38, 3, RED|_LGREY, BLUE|_LGREY, AddUtilityShadow);
  1849.       wmenuitem ( 0, 0, " Forced poll            Alt-M ", 0, 109, M_CLALL, ProcessSelection, 0, 0);
  1850.       wmenuitem ( 2, 0, " Request ECHOmail link        ", 0, 111, M_CLALL|M_NOSEL, ProcessSelection, 0, 0);
  1851.       wmenuitem ( 3, 0, " New ECHOmail link            ", 0, 112, M_CLALL, ProcessSelection, 0, 0);
  1852.       wmenuitem ( 4, 0, " Rescan ECHOmail              ", 0, 113, M_CLALL, ProcessSelection, 0, 0);
  1853.       wmenuitem ( 6, 0, " New TIC file link            ", 0, 114, M_CLALL|M_NOSEL, ProcessSelection, 0, 0);
  1854.       wmenuitem ( 8, 0, " Build nodelist index         ", 0, 119, M_CLALL, ProcessSelection, 0, 0);
  1855.       wmenuend (109, M_PD|M_SAVE, 0, 0, BLUE|_LGREY, WHITE|_LGREY, DGREY|_LGREY, YELLOW|_BLACK);
  1856.    wmenuitem (0, 16, " Mail ", 0, 300, M_HASPD, NULL, 0, 0);
  1857.       wmenubeg (1, 16, 13, 45, 3, RED|_LGREY, BLUE|_LGREY, AddMailShadow);
  1858.       wmenuitem ( 0, 0, " Import Mail          Alt-I ", 0, 101, M_CLALL, ProcessSelection, 0, 0);
  1859.       wmenuitem ( 1, 0, " Export echomail            ", 0, 102, M_CLALL, ProcessSelection, 0, 0);
  1860.       wmenuitem ( 2, 0, " Pack NetMail               ", 0, 103, M_CLALL, ProcessSelection, 0, 0);
  1861.       wmenuitem ( 4, 0, " Process ECHOmail     Alt-P ", 0, 104, M_CLALL, ProcessSelection, 0, 0);
  1862.       wmenuitem ( 6, 0, " Process NEWSgroups         ", 0, 116, M_CLALL, ProcessSelection, 0, 0);
  1863.       wmenuitem ( 7, 0, " Process E-Mail             ", 0, 118, M_CLALL, ProcessSelection, 0, 0);
  1864.       wmenuitem ( 8, 0, " Process TIC files          ", 0, 105, M_CLALL, ProcessSelection, 0, 0);
  1865.       wmenuitem (10, 0, " Import from bad msgs.      ", 0, 105, M_CLALL, ProcessSelection, 0, 0);
  1866.       wmenuend (101, M_PD|M_SAVE, 0, 0, BLUE|_LGREY, WHITE|_LGREY, DGREY|_LGREY, YELLOW|_BLACK);
  1867.    wmenuitem (0, 22, " Configure ", 0, 400, M_HASPD, NULL, 0, 0);
  1868.       wmenubeg (1, 22, 13, 43, 3, RED|_LGREY, BLUE|_LGREY, AddConfigureShadow);
  1869.       wmenuitem ( 0, 0, " Global          -> ", 0, 410, 0, NULL, 0, 0);
  1870.          wmenubeg (1, 44, 9, 64, 3, RED|_LGREY, BLUE|_LGREY, AddShadow);
  1871.          wmenuitem (0, 0, " General Options   ", 0, 201, M_CLALL, ProcessSelection, 0, 0);
  1872.          wmenuitem (1, 0, " Site Informations ", 0, 202, M_CLALL, ProcessSelection, 0, 0);
  1873.          wmenuitem (2, 0, " Addresses         ", 0, 204, M_CLALL, ProcessSelection, 0, 0);
  1874.          wmenuitem (3, 0, " Directory / Paths ", 0, 208, M_CLALL, ProcessSelection, 0, 0);
  1875.          wmenuitem (4, 0, " Time Adjustment   ", 0, 205, M_CLALL|M_NOSEL, ProcessSelection, 0, 0);
  1876.          wmenuitem (5, 0, " Internet Options  ", 0, 206, M_CLALL, ProcessSelection, 0, 0);
  1877.          wmenuitem (6, 0, " Fax Options       ", 0, 207, M_CLALL, ProcessSelection, 0, 0);
  1878.          wmenuend (201, M_PD|M_SAVE, 0, 0, BLUE|_LGREY, WHITE|_LGREY, DGREY|_LGREY, YELLOW|_BLACK);
  1879.       wmenuitem ( 1, 0, " Mailer          -> ", 0, 420, 0, NULL, 0, 0);
  1880.          wmenubeg (2, 44, 9, 66, 3, RED|_LGREY, BLUE|_LGREY, AddShadow);
  1881.          wmenuitem ( 0, 0, " Miscellaneous       ", 0, 310, M_CLALL, ProcessSelection, 0, 0);
  1882.          wmenuitem ( 1, 0, " Mail Processing     ", 0, 311, M_CLALL, ProcessSelection, 0, 0);
  1883.          wmenuitem ( 2, 0, " Areafix             ", 0, 312, M_CLALL, ProcessSelection, 0, 0);
  1884.          wmenuitem ( 3, 0, " TIC Processor       ", 0, 301, M_CLALL|M_NOSEL, ProcessSelection, 0, 0);
  1885.          wmenuitem ( 4, 0, " Files Requests      ", 0, 302, M_CLALL|M_NOSEL, ProcessSelection, 0, 0);
  1886.          wmenuitem ( 5, 0, " External Processing ", 0, 304, M_CLALL, ProcessSelection, 0, 0);
  1887.          wmenuend (310, M_PD|M_SAVE, 0, 0, BLUE|_LGREY, WHITE|_LGREY, DGREY|_LGREY, YELLOW|_BLACK);
  1888.       wmenuitem ( 2, 0, " BBS             -> ", 0, 430, 0, NULL, 0, 0);
  1889.          wmenubeg (3, 44, 12, 65, 3, RED|_LGREY, BLUE|_LGREY, AddShadow);
  1890.          wmenuitem (0, 0, " Message Areas      ", 0, 401, M_CLALL, ProcessSelection, 0, 0);
  1891.          wmenuitem (1, 0, " File Areas         ", 0, 402, M_CLALL, ProcessSelection, 0, 0);
  1892.          wmenuitem (2, 0, " General Options    ", 0, 403, M_CLALL, ProcessSelection, 0, 0);
  1893.          wmenuitem (3, 0, " Offline Reader     ", 0, 404, M_CLALL, ProcessSelection, 0, 0);
  1894.          wmenuitem (4, 0, " New Users          ", 0, 405, M_CLALL, ProcessSelection, 0, 0);
  1895.          wmenuitem (5, 0, " User Limits        ", 0, 406, M_CLALL, ProcessSelection, 0, 0);
  1896.          wmenuitem (6, 0, " Paging Hours       ", 0, 407, M_CLALL|M_NOSEL, ProcessSelection, 0, 0);
  1897.          wmenuitem (7, 0, " External Protocols ", 0, 408, M_CLALL, ProcessSelection, 0, 0);
  1898.          wmenuend (401, M_PD|M_SAVE, 0, 0, BLUE|_LGREY, WHITE|_LGREY, DGREY|_LGREY, YELLOW|_BLACK);
  1899.       wmenuitem ( 3, 0, " Modem           -> ", 0, 440, 0, NULL, 0, 0);
  1900.          wmenubeg (4, 44, 9, 67, 3, RED|_LGREY, BLUE|_LGREY, AddShadow);
  1901.          wmenuitem (0, 0, " Hardware              ", 0, 501, M_CLALL, ProcessSelection, 0, 0);
  1902.          wmenuitem (1, 0, " Command Strings       ", 0, 502, M_CLALL, ProcessSelection, 0, 0);
  1903.          wmenuitem (2, 0, " Answer Control        ", 0, 503, M_CLALL, ProcessSelection, 0, 0);
  1904.          wmenuitem (3, 0, " Nodelist Flags        ", 0, 504, M_CLALL, ProcessSelection, 0, 0);
  1905.          wmenuend (501, M_PD|M_SAVE, 0, 0, BLUE|_LGREY, WHITE|_LGREY, DGREY|_LGREY, YELLOW|_BLACK);
  1906.       wmenuitem ( 5, 0, " Event Scheduler    ", 0, 601, M_CLALL, ProcessSelection, 0, 0);
  1907.       wmenuitem ( 6, 0, " Nodelist           ", 0, 602, M_CLALL, ProcessSelection, 0, 0);
  1908.       wmenuitem ( 7, 0, " Compressors        ", 0, 603, M_CLALL, ProcessSelection, 0, 0);
  1909.       wmenuitem ( 8, 0, " Nodes              ", 0, 604, M_CLALL, ProcessSelection, 0, 0);
  1910.       wmenuitem ( 9, 0, " Menu Files         ", 0, 605, M_CLALL, ProcessSelection, 0, 0);
  1911.       wmenuitem (10, 0, " User Editor        ", 0, 606, M_CLALL, ProcessSelection, 0, 0);
  1912.       wmenuend (410, M_PD|M_SAVE, 0, 0, BLUE|_LGREY, WHITE|_LGREY, DGREY|_LGREY, YELLOW|_BLACK);
  1913.    wmenuitem (0, 33, " BBS ", 0, 500, M_HASPD, NULL, 0, 0);
  1914.       wmenubeg (1, 33, 6, 55, 3, RED|_LGREY, BLUE|_LGREY, AddBBSShadow);
  1915.       wmenuitem ( 0, 0, " Local Login   Alt-K ", 0, 115, M_CLALL, ProcessSelection, 0, 0);
  1916.       wmenuitem ( 2, 0, " Answer Now    Alt-A ", 0, 506, M_CLALL, ProcessSelection, 0, 0);
  1917.       wmenuitem ( 3, 0, " Hangup        Alt-H ", 0, 505, M_CLALL|M_NOSEL, ProcessSelection, 0, 0);
  1918.       wmenuend (115, M_PD|M_SAVE, 0, 0, BLUE|_LGREY, WHITE|_LGREY, DGREY|_LGREY, YELLOW|_BLACK);
  1919.    wmenuitem (0, 38, " Help ", 0, 600, M_HASPD, NULL, 0, 0);
  1920.       wmenubeg (1, 38, 8, 61, 3, RED|_LGREY, BLUE|_LGREY, AddHelpShadow);
  1921.       wmenuitem ( 0, 0, " Help index...        ", 0, 901, M_CLALL|M_NOSEL, ProcessSelection, 0, 0);
  1922.       wmenuitem ( 1, 0, " General help...      ", 0, 902, M_CLALL|M_NOSEL, ProcessSelection, 0, 0);
  1923.       wmenuitem ( 2, 0, " Using help...        ", 0, 903, M_CLALL|M_NOSEL, ProcessSelection, 0, 0);
  1924.       wmenuitem ( 3, 0, " Keys help...         ", 0, 904, M_CLALL|M_NOSEL, ProcessSelection, 0, 0);
  1925.       wmenuitem ( 5, 0, " Product informations ", 0, 905, M_CLALL, ProcessSelection, 0, 0);
  1926.       wmenuend (901, M_PD|M_SAVE, 0, 0, BLUE|_LGREY, WHITE|_LGREY, DGREY|_LGREY, YELLOW|_BLACK);
  1927.  
  1928.    last_sel = (short)((last_sel / 100) * 100);
  1929.    wmenuend (last_sel, M_OMNI, 0, 0, BLUE|_LGREY, WHITE|_LGREY, DGREY|_LGREY, YELLOW|_BLACK);
  1930.  
  1931.    kbput (0x1C0D);
  1932.    if (wmenuget () != -1) {
  1933.       switch (last_sel) {
  1934.          case 101:
  1935.             MailProcessorThread ((PVOID)(MAIL_IMPORTKNOWN|MAIL_IMPORTPROTECTED|MAIL_IMPORTNORMAL));
  1936.             break;
  1937.          case 102:
  1938.             MailProcessorThread ((PVOID)(MAIL_EXPORT));
  1939.             break;
  1940.          case 103:      // System / Pack mail
  1941.             MailProcessorThread ((PVOID)(MAIL_PACK|MAIL_STARTTIMER));
  1942.             break;
  1943.          case 104:      // System / Process ECHOmail
  1944.             MailProcessorThread ((PVOID)(MAIL_IMPORTKNOWN|MAIL_IMPORTPROTECTED|MAIL_IMPORTNORMAL|MAIL_EXPORT|MAIL_PACK|MAIL_STARTTIMER));
  1945.             break;
  1946.          case 105:      // System / Process TIC
  1947.             MailProcessorThread ((PVOID)(MAIL_TIC|MAIL_STARTTIMER));
  1948.             break;
  1949.          case 106:
  1950.             if (Outbound != NULL) {
  1951.                if (Log != NULL)
  1952.                   Log->Write ("+Building the outbound queue");
  1953.                Outbound->BuildQueue (Cfg->Outbound);
  1954.                unlink ("rescan.now");
  1955.                if (Log != NULL)
  1956.                   Log->Write ("+%u queue record(s) in database", Outbound->TotalNodes);
  1957.  
  1958.                RefreshOutbound ();
  1959.             }
  1960.             break;
  1961.          case 107:
  1962.             CRequestDlg ();
  1963.             break;
  1964.          case 108:
  1965.             CAttachDlg ();
  1966.             break;
  1967.          case 109:
  1968.             CPollDlg ();
  1969.             break;
  1970.          case 112:
  1971.             CNewEcholinkDlg ();
  1972.             break;
  1973.          case 113:
  1974.             CRescanDlg ();
  1975.             break;
  1976.          case 115:
  1977.             kbput (0x2500);
  1978.             break;
  1979.          case 116:      // System / Process Newsgroups
  1980.             MailProcessorThread ((PVOID)(MAIL_NEWSGROUP|MAIL_STARTTIMER));
  1981.             break;
  1982.          case 117: {    // System / EchoMail / Write AREAS.BBS
  1983.             class TAreaManager *Mgr;
  1984.  
  1985.             if ((Mgr = new TAreaManager) != NULL) {
  1986.                Mgr->Cfg = Cfg;
  1987.                Mgr->Log = Log;
  1988.                Mgr->UpdateAreasBBS ();
  1989.                delete Mgr;
  1990.             }
  1991.             break;
  1992.          }
  1993.          case 118:      // System / Process E-Mail
  1994.             MailProcessorThread ((PVOID)(MAIL_EMAIL|MAIL_STARTTIMER));
  1995.             break;
  1996.          case 119:
  1997.             CompileNodelist (TRUE);
  1998.             break;
  1999.          case 121: {    // System / EchoMail / Import AREAS.BBS
  2000.             class TAreaManager *Mgr;
  2001.  
  2002.             if ((Mgr = new TAreaManager) != NULL) {
  2003.                Mgr->Cfg = Cfg;
  2004.                Mgr->Log = Log;
  2005.                Mgr->ImportAreasBBS ();
  2006.                delete Mgr;
  2007.             }
  2008.             break;
  2009.          }
  2010.          case 130:
  2011.             kbput (0x2d00);
  2012.             break;
  2013.          case 201:
  2014.             if ((RetVal = CGeneralOptDlg ()) == TRUE)
  2015.                Cfg->Save ();
  2016.             break;
  2017.          case 202:
  2018.             if ((RetVal = CSiteInfoDlg ()) == TRUE)
  2019.                Cfg->Save ();
  2020.             break;
  2021.          case 204:
  2022.             if ((RetVal = CAddressDlg ()) == TRUE)
  2023.                Cfg->Save ();
  2024.             break;
  2025.          case 206:
  2026.             if ((RetVal = CInternetDlg ()) == TRUE)
  2027.                Cfg->Save ();
  2028.             break;
  2029.          case 207:
  2030.             if ((RetVal = CFaxDlg ()) == TRUE)
  2031.                Cfg->Save ();
  2032.             break;
  2033.          case 208:
  2034.             if ((RetVal = CDirectoriesDlg ()) == TRUE)
  2035.                Cfg->Save ();
  2036.             break;
  2037.          case 304:
  2038.             if ((RetVal = CExternalProcDlg ()) == TRUE)
  2039.                Cfg->Save ();
  2040.             break;
  2041.          case 310:
  2042.             if ((RetVal = CMailerMiscDlg ()) == TRUE)
  2043.                Cfg->Save ();
  2044.             break;
  2045.          case 311:
  2046.             if ((RetVal = CMailProcessingDlg ()) == TRUE)
  2047.                Cfg->Save ();
  2048.             break;
  2049.          case 312:
  2050.             if ((RetVal = CAreafixDlg ()) == TRUE)
  2051.                Cfg->Save ();
  2052.             break;
  2053.          case 401:
  2054.             CMessageDlg ();
  2055.             break;
  2056.          case 402:
  2057.             CFileDlg ();
  2058.             break;
  2059.          case 403:
  2060.             if ((RetVal = CBBSGeneralDlg ()) == TRUE)
  2061.                Cfg->Save ();
  2062.             break;
  2063.          case 404:
  2064.             if ((RetVal = COfflineDlg ()) == TRUE)
  2065.                Cfg->Save ();
  2066.             break;
  2067.          case 405:
  2068.             if ((RetVal = CNewUsersDlg ()) == TRUE)
  2069.                Cfg->Save ();
  2070.             break;
  2071.          case 501:
  2072.             if ((RetVal = CHardwareDlg ()) == TRUE) {
  2073.                Cfg->Save ();
  2074.                if (Modem != NULL) {
  2075.                   delete Modem;
  2076.                   Modem = NULL;
  2077.                }
  2078.                if (Modem == NULL && Cfg != NULL) {
  2079.                   if ((Modem = new TModem) != NULL) {
  2080.                      Modem->Log = Log;
  2081.                      strcpy (Modem->Device, Cfg->Device);
  2082.                      Modem->Speed = Cfg->Speed;
  2083.                      Modem->LockSpeed = Cfg->LockSpeed;
  2084.                      if (Cfg->Ring[0] != '\0')
  2085.                         strcpy (Modem->Ring, Cfg->Ring);
  2086.                      Modem->Initialize ();
  2087.                      Status = INITIALIZE;
  2088.                      Current = 0;
  2089.                   }
  2090.                }
  2091.             }
  2092.             break;
  2093.          case 502:
  2094.             if ((RetVal = CCommandsDlg ()) == TRUE) {
  2095.                Cfg->Save ();
  2096.                if (Modem != NULL) {
  2097.                   delete Modem;
  2098.                   Modem = NULL;
  2099.                }
  2100.                if (Modem == NULL && Cfg != NULL) {
  2101.                   if ((Modem = new TModem) != NULL) {
  2102.                      Modem->Log = Log;
  2103.                      strcpy (Modem->Device, Cfg->Device);
  2104.                      Modem->Speed = Cfg->Speed;
  2105.                      Modem->LockSpeed = Cfg->LockSpeed;
  2106.                      if (Cfg->Ring[0] != '\0')
  2107.                         strcpy (Modem->Ring, Cfg->Ring);
  2108.                      Modem->Initialize ();
  2109.                      Status = INITIALIZE;
  2110.                      Current = 0;
  2111.                   }
  2112.                }
  2113.             }
  2114.             break;
  2115.          case 503:
  2116.             if ((RetVal = CAnswerDlg ()) == TRUE)
  2117.                Cfg->Save ();
  2118.             break;
  2119.          case 504:
  2120.             CNodeFlagsDlg ();
  2121.             break;
  2122.          case 506:
  2123.             Modem->Serial->SendBytes ((UCHAR *)"ATA\r", 4);
  2124.             Status = ANSWERING;
  2125.             TimeOut = TimerSet (4500L);
  2126.             break;
  2127.          case 601:
  2128.             CEventDlg ();
  2129.             Events->Load ();
  2130.             break;
  2131.          case 602:
  2132.             CNodelistDlg ();
  2133.             break;
  2134.          case 603:
  2135.             CCompressorDlg ();
  2136.             break;
  2137.          case 604:
  2138.             CNodesDlg ();
  2139.             break;
  2140.          case 605: {
  2141.             CHAR Temp[128], *p = NULL;
  2142.  
  2143.             Temp[0] = '\0';
  2144.             if (wopen (10, 15, 12, 65, 1, WHITE|_LGREY, WHITE|_LGREY) > 0) {
  2145.                wshadow (DGREY|_BLACK);
  2146.                wtitle (" Menu Editor ", TCENTER, WHITE|_LGREY);
  2147.  
  2148.                wprints (0, 1, WHITE|_GREEN, " Filename ");
  2149.                winpbeg (WHITE|_BLUE, WHITE|_BLUE);
  2150.                winpdef (0, 12, Temp, "????????????????????????????????????", 0, 2, NULL, 0);
  2151.                if (winpread () == W_ESCPRESS)
  2152.                   Temp[0] = '\0';
  2153.                else {
  2154.                   while (strlen (Temp) > 0 && Temp[strlen (Temp) - 1] == ' ')
  2155.                      Temp[strlen (Temp) - 1] = '\0';
  2156.                   p = Temp;
  2157.                }
  2158.                hidecur ();
  2159.                wclose ();
  2160.             }
  2161.  
  2162.             if (p != NULL && *p == '\0') {
  2163.                sprintf (Temp, "%s*.mnu", Cfg->MenuPath);
  2164.                p = wpickfile (6, 8, 18, 71, 1, WHITE|_LGREY, WHITE|_LGREY, WHITE|_GREEN, 1, Temp, AddShadow);
  2165.             }
  2166.  
  2167.             if (p != NULL)
  2168.                CMenuEditorDlg (p);
  2169.             break;
  2170.          }
  2171.          case 606:
  2172.             CUserDlg ();
  2173.             break;
  2174.          case 905:
  2175.             CProductDlg ();
  2176.             break;
  2177.       }
  2178.    }
  2179.  
  2180.    if (RetVal == FALSE)
  2181.       Cfg->Reload ();
  2182. }
  2183.  
  2184. void main (int argc, char *argv[])
  2185. {
  2186.    int i;
  2187.    USHORT Task = 1, Local, Poll, CanExit, EndRun, Interactive, Setup;
  2188.    USHORT DoImport, DoExport, DoPack, DoNews, DoTic, DoNodelist, DoMail;
  2189.    CHAR *Config, *Channel, *Device, Temp[128];
  2190.    ULONG Flags, Speed;
  2191.  
  2192.    Log = NULL;
  2193.    Modem = NULL;
  2194.    Events = NULL;
  2195.    Outbound = NULL;
  2196.    DoImport = DoExport = DoPack = DoNews = DoTic = DoNodelist = DoMail = FALSE;
  2197.    Setup = Interactive = FALSE;
  2198.    Config = Channel = Device = NULL;
  2199.    Speed = 0L;
  2200.    Local = Poll = FALSE;
  2201.    Daemon = FALSE;
  2202.  
  2203.    for (i = 1; i < argc; i++) {
  2204.       if (!stricmp (argv[i], "/LINE")) {
  2205.          i++;
  2206.          Task = (USHORT)atoi (argv[i]);
  2207.       }
  2208.       else if (!strncmp (argv[i], "-n", 2))
  2209.          Task = (USHORT)atoi (&argv[i][2]);
  2210.       else if (!stricmp (argv[i], "IMPORT") || !stricmp (argv[i], "IN") || !stricmp (argv[i], "TOSS")) {
  2211.          DoImport = TRUE;
  2212.          Interactive = TRUE;
  2213.       }
  2214.       else if (!stricmp (argv[i], "EXPORT") || !stricmp (argv[i], "OUT") || !stricmp (argv[i], "SCAN")) {
  2215.          DoExport = TRUE;
  2216.          Interactive = TRUE;
  2217.       }
  2218.       else if (!stricmp (argv[i], "PACK")) {
  2219.          DoPack = TRUE;
  2220.          Interactive = TRUE;
  2221.       }
  2222.       else if (!stricmp (argv[i], "NEWS")) {
  2223.          DoNews = TRUE;
  2224.          Interactive = TRUE;
  2225.       }
  2226.       else if (!stricmp (argv[i], "MAIL")) {
  2227.          DoMail = TRUE;
  2228.          Interactive = TRUE;
  2229.       }
  2230.       else if (!stricmp (argv[i], "POLL")) {
  2231.          i++;
  2232.          strcpy (PollNode, argv[i]);
  2233.          Poll = TRUE;
  2234.       }
  2235.       else if (!stricmp (argv[i], "TIC"))
  2236.          DoTic = TRUE;
  2237.       else if (!stricmp (argv[i], "NODELIST")) {
  2238.          DoNodelist = TRUE;
  2239.          Interactive = TRUE;
  2240.       }
  2241.       else if (!stricmp (argv[i], "SETUP")) {
  2242.          Interactive = FALSE;
  2243.          Setup = TRUE;
  2244.          Daemon = FALSE;
  2245.       }
  2246.       else if (!strncmp (argv[i], "-p", 2))
  2247.          Device = &argv[i][2];
  2248.       else if (!strncmp (argv[i], "-b", 2))
  2249.          Speed = atol (&argv[i][2]);
  2250.       else if (!strcmp (argv[i], "-l"))
  2251.          Local = TRUE;
  2252. #if defined(__LINUX__)
  2253.       else if (!strcmp (argv[i], "-daemon"))
  2254.          Daemon = TRUE;
  2255. #endif
  2256.       else if (Config == NULL)
  2257.          Config = argv[i];
  2258.       else if (Channel == NULL)
  2259.          Channel = argv[i];
  2260.    }
  2261.  
  2262.    if (Config == NULL)
  2263.       Config = getenv ("LORA_CONFIG");
  2264.    if (Channel == NULL)
  2265.       Channel = getenv ("LORA_CHANNEL");
  2266.  
  2267.    if ((Cfg = new TConfig) != NULL) {
  2268.       Cfg->TaskNumber = Task;
  2269.       if (Cfg->Load (Config, Channel) == FALSE)
  2270.          Cfg->Default ();
  2271.       if ((Events = new TEvents (Cfg->SchedulerFile)) != NULL)
  2272.          Events->Load ();
  2273.       if ((Outbound = new TOutbound (Cfg->Outbound)) != NULL) {
  2274.          if (Cfg->MailAddress.First () == TRUE)
  2275.             Outbound->DefaultZone = Cfg->MailAddress.Zone;
  2276.       }
  2277.    }
  2278.  
  2279. #if defined(__LINUX__)
  2280.    if (Local == TRUE)
  2281.       Daemon = TRUE;
  2282. #endif
  2283.  
  2284.    if (Device != NULL)
  2285.       strcpy (Cfg->Device, Device);
  2286.    if (Speed != 0L)
  2287.       Cfg->Speed = Speed;
  2288. #if defined(__LINUX__)
  2289.    if (Cfg->SystemPath[strlen (Cfg->SystemPath) - 1] == '/')
  2290.       Cfg->SystemPath[strlen (Cfg->SystemPath) - 1] = '\0';
  2291.    chdir (Cfg->SystemPath);
  2292.    strcat (Cfg->SystemPath, "/");
  2293. #endif
  2294.  
  2295.    DisplayScreen ();
  2296.  
  2297.    if ((Log = new TPMLog) != NULL) {
  2298.       if (Daemon == TRUE)
  2299.          Log->Display = FALSE;
  2300.       if (Cfg->LogFile[0] == '\0')
  2301.          sprintf (Temp, "lora%u.log", Cfg->TaskNumber);
  2302.       else
  2303.          sprintf (Temp, Cfg->LogFile, Cfg->TaskNumber);
  2304.       Log->Open (Temp);
  2305. #if defined(__LINUX__)
  2306.       Log->Write ("+Begin, v%s (Linux)", VERSION);
  2307. #elif defined(__DOS__)
  2308.       Log->Write ("+Begin, v%s (DOS)", VERSION);
  2309. #endif
  2310.       Log->Write ("+Message-base sharing is enabled");
  2311.    }
  2312.  
  2313.    if (Interactive == FALSE) {
  2314.       if (Poll == TRUE)
  2315.          CanExit = FALSE;
  2316.       if (Local == FALSE) {
  2317.          EventsT = TimerSet (50L);
  2318.  
  2319.          EndRun = FALSE;
  2320.          while (EndRun == FALSE) {
  2321.             if (Setup == FALSE) {
  2322.                ModemTimer ();
  2323.  
  2324.                if (Poll == TRUE && Status == WAITFORCALL) {
  2325.                   if (CanExit == TRUE)
  2326.                      EndRun = TRUE;
  2327.                   else {
  2328.                      Modem->Terminal = FALSE;
  2329.                      strcpy (Modem->NodelistPath, Cfg->NodelistPath);
  2330.                      strcpy (Modem->DialCmd, Cfg->Dial);
  2331.                      Modem->Poll (PollNode);
  2332.                      Status = WAITFORCONNECT;
  2333.                      TimeOut = TimerSet ((ULONG)Cfg->DialTimeout * 100L);
  2334.                      CanExit = TRUE;
  2335.                   }
  2336.                }
  2337.  
  2338.                if (Poll == FALSE && TimeUp (EventsT) && Status == WAITFORCALL)
  2339.                   EventsTimer (NULL);
  2340.             }
  2341.  
  2342.             if (Daemon == FALSE) {
  2343.                if (kbmhit ()) {
  2344.                   switch (getxch ()) {
  2345.                      case 0x1b:     // ESC - Pulldown menu
  2346.                      case 0x011b:
  2347.                      case CTRLA:
  2348.                         ProcessMenu ();
  2349.                         break;
  2350.                      case 'A':
  2351.                      case 0x1E00:   // Alt-A - Auto answer
  2352.                         Modem->Serial->SendBytes ((UCHAR *)"ATA\r", 4);
  2353.                         Status = ANSWERING;
  2354.                         TimeOut = TimerSet (4500L);
  2355.                         break;
  2356.                      case 'I':
  2357.                      case 0x1700:   // Alt-I - Import mail
  2358.                         MailProcessorThread ((PVOID)(MAIL_IMPORTKNOWN|MAIL_IMPORTPROTECTED|MAIL_IMPORTNORMAL));
  2359.                         break;
  2360.                      case 'K':
  2361.                      case 0x2500:   // Alt-K - Local login
  2362.                         LocalThread (NULL);
  2363.                         break;
  2364.                      case 'M':
  2365.                      case 0x3200:   // Alt-M - Manual Poll
  2366.                         CPollDlg ();
  2367.                         break;
  2368.                      case 'P':
  2369.                      case 0x1900:   // Alt-P - Process ECHOmail
  2370.                         MailProcessorThread ((PVOID)(MAIL_IMPORTKNOWN|MAIL_IMPORTPROTECTED|MAIL_IMPORTNORMAL|MAIL_EXPORT|MAIL_PACK|MAIL_STARTTIMER));
  2371.                         break;
  2372.                      case 'Q':
  2373.                      case 0x1000:   // Alt-Q - Rescan outbound
  2374.                         if (Outbound != NULL) {
  2375.                            if (Log != NULL)
  2376.                               Log->Write ("+Building the outbound queue");
  2377.                            Outbound->BuildQueue (Cfg->Outbound);
  2378.                            unlink ("rescan.now");
  2379.                            if (Log != NULL)
  2380.                               Log->Write ("+%u queue record(s) in database", Outbound->TotalNodes);
  2381.  
  2382.                            RefreshOutbound ();
  2383.                         }
  2384.                         break;
  2385.                      case 'R':
  2386.                      case 0x1300:   // Alt-R - Request files
  2387.                         CRequestDlg ();
  2388.                         break;
  2389.                      case 'S':
  2390.                      case 0x1F00:   // Alt-S - Send files
  2391.                         CAttachDlg ();
  2392.                         break;
  2393.                      case 'X':
  2394.                      case 0x2D00:   // Alt-X - Uscita
  2395.                         EndRun = TRUE;
  2396.                         break;
  2397.                   }
  2398.                }
  2399.             }
  2400.          }
  2401.       }
  2402.       else
  2403.          LocalThread (NULL);
  2404.    }
  2405.    else {
  2406.       if (DoNodelist == TRUE)
  2407.          CompileNodelist (TRUE);
  2408.  
  2409.       Flags = MAIL_POSTQUIT|MAIL_NOEXTERNAL;
  2410.       if (DoImport == TRUE)
  2411.          Flags |= MAIL_IMPORTNORMAL|MAIL_IMPORTPROTECTED|MAIL_IMPORTKNOWN;
  2412.       if (DoExport == TRUE)
  2413.          Flags |= MAIL_EXPORT;
  2414.       if (DoPack == TRUE)
  2415.          Flags |= MAIL_PACK;
  2416.       if (DoNews == TRUE)
  2417.          Flags |= MAIL_NEWSGROUP;
  2418.       if (DoMail == TRUE)
  2419.          Flags |= MAIL_EMAIL;
  2420.       if (DoTic == TRUE)
  2421.          Flags |= MAIL_TIC;
  2422.       if (Flags != (MAIL_POSTQUIT|MAIL_NOEXTERNAL))
  2423.          MailProcessorThread ((PVOID)Flags);
  2424.    }
  2425.  
  2426.    if (Modem != NULL)
  2427.       delete Modem;
  2428.    if (Log != NULL) {
  2429.       Log->Write (":End");
  2430.       Log->WriteBlank ();
  2431.       delete Log;
  2432.    }
  2433.    if (Cfg != NULL)
  2434.       delete Cfg;
  2435.    if (Events != NULL)
  2436.       delete Events;
  2437.    if (Outbound != NULL)
  2438.       delete Outbound;
  2439.  
  2440.    ClearScreen ();
  2441. }
  2442.