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

  1.  
  2. // LoraBBS Version 2.99 Free Edition
  3. // Copyright (C) 1987-98 Marco Maccaferri
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include "_ldefs.h"
  20. #include "ftrans.h"
  21.  
  22. #define CAN          ('X'&037)
  23.  
  24. #define ZFILE        4              /* File name from sender */
  25. #define ZEOF         11             /* End of file */
  26. #define ZCOMPL       15             /* Request is complete */
  27.  
  28. typedef struct {
  29.    ULONG ulSize;
  30.    ULONG ulTime;
  31.    CHAR  szName[17];
  32.    CHAR  szProgram[15];
  33.    CHAR  fNoAcks;
  34.    CHAR  cbFiller[87];
  35. } ZEROBLK;
  36.  
  37. TTransfer::TTransfer (void)
  38. {
  39.    Com = NULL;
  40.    Log = NULL;
  41.    EndRun = Hangup = FALSE;
  42.    Progress = NULL;
  43.    Device[0] = '\0';
  44.  
  45.    PktSize = 128;
  46.    Soh = 0x01;
  47.    DoCrc = FALSE;
  48.    UseAck = TRUE;
  49.    FinalName[0] = '\0';
  50.    PktNumber = 0;
  51.    Task = 1;
  52. }
  53.  
  54. TTransfer::~TTransfer (void)
  55. {
  56. }
  57.  
  58. PSZ TTransfer::Receive1kXModem (PSZ pszPath)
  59. {
  60.    UseAck = TRUE;
  61.    return (ReceiveXFile (pszPath));
  62. }
  63.  
  64. USHORT TTransfer::ReceivePacket (UCHAR *lpBuffer)
  65. {
  66.    SHORT c;
  67.    USHORT i, crc, recvcrc;
  68.    UCHAR checksum;
  69.  
  70.    checksum = 0;
  71.    crc = 0;
  72.  
  73.    if ((c = TimedRead (100)) == -1 || c != PktNumber)
  74.       return (FALSE);
  75.    if ((c = TimedRead (100)) == -1 || c != (UCHAR)(PktNumber ^ 0xFF))
  76.       return (FALSE);
  77.  
  78.    if (DoCrc == TRUE) {
  79.       for (i = 0; i < PktSize; i++, lpBuffer++) {
  80.          if ((c = TimedRead (100)) == -1)
  81.             return (FALSE);
  82.          *lpBuffer = (UCHAR)c;
  83.          crc = Crc16 (*lpBuffer, crc);
  84.       }
  85.       if ((c = TimedRead (100)) == -1)
  86.          return (FALSE);
  87.       recvcrc = (USHORT)(c << 8);
  88.       if ((c = TimedRead (100)) == -1)
  89.          return (FALSE);
  90.       recvcrc = (USHORT)(recvcrc | c);
  91.       if (recvcrc != crc)
  92.          return (FALSE);
  93.    }
  94.    else {
  95.       for (i = 0; i < PktSize; i++, lpBuffer++) {
  96.          if ((c = TimedRead (100)) == -1)
  97.             return (FALSE);
  98.          *lpBuffer = (UCHAR)c;
  99.          checksum += *lpBuffer;
  100.       }
  101.       if ((c = TimedRead (100)) == -1 || c != checksum)
  102.          return (FALSE);
  103.    }
  104.  
  105.    return (TRUE);
  106. }
  107.  
  108. PSZ TTransfer::ReceiveXFile (PSZ pszFile)
  109. {
  110.    int fd;
  111.    SHORT c, errs, fStop = FALSE, fStart = FALSE;
  112.    UCHAR *buffer;
  113.    PSZ pszReturn = NULL;
  114.  
  115.    if ((fd = sopen (pszFile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, SH_DENYNO, S_IREAD|S_IWRITE)) == -1)
  116.       return (NULL);
  117.  
  118.    if ((buffer = (UCHAR *)malloc (1024)) != NULL) {
  119.       errs = 0;
  120.       DoCrc = TRUE;
  121.       PktNumber = 1;
  122.  
  123.       while (AbortSession () == FALSE && fStop == FALSE) {
  124.          if ((c = TimedRead (1000)) != -1) {
  125.             switch (c) {
  126.                case SOH:
  127.                   PktSize = 128;
  128.                   if (ReceivePacket (buffer) == TRUE) {
  129.                      if (UseAck == TRUE)
  130.                         Com->BufferByte (ACK);
  131.                      write (fd, buffer, PktSize);
  132.                      errs = 0;
  133.                      fStart = TRUE;
  134.                      PktNumber++;
  135.                   }
  136.                   else {
  137.                      Com->BufferByte (NAK);
  138.                      if (++errs >= 10) {
  139.                         Com->BufferBytes ((UCHAR *)"\x18\x18\x18\x18\x18\x08\x08\x08\x08\x08", 10);
  140.                         fStop = TRUE;
  141.                      }
  142.                   }
  143.                   break;
  144.  
  145.                case STX:
  146.                   PktSize = 1024;
  147.                   if (ReceivePacket (buffer) == TRUE) {
  148.                      if (UseAck == TRUE)
  149.                         Com->BufferByte (ACK);
  150.                      write (fd, buffer, PktSize);
  151.                      errs = 0;
  152.                      fStart = TRUE;
  153.                      PktNumber++;
  154.                   }
  155.                   else {
  156.                      Com->BufferByte (NAK);
  157.                      if (++errs >= 10) {
  158.                         Com->BufferBytes ((UCHAR *)"\x18\x18\x18\x18\x18\x08\x08\x08\x08\x08", 10);
  159.                         fStop = TRUE;
  160.                      }
  161.                   }
  162.                   break;
  163.  
  164.                case EOT:
  165.                   if (UseAck == TRUE)
  166.                      Com->BufferByte (ACK);
  167.                   fStop = TRUE;
  168.                   pszReturn = pszFile;
  169.                   break;
  170.  
  171.                case CAN:
  172.                   if (TimedRead (100) == CAN) {
  173.                      Com->BufferBytes ((UCHAR *)"\x18\x18\x18\x18\x18\x08\x08\x08\x08\x08", 10);
  174.                      fStop = TRUE;
  175.                   }
  176.                   break;
  177.             }
  178.          }
  179.          else {
  180.             errs++;
  181.             if (fStart == FALSE && errs < 5)
  182.                Com->BufferByte ('C');
  183.             else {
  184.                if (errs >= 10) {
  185.                   Com->BufferBytes ((UCHAR *)"\x18\x18\x18\x18\x18\x08\x08\x08\x08\x08", 10);
  186.                   fStop = TRUE;
  187.                }
  188.                Com->BufferByte (NAK);
  189.                if (fStart == FALSE)
  190.                   DoCrc = FALSE;
  191.             }
  192.          }
  193.       }
  194.  
  195.       free (buffer);
  196.    }
  197.  
  198.    close (fd);
  199.  
  200.    return (pszReturn);
  201. }
  202.  
  203. PSZ TTransfer::ReceiveXModem (PSZ pszPath)
  204. {
  205.    UseAck = TRUE;
  206.    return (ReceiveXFile (pszPath));
  207. }
  208.  
  209. PSZ TTransfer::ReceiveZModem (PSZ pszPath)
  210. {
  211.    PSZ retVal = NULL;
  212.  
  213.    if (ZInitReceiver () == ZFILE) {
  214.       if (ZReceiveFile (pszPath) == ZEOF)
  215.          retVal = Pathname;
  216.    }
  217.  
  218.    return (retVal);
  219. }
  220.  
  221. USHORT TTransfer::Send1kXModem (PSZ pszFile)
  222. {
  223.    Soh = STX;
  224.    PktSize = 1024;
  225.    PktNumber = 1;
  226.    UseAck = TRUE;
  227.  
  228.    return (SendXFile (pszFile));
  229. }
  230.  
  231. USHORT TTransfer::SendASCIIDump (PSZ pszFile)
  232. {
  233.    FILE *fp;
  234.    int c;
  235.    USHORT fRet, nChars;
  236.  
  237.    fRet = FALSE;
  238.    nChars = 0;
  239.  
  240.    if ((fp = _fsopen (pszFile, "rb", SH_DENYNO)) != NULL) {
  241.       Com->BufferBytes ((UCHAR *)"\r\n", 2);
  242.  
  243.       while (AbortSession () == FALSE) {
  244.          if (nChars == 0) {
  245.             if ((c = fgetc (fp)) == EOF) {
  246.                fRet = TRUE;
  247.                break;
  248.             }
  249.             Com->BufferByte ((UCHAR)c);
  250.          }
  251.  
  252.          if (Com->BytesReady () == TRUE) {
  253.             if ((c = Com->ReadByte ()) == 8) {
  254.                Com->BufferBytes ((UCHAR *)"\x08 \x08", 3);
  255.                nChars--;
  256.             }
  257.             else if (c < 32)
  258.                break;
  259.             else {
  260.                Com->SendByte ((UCHAR)c);
  261.                nChars++;
  262.             }
  263.          }
  264.       }
  265.  
  266.       fclose (fp);
  267.       Com->UnbufferBytes ();
  268.    }
  269.  
  270.    return (fRet);
  271. }
  272.  
  273. SHORT TTransfer::SendPacket (UCHAR *lpBuffer)
  274. {
  275.    USHORT i, crc;
  276.    UCHAR checksum;
  277.  
  278.    checksum = 0;
  279.    crc = 0;
  280.  
  281.    Com->BufferByte (Soh);
  282.  
  283.    Com->BufferByte (PktNumber);
  284.    Com->BufferByte ((UCHAR)(PktNumber ^ 0xFF));
  285.  
  286.    if (DoCrc == TRUE) {
  287.       for (i = 0; i < PktSize; i++, lpBuffer++) {
  288.          crc = Crc16 (*lpBuffer, crc);
  289.          Com->BufferByte (*lpBuffer);
  290.       }
  291.       Com->BufferByte ((UCHAR)(crc >> 8));
  292.       Com->BufferByte ((UCHAR)(crc & 0xFF));
  293.    }
  294.    else {
  295.       for (i = 0; i < PktSize; i++, lpBuffer++) {
  296.          checksum += *lpBuffer;
  297.          Com->BufferByte (*lpBuffer);
  298.       }
  299.       Com->BufferByte (checksum);
  300.    }
  301.  
  302.    Com->UnbufferBytes ();
  303.  
  304.    return (AbortSession ());
  305. }
  306.  
  307. USHORT TTransfer::SendXFile (PSZ pszFile)
  308. {
  309.    int fd;
  310.    SHORT c, errs;
  311.    USHORT fRet, fStarted;
  312.    UCHAR *buffer;
  313.  
  314.    DoCrc = FALSE;
  315.    errs = 0;
  316.    fRet = FALSE;
  317.    fStarted = FALSE;
  318.  
  319.    if ((buffer = (UCHAR *)malloc (PktSize)) == NULL)
  320.       return (FALSE);
  321.  
  322.    if ((fd = sopen (pszFile, O_RDONLY|O_BINARY, SH_DENYNO, S_IREAD|S_IWRITE)) == -1) {
  323.       free (buffer);
  324.       return (FALSE);
  325.    }
  326.  
  327.    memset (buffer, 26, PktSize);
  328.    read (fd, buffer, PktSize);
  329.  
  330.    if (Progress != NULL) {
  331.       strcpy (Progress->TxFileName, pszFile);
  332.       Progress->TxBlockSize = PktSize;
  333.       Progress->TxSize = filelength (fd);
  334.       Progress->Begin ();
  335.    }
  336.  
  337.    while (AbortSession () == FALSE) {
  338.       if ((c = TimedRead (1000)) != -1) {
  339.          if (c == 'C' || c == NAK) {
  340.             if (c == 'C')
  341.                DoCrc = TRUE;
  342.             SendPacket (buffer);
  343.             errs++;
  344.             fStarted = TRUE;
  345.          }
  346.          if (c == ACK || UseAck == FALSE) {
  347.             PktNumber++;
  348.             if (Progress != NULL) {
  349.                Progress->TxPosition += Progress->TxBlockSize;
  350.                Progress->Update ();
  351.             }
  352.             errs = 0;
  353.             memset (buffer, 26, PktSize);
  354.             if (read (fd, buffer, PktSize) == 0) {
  355.                Com->SendByte ((UCHAR)EOT);
  356.                while (AbortSession () == FALSE) {
  357.                   if ((c = TimedRead (100)) != -1) {
  358.                      if (c == ACK) {
  359.                         fRet = TRUE;
  360.                         break;
  361.                      }
  362.                      else if (c == 'C' || c == NAK)
  363.                         Com->SendByte ((UCHAR)EOT);
  364.                   }
  365.                   else if (++errs > 10) {
  366.                      Com->SendByte ((UCHAR)EOT);
  367.                      Com->SendBytes ((UCHAR *)"\x18\x18\x18\x18\x18\x08\x08\x08\x08\x08", 10);
  368.                      break;
  369.                   }
  370.                }
  371.                break;
  372.             }
  373.             SendPacket (buffer);
  374.             fStarted = TRUE;
  375.          }
  376.          if (c == CAN) {
  377.             if (TimedRead (100) == CAN)
  378.                break;
  379.          }
  380.       }
  381.       else {
  382.          if (++errs > 10) {
  383.             Com->SendBytes ((UCHAR *)"\x18\x18\x18\x18\x18\x08\x08\x08\x08\x08", 10);
  384.             break;
  385.          }
  386.          else if (fStarted == TRUE)
  387.             SendPacket (buffer);
  388.       }
  389.    }
  390.  
  391.    if (Progress != NULL) {
  392.       Progress->End ();
  393.       delete Progress;
  394.    }
  395.  
  396.    free (buffer);
  397.    close (fd);
  398.  
  399.    return (fRet);
  400. }
  401.  
  402. USHORT TTransfer::SendXModem (PSZ pszFile)
  403. {
  404.    Soh = SOH;
  405.    PktSize = 128;
  406.    PktNumber = 1;
  407.    UseAck = TRUE;
  408.  
  409.    return (SendXFile (pszFile));
  410. }
  411.  
  412. USHORT TTransfer::SendYModem (PSZ pszFile)
  413. {
  414.    short c;
  415.    USHORT fZeroSent, fDone, fRet, errs;
  416.    CHAR ZeroBlock[128];
  417.    PSZ p;
  418.    struct stat statbuf;
  419.  
  420.    Soh = SOH;
  421.    PktSize = 128;
  422.    PktNumber = 0;
  423.    fZeroSent = FALSE;
  424.    fDone = FALSE;
  425.    fRet = FALSE;
  426.    errs = 0;
  427.  
  428.    p = strchr (pszFile, '\0');
  429.    while (p > pszFile && *p != ':' && *p != '\\' && *p != '/')
  430.       p--;
  431.    if (*p == ':' || *p == '\\' || *p == '/')
  432.       p++;
  433.    stat (pszFile, &statbuf);
  434.  
  435.    memset (ZeroBlock, 0, sizeof (ZeroBlock));
  436.    sprintf (ZeroBlock, "%s%c%ld %ld", p, '\0', statbuf.st_size, statbuf.st_mtime);
  437.  
  438.    while (fDone == FALSE && AbortSession () == FALSE) {
  439.       if ((c = TimedRead (1000)) != -1) {
  440.          if (c == 'C' || c == NAK) {
  441.             if (c == 'C')
  442.                DoCrc = TRUE;
  443.             SendPacket ((UCHAR *)ZeroBlock);
  444.             fZeroSent = TRUE;
  445.          }
  446.          if (c == ACK && fZeroSent == TRUE) {
  447.             Soh = STX;
  448.             PktSize = 1024;
  449.             PktNumber = 1;
  450.             UseAck = TRUE;
  451.             fRet = SendXFile (pszFile);
  452.             fDone = TRUE;
  453.          }
  454.       }
  455.       else if (++errs >= 10)
  456.          fDone = TRUE;
  457.    }
  458.  
  459.    return (fRet);
  460. }
  461.  
  462. USHORT TTransfer::SendYModemG (PSZ pszFile)
  463. {
  464.    short c;
  465.    USHORT fZeroSent, fDone, fRet, errs;
  466.    CHAR ZeroBlock[128];
  467.    PSZ p;
  468.    struct stat statbuf;
  469.  
  470.    Soh = SOH;
  471.    PktSize = 128;
  472.    PktNumber = 0;
  473.    fZeroSent = FALSE;
  474.    fDone = FALSE;
  475.    fRet = FALSE;
  476.    errs = 0;
  477.  
  478.    p = strchr (pszFile, '\0');
  479.    while (p > pszFile && *p != ':' && *p != '\\' && *p != '/')
  480.       p--;
  481.    if (*p == ':' || *p == '\\' || *p == '/')
  482.       p++;
  483.    stat (pszFile, &statbuf);
  484.  
  485.    memset (ZeroBlock, 0, sizeof (ZeroBlock));
  486.    sprintf (ZeroBlock, "%s%c%ld %ld", p, '\0', statbuf.st_size, statbuf.st_mtime);
  487.  
  488.    while (fDone == FALSE && AbortSession () == FALSE) {
  489.       if ((c = TimedRead (1000)) != -1) {
  490.          if (c == 'C' || c == NAK) {
  491.             if (fZeroSent == TRUE)
  492.                fDone = TRUE;
  493.             else {
  494.                if (c == 'C')
  495.                   DoCrc = TRUE;
  496.                SendPacket ((UCHAR *)ZeroBlock);
  497.                fZeroSent = TRUE;
  498.             }
  499.          }
  500.          if (c == ACK && fZeroSent == TRUE) {
  501.             Soh = STX;
  502.             PktSize = 1024;
  503.             PktNumber = 1;
  504.             UseAck = TRUE;
  505.             fRet = SendXFile (pszFile);
  506.             fDone = TRUE;
  507.          }
  508.       }
  509.       else if (++errs >= 10)
  510.          fDone = TRUE;
  511.    }
  512.  
  513.    return (fRet);
  514. }
  515.  
  516. USHORT TTransfer::SendZModem (PSZ pszFile, PSZ pszName)
  517. {
  518.    USHORT RetVal = FALSE, i;
  519.  
  520.    Maxblklen = 1024;
  521.    if (FileSent == 0 && pszFile == NULL)
  522.       ZInitSender (TRUE);
  523.    else
  524.       ZInitSender (FALSE);
  525.    if (pszFile != NULL) {
  526.       if ((i = ZSendFile (pszFile, pszName)) == OK || i == ZSKIP) {
  527.          RetVal = TRUE;
  528.          FileSent++;
  529.       }
  530.    }
  531.    else
  532.       ZEndSender ();
  533.  
  534.    return (RetVal);
  535. }
  536.  
  537. USHORT TTransfer::SendZModem8K (PSZ pszFile, PSZ pszName)
  538. {
  539.    USHORT RetVal = FALSE, i;
  540.  
  541.    Maxblklen = KSIZE;
  542.    if (FileSent == 0 && pszFile == NULL)
  543.       ZInitSender (TRUE);
  544.    else
  545.       ZInitSender (FALSE);
  546.    if (pszFile != NULL) {
  547.       if ((i = ZSendFile (pszFile, pszName)) == OK || i == ZSKIP) {
  548.          RetVal = TRUE;
  549.          FileSent++;
  550.       }
  551.    }
  552.    else
  553.       ZEndSender ();
  554.  
  555.    return (RetVal);
  556. }
  557.  
  558. VOID TTransfer::Janus (PSZ pszPath)
  559. {
  560. #if !defined(__LINUX__)
  561.    class TJanus *Jan;
  562.  
  563.    if ((Jan = new TJanus) != NULL) {
  564.       strcpy (Jan->RxPath, pszPath);
  565.       Jan->Com = Com;
  566.       Jan->Log = Log;
  567.       Jan->TxQueue = &TxQueue;
  568.       Jan->RxQueue = &RxQueue;
  569.       Jan->Transfer ();
  570.       delete Jan;
  571.    }
  572. #endif
  573. }
  574.  
  575. VOID TTransfer::RunExternalProtocol (USHORT Download, PSZ Cmd, class TProtocol *Protocol)
  576. {
  577.    FILE *fp;
  578.    USHORT i, Batch = FALSE, Found = FALSE;
  579.    CHAR Command[128], Temp[128], Control[128], *p;
  580.    ULONG Cps;
  581.  
  582.    if (TxQueue.TotalFiles > 1L)
  583.       Batch = TRUE;
  584.  
  585.    if (Protocol != NULL) {
  586.       if (Protocol->First () == TRUE)
  587.          do {
  588.             if (Protocol->Active == TRUE && (Batch == FALSE || Protocol->Batch == TRUE)) {
  589.                if (!stricmp (Protocol->Key, Cmd)) {
  590.                   Found = TRUE;
  591.                   break;
  592.                }
  593.             }
  594.          } while (Protocol->Next () == TRUE);
  595.    }
  596.    if (Found == TRUE) {
  597.       if (Protocol->LogFileName[0] != '\0') {
  598.          strcpy (Command, Protocol->LogFileName);
  599.          if (strstr (Command, "%k") != NULL) {
  600.             sprintf (Temp, "%u", Task);
  601.             strsrep (Command, "%k", Temp);
  602.          }
  603.          unlink (Command);
  604.       }
  605.       if (Protocol->CtlFileName[0] != '\0') {
  606.          strcpy (Control, Protocol->CtlFileName);
  607.          if (strstr (Control, "%k") != NULL) {
  608.             sprintf (Temp, "%u", Task);
  609.             strsrep (Control, "%k", Temp);
  610.          }
  611.  
  612.          if ((fp = fopen (Control, "wt")) != NULL) {
  613.             if (TxQueue.First () == TRUE)
  614.                do {
  615.                   strcpy (Command, Protocol->DownloadCtlString);
  616.                   if (strstr (Command, "%1") != NULL)
  617.                      strsrep (Command, "%1", TxQueue.Complete);
  618.                   fprintf (fp, "%s\n", Command);
  619.                } while (TxQueue.Next () == TRUE);
  620.             fclose (fp);
  621.          }
  622.       }
  623.       if (Download == TRUE) {
  624.          strcpy (Command, Protocol->DownloadCmd);
  625.          if (strstr (Command, "%k") != NULL) {
  626.             sprintf (Temp, "%u", Task);
  627.             strsrep (Command, "%k", Temp);
  628.          }
  629.          if (strstr (Command, "%P") != NULL) {
  630. #if defined(__LINUX__)
  631.             strsrep (Command, "%P", Device);
  632. #else
  633.             sprintf (Temp, "%u", atoi (&Device[3]));
  634.             strsrep (Command, "%P", Temp);
  635. #endif
  636.          }
  637.          if (strstr (Command, "%b") != NULL) {
  638.             sprintf (Temp, "%lu", Speed);
  639.             strsrep (Command, "%b", Temp);
  640.          }
  641.          if (strstr (Command, "%1") != NULL) {
  642.             if (TxQueue.First () == TRUE)
  643.                strsrep (Command, "%1", TxQueue.Complete);
  644.             else
  645.                strsrep (Command, "%1", "");
  646.          }
  647.          if (strstr (Command, "%2") != NULL)
  648.             strsrep (Command, "%2", Control);
  649.          if (Log != NULL)
  650.             Log->Write (":Running %s", Command);
  651.          RunExternal (Command, 0);
  652.          if (Log != NULL)
  653.             Log->Write (":Returned from external protocol");
  654.       }
  655.       if (Protocol->CtlFileName[0] != '\0')
  656.          unlink (Control);
  657.       if (Protocol->LogFileName[0] != '\0') {
  658.          strcpy (Command, Protocol->LogFileName);
  659.          if (strstr (Command, "%k") != NULL) {
  660.             sprintf (Temp, "%u", Task);
  661.             strsrep (Command, "%k", Temp);
  662.          }
  663.  
  664.          if ((fp = fopen (Command, "rt")) != NULL) {
  665.             while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  666.                if (Temp[strlen (Temp) - 1] == '\n')
  667.                   Temp[strlen (Temp) - 1] = '\0';
  668.                if ((p = strtok (Temp, " ")) != NULL) {
  669.                   if (!strcmp (p, Protocol->DownloadKeyword)) {
  670.                      i = 1;
  671.                      Found = FALSE;
  672.                      while ((p = strtok (NULL, " ")) != NULL) {
  673.                         i++;
  674.                         if (Protocol->FileNamePos == i) {
  675.                            if (TxQueue.First () == TRUE)
  676.                               do {
  677.                                  if (!stricmp (p, TxQueue.Complete) || !stricmp (p, TxQueue.Name)) {
  678.                                     Found = TRUE;
  679.                                     break;
  680.                                  }
  681.                               } while (TxQueue.Next () == TRUE);
  682.                         }
  683.                         if (Protocol->CpsPos == i)
  684.                            Cps = (ULONG)atoi (p);
  685.                      }
  686.                      if (Found == TRUE) {
  687.                         Log->Write ("+CPS: %lu (%lu bytes)  Efficiency: %d%%", Cps, TxQueue.Size, (Cps * 100L) / (Speed / 10));
  688.                         Log->Write ("+Sent-%s %s", Protocol->Key, strupr (TxQueue.Complete));
  689.                         TxQueue.Sent = TRUE;
  690.                         TxQueue.Update ();
  691.                      }
  692.                   }
  693.                }
  694.             }
  695.             fclose (fp);
  696.          }
  697.  
  698.          unlink (Command);
  699.       }
  700.    }
  701. }
  702.  
  703. // ----------------------------------------------------------------------
  704.  
  705. TProgress::TProgress (void)
  706. {
  707.    Type = 0;
  708.    RxBlockSize = TxBlockSize = 0;
  709.    RxFileName[0] = TxFileName[0] = '\0';
  710.    RxSize = RxPosition = 0L;
  711.    TxSize = TxPosition = 0L;
  712. }
  713.  
  714. TProgress::~TProgress (void)
  715. {
  716. }
  717.  
  718. VOID TProgress::Begin (VOID)
  719. {
  720. }
  721.  
  722. VOID TProgress::End (VOID)
  723. {
  724. }
  725.  
  726. VOID TProgress::Update (VOID)
  727. {
  728. }
  729.  
  730.  
  731.