home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / ASCIITransfer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  20.7 KB  |  1,183 lines

  1. /*
  2. **    ASCIITransfer.c
  3. **
  4. **    ASCII file transfer routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #ifndef _GLOBAL_H
  11. #include "Global.h"
  12. #endif
  13.  
  14.     /* Local variables. */
  15.  
  16. STATIC UBYTE    ASCIISendPrompt[256];
  17. STATIC LONG    ASCIISendPromptLen;
  18. STATIC BOOL    (* ASCIISendLine)(register STRPTR,register LONG);
  19.  
  20. STATIC LONG
  21. MangleASCIIBuffer(BYTE TranslateCR,BYTE TranslateLF,STRPTR Source,LONG SourceLen,STRPTR Destination)
  22. {
  23.     LONG    CR_Len,
  24.         LF_Len;
  25.     STRPTR    CR_String,
  26.         LF_String;
  27.     LONG    Mask;
  28.     LONG    Len = 0;
  29.  
  30.     switch(TranslateCR)
  31.     {
  32.         case EOL_IGNORE:
  33.  
  34.             CR_Len = 0;
  35.             break;
  36.  
  37.         case EOL_CR:
  38.  
  39.             CR_Len        = 1;
  40.             CR_String    = "\r";
  41.             break;
  42.  
  43.         case EOL_LF:
  44.  
  45.             CR_Len        = 1;
  46.             CR_String    = "\n";
  47.             break;
  48.  
  49.         case EOL_CRLF:
  50.  
  51.             CR_Len        = 2;
  52.             CR_String    = "\r\n";
  53.             break;
  54.  
  55.         case EOL_LFCR:
  56.  
  57.             CR_Len        = 2;
  58.             CR_String    = "\n\r";
  59.             break;
  60.     }
  61.  
  62.     switch(TranslateLF)
  63.     {
  64.         case EOL_IGNORE:
  65.  
  66.             LF_Len = 0;
  67.             break;
  68.  
  69.         case EOL_LF:
  70.  
  71.             LF_Len        = 1;
  72.             LF_String    = "\n";
  73.             break;
  74.  
  75.         case EOL_CR:
  76.  
  77.             LF_Len        = 1;
  78.             LF_String    = "\r";
  79.             break;
  80.  
  81.         case EOL_LFCR:
  82.  
  83.             LF_Len        = 2;
  84.             LF_String    = "\n\r";
  85.             break;
  86.  
  87.         case EOL_CRLF:
  88.  
  89.             LF_Len        = 2;
  90.             LF_String    = "\r\n";
  91.             break;
  92.     }
  93.  
  94.     if(Config -> TransferConfig -> StripBit8)
  95.         Mask = 0x7F;
  96.     else
  97.         Mask = 0xFF;
  98.  
  99.     do
  100.     {
  101.         switch(*Source)
  102.         {
  103.             case '\r':
  104.  
  105.                 if(CR_Len)
  106.                 {
  107.                     CopyMem(CR_String,Destination,CR_Len);
  108.  
  109.                     Destination    += CR_Len;
  110.                     Len        += CR_Len;
  111.                 }
  112.  
  113.                 break;
  114.  
  115.             case '\n':
  116.  
  117.                 if(LF_Len)
  118.                 {
  119.                     CopyMem(LF_String,Destination,LF_Len);
  120.  
  121.                     Destination    += LF_Len;
  122.                     Len        += LF_Len;
  123.                 }
  124.  
  125.                 break;
  126.  
  127.             default:
  128.  
  129.                 *Destination++ = (*Source) & Mask;
  130.  
  131.                 Len++;
  132.  
  133.                 break;
  134.         }
  135.  
  136.         Source++;
  137.     }
  138.     while(--SourceLen);
  139.  
  140.     return(Len);
  141. }
  142.  
  143.     /* WaitForPrompt(STRPTR Prompt,LONG PromptLen):
  144.      *
  145.      *    Scan the incoming data flow for a certain string.
  146.      */
  147.  
  148. STATIC BOOL
  149. WaitForPrompt(STRPTR Prompt,LONG PromptLen)
  150. {
  151.     ULONG Signals;
  152.  
  153.     MatchPrompt(NULL,0,NULL,0);
  154.  
  155.     if(DataHold)
  156.     {
  157.         DataHold = NULL;
  158.  
  159.         RestartSerial();
  160.     }
  161.  
  162.     if(CheckSerialRead())
  163.         Signals = SIG_SERIAL;
  164.     else
  165.         Signals = NULL;
  166.  
  167.     StartTime(Config -> TransferConfig -> SendTimeout / 100,(Config -> TransferConfig -> SendTimeout % 100) * 10000);
  168.  
  169.     for(;;)
  170.     {
  171.         if(Signals & SIG_SERIAL)
  172.         {
  173.             if(!WaitSerialRead())
  174.             {
  175.                 LONG Length;
  176.  
  177.                 BytesIn++;
  178.  
  179.                 ConProcess(ReadBuffer,1);
  180.  
  181.                 Status = STATUS_READY;
  182.  
  183.                 if(MatchPrompt(ReadBuffer,1,Prompt,PromptLen))
  184.                 {
  185.                     StopTime();
  186.  
  187.                     RestartSerial();
  188.  
  189.                     return(TRUE);
  190.                 }
  191.  
  192.                 do
  193.                 {
  194.                         /* Check how many bytes are still in
  195.                          * the serial buffer.
  196.                          */
  197.  
  198.                     if(Length = GetSerialWaiting())
  199.                     {
  200.                         if(Length > SerialBufferSize)
  201.                             Length = SerialBufferSize;
  202.  
  203.                         if(!DoSerialRead(ReadBuffer,Length))
  204.                         {
  205.                             BytesIn += Length;
  206.  
  207.                             ConProcess(ReadBuffer,Length);
  208.  
  209.                             Status = STATUS_READY;
  210.  
  211.                             if(MatchPrompt(ReadBuffer,Length,Prompt,PromptLen))
  212.                             {
  213.                                 StopTime();
  214.  
  215.                                 RestartSerial();
  216.  
  217.                                 return(TRUE);
  218.                             }
  219.                         }
  220.                     }
  221.                 }
  222.                 while(Length);
  223.             }
  224.  
  225.             RestartSerial();
  226.         }
  227.  
  228.         if(Signals & SIG_TIMER)
  229.         {
  230.             WaitTime();
  231.  
  232.             return(FALSE);
  233.         }
  234.  
  235.         Signals = Wait(SIG_SERIAL | SIG_TIMER);
  236.     }
  237. }
  238.  
  239.     /* ASCIISendLinePrompt(STRPTR Line,LONG Len):
  240.      *
  241.      *    Send text line, wait for prompt.
  242.      */
  243.  
  244. STATIC BOOL
  245. ASCIISendLinePrompt(STRPTR Line,LONG Len)
  246. {
  247.     LONG i;
  248.  
  249.     if(Len == -1)
  250.         Len = strlen(Line);
  251.  
  252.     while(Len)
  253.     {
  254.         i = 0;
  255.  
  256.         while(i < Len && Line[i] != '\r')
  257.             i++;
  258.  
  259.  
  260.         if(Line[i] == '\r')
  261.         {
  262.             i++;
  263.  
  264.             SerWrite(Line,i);
  265.  
  266.             if(!WaitForPrompt(ASCIISendPrompt,ASCIISendPromptLen))
  267.                 return(FALSE);
  268.         }
  269.         else
  270.         {
  271.             if(i)
  272.                 SerWrite(Line,i);
  273.         }
  274.  
  275.         Len    -= i;
  276.         Line    += i;
  277.     }
  278.  
  279.     return(TRUE);
  280. }
  281.  
  282.     /* ASCIISendLineDelay(STRPTR Line,LONG Len):
  283.      *
  284.      *    Send a text line, include a delay where necessary.
  285.      */
  286.  
  287. STATIC BOOL
  288. ASCIISendLineDelay(STRPTR Line,LONG Len)
  289. {
  290.     if(Len == -1)
  291.         Len = strlen(Line);
  292.  
  293.     while(Len--)
  294.     {
  295.         SerWrite(Line,1);
  296.  
  297.         if(*Line == '\r')
  298.             DelayTime(Config -> TransferConfig -> LineDelay / 100,(Config -> TransferConfig -> LineDelay % 100) * 10000);
  299.         else
  300.             DelayTime(Config -> TransferConfig -> CharDelay / 100,(Config -> TransferConfig -> CharDelay % 100) * 10000);
  301.  
  302.         Line++;
  303.     }
  304.  
  305.     return(TRUE);
  306. }
  307.  
  308.     /* ASCIISendLineEcho(STRPTR Line,LONG Len):
  309.      *
  310.      *    Send a text line, wait for single characters to be echoed.
  311.      */
  312.  
  313. STATIC BOOL
  314. ASCIISendLineEcho(STRPTR Line,LONG Len)
  315. {
  316.     ULONG Signals;
  317.  
  318.     if(DataHold)
  319.     {
  320.         DataHold = NULL;
  321.  
  322.         RestartSerial();
  323.     }
  324.  
  325.     if(Len == -1)
  326.         Len = strlen(Line);
  327.  
  328.     while(Len--)
  329.     {
  330.         SerWrite(Line,1);
  331.  
  332.         StartTime(Config -> TransferConfig -> SendTimeout / 100,(Config -> TransferConfig -> SendTimeout % 100) * 10000);
  333.  
  334.         FOREVER
  335.         {
  336.             Signals = Wait(SIG_TIMER | SIG_SERIAL);
  337.  
  338.             if(Signals & SIG_SERIAL)
  339.             {
  340.                 if(!WaitSerialRead())
  341.                 {
  342.                     if(*(UBYTE *)ReadBuffer == *Line)
  343.                     {
  344.                         StopTime();
  345.  
  346.                         RestartSerial();
  347.  
  348.                         break;
  349.                     }
  350.  
  351.                     RestartSerial();
  352.                 }
  353.                 else
  354.                 {
  355.                     StopTime();
  356.  
  357.                     RestartSerial();
  358.  
  359.                     return(FALSE);
  360.                 }
  361.             }
  362.  
  363.             if(Signals & SIG_TIMER)
  364.             {
  365.                 WaitTime();
  366.  
  367.                 return(FALSE);
  368.             }
  369.         }
  370.  
  371.         Line++;
  372.     }
  373.  
  374.     return(TRUE);
  375. }
  376.  
  377.     /* ASCIISendLineAnyEcho(STRPTR Line,LONG Len):
  378.      *
  379.      *    Send a text line, wait for characters to be echoed.
  380.      */
  381.  
  382. STATIC BOOL
  383. ASCIISendLineAnyEcho(STRPTR Line,LONG Len)
  384. {
  385.     ULONG Signals;
  386.  
  387.     if(DataHold)
  388.     {
  389.         DataHold = NULL;
  390.  
  391.         RestartSerial();
  392.     }
  393.  
  394.     if(Len == -1)
  395.         Len = strlen(Line);
  396.  
  397.     while(Len--)
  398.     {
  399.         SerWrite(Line,1);
  400.  
  401.         StartTime(Config -> TransferConfig -> SendTimeout / 100,(Config -> TransferConfig -> SendTimeout % 100) * 10000);
  402.  
  403.         FOREVER
  404.         {
  405.             Signals = Wait(SIG_TIMER | SIG_SERIAL);
  406.  
  407.             if(Signals & SIG_SERIAL)
  408.             {
  409.                 if(!WaitSerialRead())
  410.                 {
  411.                     StopTime();
  412.  
  413.                     RestartSerial();
  414.  
  415.                     break;
  416.                 }
  417.                 else
  418.                 {
  419.                     StopTime();
  420.  
  421.                     RestartSerial();
  422.  
  423.                     return(FALSE);
  424.                 }
  425.             }
  426.  
  427.             if(Signals & SIG_TIMER)
  428.             {
  429.                 WaitTime();
  430.  
  431.                 return(FALSE);
  432.             }
  433.         }
  434.  
  435.         Line++;
  436.     }
  437.  
  438.     return(TRUE);
  439. }
  440.  
  441.     /* ASCIISendSetup():
  442.      *
  443.      *    Choose the right routine for the text line output job.
  444.      */
  445.  
  446. VOID
  447. ASCIISendSetup()
  448. {
  449.         /* Pick the line send routine. */
  450.  
  451.     switch(Config -> TransferConfig -> PacingMode)
  452.     {
  453.         case PACE_DIRECT:
  454.  
  455.             ASCIISendLine = SendLineSimple;
  456.             break;
  457.  
  458.         case PACE_ECHO:
  459.  
  460.             if(Config -> TransferConfig -> SendTimeout)
  461.                 ASCIISendLine = ASCIISendLineEcho;
  462.             else
  463.                 ASCIISendLine = SendLineSimple;
  464.  
  465.             break;
  466.  
  467.         case PACE_ANYECHO:
  468.  
  469.             if(Config -> TransferConfig -> SendTimeout)
  470.                 ASCIISendLine = ASCIISendLineAnyEcho;
  471.             else
  472.                 ASCIISendLine = SendLineSimple;
  473.  
  474.             break;
  475.  
  476.         case PACE_PROMPT:
  477.  
  478.             if(Config -> TransferConfig -> SendTimeout)
  479.             {
  480.                     /* Prepare the prompt string. */
  481.  
  482.                 if(Config -> TransferConfig -> LinePrompt[0])
  483.                     ASCIISendPromptLen = TranslateString(Config -> TransferConfig -> LinePrompt,ASCIISendPrompt);
  484.                 else
  485.                 {
  486.                     ASCIISendPrompt[0] = 0;
  487.                     ASCIISendPromptLen = 0;
  488.                 }
  489.  
  490.                 ASCIISendLine = ASCIISendLinePrompt;
  491.             }
  492.             else
  493.                 ASCIISendLine = SendLineSimple;
  494.  
  495.             break;
  496.  
  497.         case PACE_DELAY:
  498.  
  499.             if(Config -> TransferConfig -> LineDelay || Config -> TransferConfig -> CharDelay)
  500.                 ASCIISendLine = ASCIISendLineDelay;
  501.             else
  502.                 ASCIISendLine = SendLineSimple;
  503.  
  504.             break;
  505.  
  506.         case PACE_KEYBOARD:
  507.  
  508.             ASCIISendLine = SendLineKeyDelay;
  509.             break;
  510.     }
  511. }
  512.  
  513. BOOL
  514. InternalASCIIUpload(STRPTR SingleFile,BOOL WaitForIt)
  515. {
  516.     BYTE    OldStatus = Status;
  517.     BOOL    DidSend = FALSE;
  518.     BPTR    NewDir,OldDir;
  519.  
  520.         /* We are uploading data. */
  521.  
  522.     Uploading = TRUE;
  523.  
  524.     if(NewDir = Lock(Config -> PathConfig -> ASCIIUploadPath,ACCESS_READ))
  525.         OldDir = CurrentDir(NewDir);
  526.     else
  527.         OldDir = NULL;
  528.  
  529.     BlockWindows();
  530.  
  531.     if(!FileTransferInfo)
  532.     {
  533.         if(SingleFile)
  534.         {
  535.             ULONG Size;
  536.  
  537.             if(Size = GetFileSize(SingleFile))
  538.             {
  539.                 if(FileTransferInfo = AllocFileTransferInfo())
  540.                 {
  541.                     if(!AddFileTransferNode(FileTransferInfo,SingleFile,Size))
  542.                     {
  543.                         FreeFileTransferInfo(FileTransferInfo);
  544.  
  545.                         FileTransferInfo = NULL;
  546.                     }
  547.                 }
  548.             }
  549.         }
  550.         else
  551.         {
  552.             struct FileRequester    *FileRequest;
  553.             UBYTE             DummyBuffer[MAX_FILENAME_LENGTH];
  554.  
  555.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + TRANSFER_ASCII),Config -> PathConfig -> ASCIIUploadPath,"",DummyBuffer,"",FALSE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),TRUE))
  556.             {
  557.                 strcpy(Config -> PathConfig -> ASCIIUploadPath,FileRequest -> fr_Drawer);
  558.  
  559.                 ConfigChanged = TRUE;
  560.  
  561.                 FileTransferInfo = BuildFileTransferInfo(FileRequest);
  562.  
  563.                 FreeAslRequest(FileRequest);
  564.             }
  565.         }
  566.     }
  567.     else
  568.     {
  569.         if(SingleFile)
  570.         {
  571.             ULONG Size;
  572.  
  573.             if(Size = GetFileSize(SingleFile))
  574.             {
  575.                 if(!AddFileTransferNode(FileTransferInfo,SingleFile,Size))
  576.                 {
  577.                     FreeFileTransferInfo(FileTransferInfo);
  578.  
  579.                     FileTransferInfo = NULL;
  580.                 }
  581.             }
  582.         }
  583.     }
  584.  
  585.     TransferAborted = FALSE;
  586.  
  587.     TransferFailed = TRUE;
  588.  
  589.     TransferError = FALSE;
  590.  
  591.     if(FileTransferInfo)
  592.     {
  593.         struct Window *ThisWindow;
  594.  
  595.         if(ThisWindow = CreateASCIIWindow(TRUE))
  596.         {
  597.             struct Buffer    *File;
  598.             LONG         Chars = 0,Lines = 0,Len,i;
  599.             BOOL         Terminated = FALSE;
  600.  
  601.             FileTransferInfo -> DoneSize    = 0;
  602.             FileTransferInfo -> DoneFiles    = 0;
  603.  
  604.             FileTransferInfo -> CurrentFile    = (struct FileTransferNode *)FileTransferInfo -> FileList . mlh_Head;
  605.             FileTransferInfo -> CurrentSize    = FileTransferInfo -> CurrentFile -> Size;
  606.  
  607.             Status = STATUS_UPLOAD;
  608.  
  609.             ASCIISendSetup();
  610.  
  611.             if(DataHold)
  612.             {
  613.                 if(!Config -> TransferConfig -> QuietTransfer)
  614.                 {
  615.                     ConProcess(DataHold,DataSize);
  616.  
  617.                     Status = STATUS_UPLOAD;
  618.                 }
  619.  
  620.                 DataHold = NULL;
  621.  
  622.                 RestartSerial();
  623.             }
  624.  
  625.             while(!Terminated && FileTransferInfo -> CurrentFile -> Node . mln_Succ)
  626.             {
  627.                 if(File = BufferOpen(FileTransferInfo -> CurrentFile -> Name,"r"))
  628.                 {
  629.                     UBYTE    DummyBuffer[512],
  630.                         OtherBuffer[256];
  631.                     ULONG    Signals;
  632.                     BOOL    LastCR = FALSE,Skipped = FALSE;
  633.  
  634.                     AddASCIIMessage(ThisWindow,LocaleString(MSG_ASCIIPANEL_OPENING_FILE_TXT),FileTransferInfo -> CurrentFile -> Name);
  635.  
  636.                     while(!Skipped && !Terminated && (Len = BufferRead(File,OtherBuffer,256)) > 0)
  637.                     {
  638.                         if(Len = MangleASCIIBuffer(Config -> TransferConfig -> SendCR,Config -> TransferConfig -> SendLF,OtherBuffer,Len,DummyBuffer))
  639.                         {
  640.                             for(i = 0 ; i < Len ; i++)
  641.                             {
  642.                                 if(DummyBuffer[i] == '\r')
  643.                                 {
  644.                                     Lines++;
  645.  
  646.                                     LastCR = TRUE;
  647.                                 }
  648.                                 else
  649.                                 {
  650.                                     if(DummyBuffer[i] == '\n' && !LastCR)
  651.                                         Lines++;
  652.  
  653.                                     LastCR = FALSE;
  654.                                 }
  655.                             }
  656.  
  657.                             Chars += Len;
  658.  
  659.                             DidSend = TRUE;
  660.  
  661.                             TransferFailed = FALSE;
  662.  
  663.                             (*ASCIISendLine)(DummyBuffer,Len);
  664.                         }
  665.  
  666.                         Signals = CheckSignal(SIG_BREAK | SIG_SERIAL | PORTMASK(ThisWindow -> UserPort));
  667.  
  668.                         if(Signals & SIG_BREAK)
  669.                             Terminated = TransferAborted = TRUE;
  670.  
  671.                         if(Signals & PORTMASK(ThisWindow -> UserPort))
  672.                         {
  673.                             switch(HandleASCIIWindow())
  674.                             {
  675.                                 case 1:    Terminated = TransferAborted = TRUE;
  676.                                     break;
  677.  
  678.                                 case 2:    Skipped = TRUE;
  679.                                     break;
  680.                             }
  681.  
  682.                             if(Terminated || Skipped)
  683.                                 break;
  684.                         }
  685.  
  686.                         if(Signals & SIG_SERIAL)
  687.                         {
  688.                             if(!WaitSerialRead())
  689.                             {
  690.                                 LONG Length;
  691.  
  692.                                 if(!Config -> TransferConfig -> QuietTransfer)
  693.                                 {
  694.                                     BytesIn++;
  695.  
  696.                                     ConProcess(ReadBuffer,1);
  697.  
  698.                                     Status = STATUS_UPLOAD;
  699.                                 }
  700.  
  701.                                     /* Check how many bytes are still in
  702.                                      * the serial buffer.
  703.                                      */
  704.  
  705.                                 if(Length = GetSerialWaiting())
  706.                                 {
  707.                                     if(Length > SerialBufferSize)
  708.                                         Length = SerialBufferSize;
  709.  
  710.                                     if(Length > Config -> SerialConfig -> Quantum)
  711.                                         Length = Config -> SerialConfig -> Quantum;
  712.  
  713.                                     if(!DoSerialRead(ReadBuffer,Length))
  714.                                     {
  715.                                         if(!Config -> TransferConfig -> QuietTransfer)
  716.                                         {
  717.                                             BytesIn += Length;
  718.  
  719.                                                 /* Send the data to the console. */
  720.  
  721.                                             ConProcess(ReadBuffer,Length);
  722.  
  723.                                             Status = STATUS_UPLOAD;
  724.                                         }
  725.                                     }
  726.                                 }
  727.                             }
  728.  
  729.                             RestartSerial();
  730.                         }
  731.  
  732.                         UpdateASCIIWindow(ThisWindow,Chars,FileTransferInfo -> CurrentFile -> Size,Lines);
  733.                     }
  734.  
  735.                     if(Len < 0)
  736.                     {
  737.                         AddASCIIMessage(ThisWindow,LocaleString(MSG_ASCIIPANEL_ERROR_READING_FILE_TXT),FileTransferInfo -> CurrentFile -> Name);
  738.  
  739.                         TransferFailed = TRUE;
  740.  
  741.                         break;
  742.                     }
  743.  
  744.                     BufferClose(File);
  745.  
  746.                     RemoveUploadListItem(FileTransferInfo -> CurrentFile -> Name);
  747.                 }
  748.                 else
  749.                 {
  750.                     AddASCIIMessage(ThisWindow,LocaleString(MSG_ASCIIPANEL_ERROR_OPENING_FILE_TXT),FileTransferInfo -> CurrentFile -> Name);
  751.  
  752.                     TransferFailed = TRUE;
  753.  
  754.                     break;
  755.                 }
  756.  
  757.                 FileTransferInfo -> DoneSize    += FileTransferInfo -> CurrentSize;
  758.                 FileTransferInfo -> DoneFiles    += 1;
  759.  
  760.                 FileTransferInfo -> CurrentFile  = (struct FileTransferNode *)FileTransferInfo -> CurrentFile -> Node . mln_Succ;
  761.                 FileTransferInfo -> CurrentSize  = FileTransferInfo -> CurrentFile -> Size;
  762.             }
  763.  
  764.             if(TransferFailed || TransferError)
  765.                 WakeUp(ThisWindow,SOUND_BADTRANSFER);
  766.             else
  767.             {
  768.                 WakeUp(ThisWindow,SOUND_GOODTRANSFER);
  769.  
  770.                 DelayTime(2,0);
  771.             }
  772.  
  773.             DeleteASCIIWindow(ThisWindow,TransferFailed && WaitForIt);
  774.         }
  775.  
  776.         FreeFileTransferInfo(FileTransferInfo);
  777.  
  778.         FileTransferInfo = NULL;
  779.     }
  780.  
  781.     if(TransferFailed || TransferAborted)
  782.         Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  783.     else
  784.         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  785.  
  786.     if(OldDir)
  787.         CurrentDir(OldDir);
  788.  
  789.     if(NewDir)
  790.         UnLock(NewDir);
  791.  
  792.     SendAbort = FALSE;
  793.  
  794.     Status = OldStatus;
  795.  
  796.     ReleaseWindows();
  797.  
  798.     DidTransfer = FALSE;
  799.  
  800.     if(WaitForIt)
  801.     {
  802.         if(Config -> CommandConfig -> DownloadMacro[0])
  803.             SerialCommand(Config -> CommandConfig -> UploadMacro);
  804.     }
  805.  
  806.     DidTransfer = FALSE;
  807.  
  808.     return(DidSend);
  809. }
  810.  
  811. BOOL
  812. InternalASCIIDownload(STRPTR Name,BOOL WaitForIt)
  813. {
  814.     struct FileRequester    *FileRequest;
  815.     UBYTE             DummyBuffer[MAX_FILENAME_LENGTH];
  816.     BYTE             OldStatus = Status;
  817.     BOOL             DidSend = FALSE;
  818.     BPTR             NewDir,OldDir;
  819.  
  820.     ClearGenericList(GenericListTable[GLIST_DOWNLOAD]);
  821.  
  822.     DownloadPath = Config -> PathConfig -> ASCIIDownloadPath;
  823.  
  824.     if(DownloadPath[0])
  825.     {
  826.         if(NewDir = Lock(DownloadPath,ACCESS_READ))
  827.             OldDir = CurrentDir(NewDir);
  828.         else
  829.             OldDir = NULL;
  830.     }
  831.     else
  832.         NewDir = OldDir = NULL;
  833.  
  834.     BlockWindows();
  835.  
  836.     if(!Name)
  837.     {
  838.         if(FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + TRANSFER_ASCII),DownloadPath,"",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE))
  839.         {
  840.                 /* Save the download path. */
  841.  
  842.             strcpy(DownloadPath,FileRequest -> fr_Drawer);
  843.  
  844.             ConfigChanged = TRUE;
  845.  
  846.             FreeAslRequest(FileRequest);
  847.  
  848.             Name = DummyBuffer;
  849.         }
  850.     }
  851.     else
  852.     {
  853.         STRPTR Index;
  854.  
  855.         strcpy(DownloadPath,Name);
  856.  
  857.         ConfigChanged = TRUE;
  858.  
  859.         Index = PathPart(DownloadPath);
  860.  
  861.         *Index = 0;
  862.     }
  863.  
  864.     TransferAborted = FALSE;
  865.  
  866.     TransferFailed = TRUE;
  867.  
  868.     TransferError = FALSE;
  869.  
  870.     if(Name)
  871.     {
  872.         struct Window *ThisWindow;
  873.  
  874.         if(ThisWindow = CreateASCIIWindow(FALSE))
  875.         {
  876.             struct Buffer *File;
  877.  
  878.             if(File = BufferOpen(Name,"w"))
  879.             {
  880.                 UBYTE    OtherBuffer[512];
  881.                 LONG    Chars = 0,Lines = 0,i;
  882.                 BOOL    Terminated = FALSE;
  883.                 ULONG    Signals;
  884.  
  885.                 AddASCIIMessage(ThisWindow,LocaleString(MSG_ASCIIPANEL_OPENING_FILE_TXT),Name);
  886.  
  887.                 TransferFailed = FALSE;
  888.  
  889.                 Status = STATUS_DOWNLOAD;
  890.  
  891.                 if(DataHold)
  892.                 {
  893.                     LONG Size,Len;
  894.  
  895.                     do
  896.                     {
  897.                         if(DataSize > 256)
  898.                             Size = 256;
  899.                         else
  900.                             Size = DataSize;
  901.  
  902.                         if(Len = MangleASCIIBuffer(Config -> TransferConfig -> ReceiveCR,Config -> TransferConfig -> ReceiveLF,DataHold,Size,OtherBuffer))
  903.                         {
  904.                             if(Config -> TransferConfig -> IgnoreDataPastArnold)
  905.                             {
  906.                                 for(i = 0 ; i < Len ; i++)
  907.                                 {
  908.                                     if(OtherBuffer[i] == '\r')
  909.                                         Lines++;
  910.  
  911.                                     if(OtherBuffer[i] == Config -> TransferConfig -> TerminatorChar)
  912.                                     {
  913.                                         Len = i;
  914.  
  915.                                         Terminated = TRUE;
  916.  
  917.                                         break;
  918.                                     }
  919.                                 }
  920.                             }
  921.                             else
  922.                             {
  923.                                 for(i = 0 ; i < Len ; i++)
  924.                                 {
  925.                                     if(OtherBuffer[i] == '\r')
  926.                                         Lines++;
  927.                                 }
  928.                             }
  929.  
  930.                             if(Len)
  931.                             {
  932.                                 Chars += Len;
  933.  
  934.                                 if(BufferWrite(File,OtherBuffer,Len) != Len)
  935.                                 {
  936.                                     TransferFailed = Terminated = TRUE;
  937.  
  938.                                     AddASCIIMessage(ThisWindow,LocaleString(MSG_ASCIIPANEL_ERROR_WRITING_FILE_TXT),Name);
  939.                                 }
  940.                             }
  941.                         }
  942.  
  943.                         if(!Config -> TransferConfig -> QuietTransfer)
  944.                         {
  945.                             ConProcess(DataHold,Size);
  946.  
  947.                             Status = STATUS_DOWNLOAD;
  948.                         }
  949.  
  950.                         DataSize -= Size;
  951.  
  952.                         if(DataSize > 0)
  953.                             DataHold += Size;
  954.                         else
  955.                             DataHold = NULL;
  956.                     }
  957.                     while(DataHold && !Terminated);
  958.  
  959.                     RestartSerial();
  960.  
  961.                     UpdateASCIIWindow(ThisWindow,Chars,0,Lines);
  962.                 }
  963.  
  964.                 if(!Terminated)
  965.                 {
  966.                     StartTime(5,0);
  967.  
  968.                     do
  969.                     {
  970.                         Signals = Wait(SIG_BREAK | SIG_SERIAL | SIG_TIMER | PORTMASK(ThisWindow -> UserPort));
  971.  
  972.                         if(Signals & PORTMASK(ThisWindow -> UserPort))
  973.                         {
  974.                             if(HandleASCIIWindow())
  975.                                 break;
  976.                         }
  977.  
  978.                         if(Signals & SIG_SERIAL)
  979.                         {
  980.                             StopTime();
  981.  
  982.                             if(!WaitSerialRead())
  983.                             {
  984.                                 LONG Length;
  985.  
  986.                                 BytesIn++;
  987.  
  988.                                 if(!Config -> TransferConfig -> QuietTransfer)
  989.                                 {
  990.                                     ConProcess(ReadBuffer,1);
  991.  
  992.                                     Status = STATUS_DOWNLOAD;
  993.                                 }
  994.  
  995.                                 if(Length = MangleASCIIBuffer(Config -> TransferConfig -> ReceiveCR,Config -> TransferConfig -> ReceiveLF,ReadBuffer,1,OtherBuffer))
  996.                                 {
  997.                                     if(Config -> TransferConfig -> IgnoreDataPastArnold)
  998.                                     {
  999.                                         for(i = 0 ; i < Length ; i++)
  1000.                                         {
  1001.                                             if(OtherBuffer[i] == Config -> TransferConfig -> TerminatorChar)
  1002.                                             {
  1003.                                                 Length = i;
  1004.  
  1005.                                                 Terminated = TRUE;
  1006.  
  1007.                                                 break;
  1008.                                             }
  1009.                                         }
  1010.  
  1011.                                         if(Terminated)
  1012.                                         {
  1013.                                             RestartSerial();
  1014.  
  1015.                                             break;
  1016.                                         }
  1017.                                     }
  1018.  
  1019.                                     if(Length)
  1020.                                     {
  1021.                                         if(BufferWrite(File,OtherBuffer,Length) != Length)
  1022.                                         {
  1023.                                             TransferFailed = Terminated = TRUE;
  1024.  
  1025.                                             AddASCIIMessage(ThisWindow,LocaleString(MSG_ASCIIPANEL_ERROR_WRITING_FILE_TXT),Name);
  1026.                                         }
  1027.  
  1028.                                         for(i = 0 ; i < Length ; i++)
  1029.                                         {
  1030.                                             if(OtherBuffer[i] == '\r')
  1031.                                                 Lines++;
  1032.                                         }
  1033.  
  1034.                                         Chars += Length;
  1035.                                     }
  1036.                                 }
  1037.  
  1038.                                     /* Check how many bytes are still in
  1039.                                      * the serial buffer.
  1040.                                      */
  1041.  
  1042.                                 if(Length = GetSerialWaiting())
  1043.                                 {
  1044.                                     if(Length > SerialBufferSize)
  1045.                                         Length = SerialBufferSize;
  1046.  
  1047.                                     if(Length > Config -> SerialConfig -> Quantum)
  1048.                                         Length = Config -> SerialConfig -> Quantum;
  1049.  
  1050.                                     if(Length > 256)
  1051.                                         Length = 256;
  1052.  
  1053.                                     if(!DoSerialRead(ReadBuffer,Length))
  1054.                                     {
  1055.                                         BytesIn += Length;
  1056.  
  1057.                                             /* Send the data to the console. */
  1058.  
  1059.                                         if(!Config -> TransferConfig -> QuietTransfer)
  1060.                                         {
  1061.                                             ConProcess(ReadBuffer,Length);
  1062.  
  1063.                                             Status = STATUS_DOWNLOAD;
  1064.                                         }
  1065.  
  1066.                                         if(Length = MangleASCIIBuffer(Config -> TransferConfig -> ReceiveCR,Config -> TransferConfig -> ReceiveLF,ReadBuffer,Length,OtherBuffer))
  1067.                                         {
  1068.                                             if(Config -> TransferConfig -> IgnoreDataPastArnold)
  1069.                                             {
  1070.                                                 for(i = 0 ; i < Length ; i++)
  1071.                                                 {
  1072.                                                     if(OtherBuffer[i] == '\r')
  1073.                                                         Lines++;
  1074.  
  1075.                                                     if(OtherBuffer[i] == Config -> TransferConfig -> TerminatorChar)
  1076.                                                     {
  1077.                                                         Length = i;
  1078.  
  1079.                                                         Terminated = TRUE;
  1080.  
  1081.                                                         break;
  1082.                                                     }
  1083.                                                 }
  1084.                                             }
  1085.                                             else
  1086.                                             {
  1087.                                                 for(i = 0 ; i < Length ; i++)
  1088.                                                 {
  1089.                                                     if(OtherBuffer[i] == '\r')
  1090.                                                         Lines++;
  1091.                                                 }
  1092.                                             }
  1093.  
  1094.                                             if(Length)
  1095.                                             {
  1096.                                                 Chars += Length;
  1097.  
  1098.                                                 if(BufferWrite(File,OtherBuffer,Length) != Length)
  1099.                                                 {
  1100.                                                     TransferFailed = Terminated = TRUE;
  1101.  
  1102.                                                     AddASCIIMessage(ThisWindow,LocaleString(MSG_ASCIIPANEL_ERROR_WRITING_FILE_TXT),Name);
  1103.                                                 }
  1104.                                             }
  1105.                                         }
  1106.                                     }
  1107.                                 }
  1108.  
  1109.                                 UpdateASCIIWindow(ThisWindow,Chars,0,Lines);
  1110.                             }
  1111.  
  1112.                             StartTime(5,0);
  1113.  
  1114.                             Signals &= ~SIG_TIMER;
  1115.  
  1116.                             RestartSerial();
  1117.                         }
  1118.  
  1119.                         if(Signals & SIG_TIMER)
  1120.                             Terminated = TRUE;
  1121.  
  1122.                         if(Signals & SIG_BREAK)
  1123.                             TransferAborted = Terminated = TRUE;
  1124.                     }
  1125.                     while(!Terminated);
  1126.  
  1127.                     StopTime();
  1128.                 }
  1129.  
  1130.                 BufferClose(File);
  1131.             }
  1132.             else
  1133.             {
  1134.                 AddASCIIMessage(ThisWindow,LocaleString(MSG_ASCIIPANEL_ERROR_OPENING_FILE_TXT),Name);
  1135.  
  1136.                 TransferFailed = TRUE;
  1137.             }
  1138.  
  1139.             if(TransferFailed || TransferError)
  1140.                 WakeUp(ThisWindow,SOUND_BADTRANSFER);
  1141.             else
  1142.             {
  1143.                 WakeUp(ThisWindow,SOUND_GOODTRANSFER);
  1144.  
  1145.                 DelayTime(2,0);
  1146.             }
  1147.  
  1148.             DeleteASCIIWindow(ThisWindow,TransferFailed && WaitForIt);
  1149.         }
  1150.     }
  1151.  
  1152.     if(TransferFailed || TransferAborted)
  1153.         Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1154.     else
  1155.         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1156.  
  1157.     if(OldDir)
  1158.         CurrentDir(OldDir);
  1159.  
  1160.     if(NewDir)
  1161.         UnLock(NewDir);
  1162.  
  1163.     SendAbort = FALSE;
  1164.  
  1165.     Status = OldStatus;
  1166.  
  1167.     ReleaseWindows();
  1168.  
  1169.     DownloadPath = NULL;
  1170.  
  1171.     DidTransfer = FALSE;
  1172.  
  1173.     if(WaitForIt)
  1174.     {
  1175.         if(Config -> CommandConfig -> DownloadMacro[0])
  1176.             SerialCommand(Config -> CommandConfig -> DownloadMacro);
  1177.     }
  1178.  
  1179.     DidTransfer = FALSE;
  1180.  
  1181.     return(DidSend);
  1182. }
  1183.