home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / comm / term23_2.lha / Source_Code / termSource / termXPR.c < prev    next >
C/C++ Source or Header  |  1992-08-18  |  50KB  |  2,201 lines

  1. /*
  2. **    $Id: termXPR.c,v 1.13 92/08/18 16:13:22 olsen Sta Locker: olsen $
  3. **    $Revision: 1.13 $
  4. **    $Date: 92/08/18 16:13:22 $
  5. **
  6. **    External transfer protocol support routines
  7. **
  8. **    Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
  9. **        All Rights Reserved
  10. */
  11.  
  12. #include "termGlobal.h"
  13.  
  14.     /* How many options will xpr_options display in a single column. */
  15.  
  16. #define OPTION_WRAP     16
  17.  
  18.     /* These variables keep the transferred bytes and transfer
  19.      * time in seconds.
  20.      */
  21.  
  22. STATIC LONG         ByteVal,
  23.              ByteMax,
  24.              TimeVal,
  25.              TimeMax;
  26.  
  27.     /* The name of the file being transmitted, in case the
  28.      * `override transfer path' feature is enabled.
  29.      */
  30.  
  31. STATIC UBYTE         RealName[256];
  32.  
  33. STATIC struct Buffer    *CurrentFile;
  34.  
  35.     /* Yet another flag, this one determines whether we already told
  36.      * the user that the file we are currently processing will fit
  37.      * on the destination device.
  38.      */
  39.  
  40. STATIC BYTE         Alerted;
  41.  
  42.     /* xpr_fopen(UBYTE *FileName,UBYTE *AccessMode):
  43.      *
  44.      *    Open a file for random access.
  45.      */
  46.  
  47. LONG __saveds __asm
  48. xpr_fopen(register __a0 UBYTE *FileName,register __a1 UBYTE *AccessMode)
  49. {
  50.     struct Buffer *File;
  51.  
  52.     Alerted = FALSE;
  53.  
  54.         /* Reset transfer counters. */
  55.  
  56.     ByteVal = ByteMax = TimeVal = TimeMax = 0;
  57.  
  58.         /* Disable the time and data bars in the transfer window. */
  59.  
  60.     if(TransferWindow)
  61.     {
  62.         GhostStats(TransferGadgetArray[GAD_TRANSFER_PERCENT]);
  63.         GhostStats(TransferGadgetArray[GAD_TRANSFER_TIME]);
  64.     }
  65.  
  66.         /* Remember file name. */
  67.  
  68.     strcpy(RealName,FileName);
  69.  
  70.         /* Build a new filename if neccessary. */
  71.  
  72.     if(Config . OverridePath)
  73.     {
  74.         if(!Uploading)
  75.         {
  76.             if(!DownloadPath)
  77.             {
  78.                 if(!Config . BinaryDownloadPath[0])
  79.                 {
  80.                     if(!GetCurrentDirName(RealName,256))
  81.                         RealName[0] = 0;
  82.                 }
  83.                 else
  84.                     strcpy(RealName,Config . BinaryDownloadPath);
  85.             }
  86.             else
  87.             {
  88.                 if(!DownloadPath[0])
  89.                 {
  90.                     if(!GetCurrentDirName(RealName,256))
  91.                         RealName[0] = 0;
  92.                 }
  93.                 else
  94.                     strcpy(RealName,DownloadPath);
  95.             }
  96.  
  97.             if(AddPart(RealName,FilePart(FileName),256))
  98.                 FileName = RealName;
  99.             else
  100.                 strcpy(RealName,FileName);
  101.         }
  102.     }
  103.  
  104.         /* Determine file transfer mode... */
  105.  
  106.     if(File = BufferOpen(FileName,AccessMode))
  107.     {
  108.         switch(AccessMode[0])
  109.         {
  110.             case 'r':    LogAction(LocaleString(MSG_TERMXPR_LOGMSG_SEND_FILE_TXT),FileName);
  111.                     break;
  112.  
  113.             case 'w':    LogAction(LocaleString(MSG_TERMXPR_LOGMSG_RECEIVE_FILE_TXT),FileName);
  114.                     AddDownloadObject(FileName);
  115.                     break;
  116.  
  117.             case 'a':    LogAction(LocaleString(MSG_TERMXPR_LOGMSG_UPDATE_FILE_TXT),FileName);
  118.                     break;
  119.         }
  120.  
  121.         CurrentFile = File;
  122.     }
  123.  
  124.     DidTransfer = TRUE;
  125.  
  126.     return((LONG)File);
  127. }
  128.  
  129.     /* xpr_fclose(struct Buffer *File):
  130.      *
  131.      *    Close a file opened by xpr_fopen.
  132.      */
  133.  
  134. LONG __saveds __asm
  135. xpr_fclose(register __a0 struct Buffer *File)
  136. {
  137.     BYTE    WriteAccess    = File -> WriteAccess,
  138.         Used        = File -> Used;
  139.  
  140.         /* Close the file and see what it brings... */
  141.  
  142.     if(BufferClose(File))
  143.     {
  144.             /* Did any access take place at all?
  145.              * xprzmodem.library for example just
  146.              * opens and closes a file in order to
  147.              * see if it exists.
  148.              */
  149.  
  150.         if(!Used)
  151.             LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_TXT),RealName);
  152.         else
  153.         {
  154.                 /* Did we receive or send a file? */
  155.  
  156.             if(WriteAccess)
  157.             {
  158.                 LONG Size;
  159.     
  160.                     /* Did the file remain empty? */
  161.     
  162.                 if(!(Size = GetFileSize(RealName)))
  163.                 {
  164.                     AddTransferInfo(LocaleString(MSG_TERMXPR_FILE_REMOVED_TXT),FilePart(RealName));
  165.  
  166.                         /* Delete empty file. */
  167.  
  168.                     if(DeleteFile(RealName))
  169.                         LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_REMOVED_TXT),RealName);
  170.                     else
  171.                         LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_TXT),RealName);
  172.                 }
  173.                 else
  174.                 {
  175.                     if(ByteMax)
  176.                     {
  177.                         if(Size >= ByteMax)
  178.                             AddTransferInfo(LocaleString(MSG_TERMXPR_FILE_RECEIVED_TXT),FilePart(RealName));
  179.                         else
  180.                             AddTransferInfo(LocaleString(MSG_TERMXPR_INCOMPLETE_FILE_RECEIVED_TXT),FilePart(RealName));
  181.                     }
  182.  
  183.                         /* Try to identify the file type. */
  184.  
  185.                     Identify(RealName);
  186.  
  187.                     LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_BYTES_TXT),RealName,Size);
  188.                 }
  189.             }
  190.             else
  191.             {
  192.                     /* Set the archived bit on files we uploaded? */
  193.  
  194.                 if(Config . SetArchivedBit)
  195.                 {
  196.                     BPTR FileLock;
  197.  
  198.                         /* Get a lock on it. */
  199.  
  200.                     if(FileLock = Lock(RealName,ACCESS_READ))
  201.                     {
  202.                         struct FileInfoBlock __aligned FileInfo;
  203.  
  204.                             /* Examine the file. */
  205.  
  206.                         if(Examine(FileLock,&FileInfo))
  207.                         {
  208.                                 /* Remove the lock. */
  209.  
  210.                             UnLock(FileLock);
  211.  
  212.                                 /* Set the `archived' bit. */
  213.  
  214.                             SetProtection(RealName,FileInfo . fib_Protection | FIBF_ARCHIVE);
  215.                         }
  216.                         else
  217.                             UnLock(FileLock);
  218.                     }
  219.                 }
  220.  
  221.                 AddTransferInfo(LocaleString(MSG_TERMXPR_FILE_SENT_TXT),FilePart(RealName));
  222.  
  223.                 LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_TXT),RealName);
  224.             }
  225.         }
  226.     }
  227.  
  228.     RealName[0] = 0;
  229.  
  230.     CurrentFile = NULL;
  231.  
  232.     return(1);
  233. }
  234.  
  235.     /* xpr_fread(APTR Buffer,LONG Size,LONG Count,struct Buffer *File):
  236.      *
  237.      *    Read a few bytes from a file.
  238.      */
  239.  
  240. LONG __saveds __asm
  241. xpr_fread(register __a0 APTR Buffer,register __d0 LONG Size,register __d1 LONG Count,register __a1 struct Buffer *File)
  242. {
  243.     return(BufferRead(File,Buffer,Size * Count) / Size);
  244. }
  245.  
  246.     /* xpr_fwrite(APTR Buffer,LONG Size,LONG Count,struct Buffer *File):
  247.      *
  248.      *    Write a few bytes to a file.
  249.      */
  250.  
  251. LONG __saveds __asm
  252. xpr_fwrite(register __a0 APTR Buffer,register __d0 LONG Size,register __d1 LONG Count,register __a1 struct Buffer *File)
  253. {
  254.     return(BufferWrite(File,Buffer,Size * Count) / Size);
  255. }
  256.  
  257.     /* xpr_fseek(struct Buffer *File,LONG Offset,LONG Origin):
  258.      *
  259.      *    Move the read/write pointer in a file.
  260.      */
  261.  
  262. LONG __saveds __asm
  263. xpr_fseek(register __a0 struct Buffer *File,register __d0 LONG Offset,register __d1 LONG Origin)
  264. {
  265.     return(BufferSeek(File,Offset,Origin) ? 0 : -1);
  266. }
  267.  
  268.     /* xpr_sread(UBYTE *Buffer,LONG Size,LONG Timeout):
  269.      *
  270.      *    Read a few bytes from the serial port (including
  271.      *    timeouts).
  272.      */
  273.  
  274. ULONG __saveds __asm
  275. xpr_sread(register __a0 UBYTE *Buffer,register __d0 ULONG Size,register __d1 LONG Timeout)
  276. {
  277.         /* Valid parameters? */
  278.  
  279.     if(WriteRequest && Size)
  280.     {
  281.             /* How many bytes are still in the serial buffer? */
  282.  
  283.         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  284.  
  285.         DoIO(WriteRequest);
  286.  
  287.             /* Return error if carrier is lost. */
  288.  
  289.         if(Config . CheckCarrier && (WriteRequest -> io_Status & (1 << 5)))
  290.         {
  291.             Online = FALSE;
  292.  
  293.             return(-1);
  294.         }
  295.  
  296.             /* No timeout specified? Return as many bytes
  297.              * as are currently within the buffer.
  298.              */
  299.  
  300.         if(Timeout < 1)
  301.         {
  302.                 /* Are there any bytes in the buffer? */
  303.  
  304.             if(WriteRequest -> IOSer . io_Actual > 0)
  305.             {
  306.                     /* More bytes available than requested? */
  307.  
  308.                 if(Size < WriteRequest -> IOSer . io_Actual)
  309.                     ReadRequest -> IOSer . io_Length = Size;
  310.                 else
  311.                     ReadRequest -> IOSer . io_Length = WriteRequest -> IOSer . io_Actual;
  312.  
  313.                     /* Fill the buffer. */
  314.  
  315.                 ReadRequest -> IOSer . io_Command    = CMD_READ;
  316.                 ReadRequest -> IOSer . io_Data        = Buffer;
  317.  
  318.                 if(!DoIO(ReadRequest))
  319.                 {
  320.                     BytesIn += ReadRequest -> IOSer . io_Actual;
  321.  
  322.                     return(ReadRequest -> IOSer . io_Actual);
  323.                 }
  324.             }
  325.         }
  326.         else
  327.         {
  328.             if(WriteRequest -> IOSer . io_Actual < Size)
  329.             {
  330.                 register ULONG SignalSet;
  331.  
  332.                     /* Set up the timer. */
  333.  
  334.                 TimeRequest -> tr_node . io_Command = TR_ADDREQUEST;
  335.  
  336.                 if(Timeout >= MILLION)
  337.                 {
  338.                     TimeRequest -> tr_time . tv_secs    = Timeout >= MILLION ? Timeout / MILLION : 0;
  339.                     TimeRequest -> tr_time . tv_micro    = Timeout % MILLION;
  340.                 }
  341.                 else
  342.                 {
  343.                     TimeRequest -> tr_time . tv_secs    = 0;
  344.                     TimeRequest -> tr_time . tv_micro    = Timeout;
  345.                 }
  346.  
  347.                     /* Set up the read request. */
  348.  
  349.                 ReadRequest -> IOSer . io_Command    = CMD_READ;
  350.                 ReadRequest -> IOSer . io_Data        = Buffer;
  351.                 ReadRequest -> IOSer . io_Length    = Size;
  352.  
  353.                     /* Prevent early termination. */
  354.  
  355.                 SetSignal(0,SIG_SERIAL | SIG_TIMER);
  356.  
  357.                     /* Start IO... */
  358.  
  359.                 SendIO(ReadRequest);
  360.                 SendIO(TimeRequest);
  361.  
  362.                 FOREVER
  363.                 {
  364.                         /* Build signal mask. */
  365.  
  366.                     if(TransferWindow)
  367.                         SignalSet = SIG_SERIAL | SIG_TIMER | (1 << TransferWindow -> UserPort -> mp_SigBit);
  368.                     else
  369.                         SignalSet = SIG_SERIAL | SIG_TIMER;
  370.  
  371.                         /* Wait for either of both IORequests to return. */
  372.  
  373.                     SignalSet = Wait(SignalSet);
  374.  
  375.                         /* Hit by timeout? */
  376.  
  377.                     if(SignalSet & SIG_TIMER)
  378.                     {
  379.                             /* Abort the read request. */
  380.  
  381.                         AbortIO(ReadRequest);
  382.                         WaitIO(ReadRequest);
  383.  
  384.                             /* Remove the timer request. */
  385.  
  386.                         WaitIO(TimeRequest);
  387.  
  388.                             /* Did the driver receive any
  389.                              * data?
  390.                              */
  391.  
  392.                         if(!ReadRequest -> IOSer . io_Actual)
  393.                         {
  394.                                 /* Take a second look and query the number of
  395.                                  * bytes ready to be received, there may
  396.                                  * still be some bytes in the buffer.
  397.                                  * Note: this depends on the way the
  398.                                  * driver handles read abort.
  399.                                  */
  400.  
  401.                             WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  402.  
  403.                             DoIO(WriteRequest);
  404.  
  405.                                 /* Are there any bytes to transfer? */
  406.  
  407.                             if(WriteRequest -> IOSer . io_Actual > 0)
  408.                             {
  409.                                     /* Don't read more than actually wanted. */
  410.  
  411.                                 if(Size < WriteRequest -> IOSer . io_Actual)
  412.                                     ReadRequest -> IOSer . io_Length = Size;
  413.                                 else
  414.                                     ReadRequest -> IOSer . io_Length = WriteRequest -> IOSer . io_Actual;
  415.  
  416.                                 ReadRequest -> IOSer . io_Command    = CMD_READ;
  417.                                 ReadRequest -> IOSer . io_Data        = Buffer;
  418.  
  419.                                     /* Read the data. */
  420.  
  421.                                 if(!DoIO(ReadRequest))
  422.                                 {
  423.                                     BytesIn += ReadRequest -> IOSer . io_Actual;
  424.  
  425.                                     return(ReadRequest -> IOSer . io_Actual);
  426.                                 }
  427.                                 else
  428.                                     return(0);
  429.                             }
  430.                             else
  431.                                 return(0);
  432.                         }
  433.                         else
  434.                             return(ReadRequest -> IOSer . io_Actual);
  435.                     }
  436.  
  437.                         /* Receive buffer filled? */
  438.  
  439.                     if(SignalSet & SIG_SERIAL)
  440.                     {
  441.                         AbortIO(TimeRequest);
  442.                         WaitIO(TimeRequest);
  443.  
  444.                         WaitIO(ReadRequest);
  445.  
  446.                         if(!ReadRequest -> IOSer . io_Error)
  447.                         {
  448.                             BytesIn += ReadRequest -> IOSer . io_Actual;
  449.  
  450.                             return(ReadRequest -> IOSer . io_Actual);
  451.                         }
  452.                         else
  453.                             return(0);
  454.                     }
  455.  
  456.                         /* Check the transfer window for
  457.                          * possible user abort.
  458.                          */
  459.  
  460.                     if(TransferWindow)
  461.                     {
  462.                         if(SignalSet & (1 << TransferWindow -> UserPort -> mp_SigBit))
  463.                         {
  464.                             if(xpr_chkabort() == -1)
  465.                             {
  466.                                 AbortIO(ReadRequest);
  467.                                 AbortIO(TimeRequest);
  468.  
  469.                                 WaitIO(ReadRequest);
  470.                                 WaitIO(TimeRequest);
  471.  
  472.                                 SendAbort = TRUE;
  473.  
  474.                                 return(-1);
  475.                             }
  476.                         }
  477.                     }
  478.                 }
  479.             }
  480.             else
  481.             {
  482.                 ReadRequest -> IOSer . io_Command    = CMD_READ;
  483.                 ReadRequest -> IOSer . io_Data        = Buffer;
  484.                 ReadRequest -> IOSer . io_Length    = Size;
  485.  
  486.                 if(!DoIO(ReadRequest))
  487.                 {
  488.                     BytesIn += ReadRequest -> IOSer . io_Actual;
  489.  
  490.                     return(Size);
  491.                 }
  492.             }
  493.         }
  494.     }
  495.  
  496.     return(0);
  497. }
  498.  
  499.     /* xpr_swrite(UBYTE *Buffer,LONG Size):
  500.      *
  501.      *    Write a few bytes to the serial port.
  502.      */
  503.  
  504. LONG __saveds __asm
  505. xpr_swrite(register __a0 UBYTE *Buffer,register __d0 LONG Size)
  506. {
  507.     if(WriteRequest)
  508.     {
  509.         WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  510.         WriteRequest -> IOSer . io_Data        = Buffer;
  511.         WriteRequest -> IOSer . io_Length    = Size;
  512.  
  513.         BytesOut += Size;
  514.  
  515.         return((LONG)DoIO(WriteRequest));
  516.     }
  517.     else
  518.         return(-1);
  519. }
  520.  
  521.     /* xpr_sflush():
  522.      *
  523.      *    Release the contents of all serial buffers.
  524.      */
  525.  
  526. LONG __saveds
  527. xpr_sflush()
  528. {
  529.     if(WriteRequest)
  530.     {
  531.         WriteRequest -> IOSer . io_Command = CMD_CLEAR;
  532.  
  533.         return((LONG)DoIO(WriteRequest));
  534.     }
  535.     else
  536.         return(-1);
  537. }
  538.  
  539.     /* GetSeconds(UBYTE *String):
  540.      *
  541.      *    Tries to turn a string of the format hh:mm:ss into
  542.      *    an integer number.
  543.      */
  544.  
  545. STATIC LONG __regargs
  546. GetSeconds(UBYTE *String)
  547. {
  548.     UBYTE    Buffer[20];
  549.     LONG    Seconds = 0;
  550.  
  551.     memset(Buffer,0,20);
  552.  
  553.     strcpy(Buffer,String);
  554.  
  555.     Seconds += atol(&Buffer[6]);
  556.  
  557.     Buffer[5] = 0;
  558.  
  559.     Seconds += atol(&Buffer[3]) * 60;
  560.  
  561.     Buffer[2] = 0;
  562.  
  563.     Seconds += atol(&Buffer[0]) * 3600;
  564.  
  565.     return(Seconds);
  566. }
  567.  
  568.     /* TruncateName(UBYTE *FileName):
  569.      *
  570.      *    Truncates a file name to a maximum of 48 characters.
  571.      */
  572.  
  573. STATIC UBYTE * __regargs
  574. TruncateName(UBYTE *FileName)
  575. {
  576.     WORD Len = strlen(FileName);
  577.  
  578.     if(Len > 48)
  579.     {
  580.         WORD i;
  581.  
  582.         for(i = Len - 48 ; i < Len ; i++)
  583.         {
  584.             if(i >= Len - 44 && FileName[i] == '/')
  585.             {
  586.                 STATIC UBYTE NameBuffer[256];
  587.  
  588.                 strcpy(NameBuffer,".../");
  589.  
  590.                 strcat(NameBuffer,&FileName[i + 1]);
  591.  
  592.                 return(NameBuffer);
  593.             }
  594.         }
  595.     }
  596.  
  597.     return(FileName);
  598. }
  599.  
  600.     /* CalculateBlocks(LONG Size,LONG BlockSize):
  601.      *
  602.      *    Calculate the number of blocks a file will
  603.      *    occupy if saved to a disk.
  604.      */
  605.  
  606. STATIC LONG __regargs
  607. CalculateBlocks(LONG Size,LONG BlockSize)
  608. {
  609.     LONG    Blocks        = 1;        /* One for the file header. */
  610.     BYTE    HasExtension    = FALSE,    /* No extension block yet. */
  611.         Extension    = 0;        /* How many block pointers yet. */
  612.  
  613.         /* Round to next block. */
  614.  
  615.     Size = ((Size + BlockSize - 1) / BlockSize) * BlockSize;
  616.  
  617.     while(Size)
  618.     {
  619.             /* Add another block. */
  620.  
  621.         Blocks++;
  622.  
  623.             /* Subtract another block. */
  624.  
  625.         Size -= BlockSize;
  626.  
  627.             /* Add another block pointer, if 72 have been
  628.              * added, add another extension block.
  629.              */
  630.  
  631.         if((Extension++) == 72)
  632.         {
  633.                 /* If no extension block has been generated
  634.                  * yet, we were running on the block pointers
  635.                  * of the file header itself.
  636.                  */
  637.  
  638.             if(!HasExtension)
  639.                 HasExtension = TRUE;
  640.             else
  641.                 Blocks++;
  642.  
  643.                 /* Reset extension block counter. */
  644.  
  645.             Extension = 0;
  646.         }
  647.     }
  648.  
  649.     return(Blocks);
  650. }
  651.  
  652.     /* xpr_update(struct XPR_UPDATE *UpdateInfo):
  653.      *
  654.      *    Update the information displayed in the transfer window.
  655.      */
  656.  
  657. LONG __saveds __asm
  658. xpr_update(register __a0 struct XPR_UPDATE *UpdateInfo)
  659. {
  660.     if(!TransferWindow)
  661.     {
  662.         BlockWindows();
  663.  
  664.         LogAction(LocaleString(MSG_TERMXPR_LOGMSG_INITIATE_BINARY_DOWNLOAD_TXT));
  665.  
  666.         if(!TransferPanel(LocaleString(MSG_TERMXPR_RECEIVE_FILES_TXT)))
  667.         {
  668.             ReleaseWindows();
  669.  
  670.             return(0);
  671.         }
  672.     }
  673.  
  674.     if(UpdateInfo)
  675.     {
  676.         BYTE    NewByte = FALSE,
  677.             NewTime = FALSE;
  678.  
  679.         if((UpdateInfo -> xpru_updatemask & XPRU_PROTOCOL) && UpdateInfo -> xpru_protocol)
  680.             SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_1],0,UpdateInfo -> xpru_protocol);
  681.  
  682.         if((UpdateInfo -> xpru_updatemask & XPRU_MSG) && UpdateInfo -> xpru_msg)
  683.             SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_2],0,UpdateInfo -> xpru_msg);
  684.  
  685.         if((UpdateInfo -> xpru_updatemask & XPRU_ERRORMSG) && UpdateInfo -> xpru_errormsg)
  686.             AddTransferInfo(UpdateInfo -> xpru_errormsg);
  687.  
  688.         if((UpdateInfo -> xpru_updatemask & XPRU_FILENAME) && UpdateInfo -> xpru_filename)
  689.         {
  690.             if(Config . OverridePath && !Uploading)
  691.             {
  692.                 if(!RealName[0])
  693.                 {
  694.                     if(!DownloadPath)
  695.                         strcpy(RealName,&Config . BinaryDownloadPath[0]);
  696.                     else
  697.                         strcpy(RealName,DownloadPath);
  698.  
  699.                     if(!AddPart(RealName,FilePart(UpdateInfo -> xpru_filename),256))
  700.                         strcpy(RealName,UpdateInfo -> xpru_filename);
  701.                 }
  702.  
  703.                 SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_3],0,TruncateName(RealName));
  704.             }
  705.             else
  706.                 SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_3],0,TruncateName(UpdateInfo -> xpru_filename));
  707.         }
  708.  
  709.         if((UpdateInfo -> xpru_updatemask & XPRU_FILESIZE) && UpdateInfo -> xpru_filesize != -1)
  710.         {
  711.             if(CurrentFile -> DirLock && CurrentFile -> InfoData . id_NumBlocks && CurrentFile -> InfoData . id_BytesPerBlock)
  712.                 SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_3],1,ConvNumber10,UpdateInfo -> xpru_filesize);
  713.             else
  714.                 SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_3],1,ConvNumber,UpdateInfo -> xpru_filesize);
  715.  
  716.             if(ByteMax = UpdateInfo -> xpru_filesize)
  717.                 NewByte = TRUE;
  718.         }
  719.  
  720.         if((UpdateInfo -> xpru_updatemask & XPRU_BYTES) && UpdateInfo -> xpru_bytes != -1)
  721.         {
  722.             SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],0,ConvNumber,ByteVal = UpdateInfo -> xpru_bytes);
  723.  
  724.             if(ByteMax)
  725.                 NewByte = TRUE;
  726.  
  727.             if(CurrentFile -> DirLock && !Uploading)
  728.             {
  729.                 if(CurrentFile -> InfoData . id_NumBlocks && CurrentFile -> InfoData . id_BytesPerBlock)
  730.                 {
  731.                     if(ByteMax)
  732.                     {
  733.                         register LONG Blocks = CalculateBlocks(ByteMax,CurrentFile -> InfoData . id_BytesPerBlock),Space = CurrentFile -> InfoData . id_NumBlocks - CurrentFile -> InfoData . id_NumBlocksUsed;
  734.  
  735.                         SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_3],2,LocaleString(MSG_TERMXPR_BYTES_FULL_TXT),Space * CurrentFile -> InfoData . id_BytesPerBlock,100 * (CurrentFile -> InfoData . id_NumBlocksUsed) / CurrentFile -> InfoData . id_NumBlocks,(Space < Blocks) ? LocaleString(MSG_TERMXPR_FILE_MAY_NOT_FIT_TXT) : "");
  736.  
  737.                             /* Tell the user that trouble
  738.                              * might be underway.
  739.                              */
  740.  
  741.                         if(!Alerted && (Space < Blocks))
  742.                         {
  743.                             Alerted = TRUE;
  744.  
  745.                             BumpWindow(TransferWindow);
  746.  
  747.                             Say(LocaleString(MSG_TERMXPR_SAY_FILE_MAY_NOT_FIT_TXT));
  748.                         }
  749.                     }
  750.                     else
  751.                         SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_3],2,LocaleString(MSG_TERMXPR_BYTES_FULL_TXT),(CurrentFile -> InfoData . id_NumBlocks - CurrentFile -> InfoData . id_NumBlocksUsed) * CurrentFile -> InfoData . id_BytesPerBlock,100 * (CurrentFile -> InfoData . id_NumBlocksUsed) / CurrentFile -> InfoData . id_NumBlocks);
  752.                 }
  753.             }
  754.         }
  755.  
  756.         if((UpdateInfo -> xpru_updatemask & XPRU_BLOCKS) && UpdateInfo -> xpru_blocks != -1)
  757.             SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],1,ConvNumber,UpdateInfo -> xpru_blocks);
  758.  
  759.         if((UpdateInfo -> xpru_updatemask & XPRU_BLOCKSIZE) && UpdateInfo -> xpru_blocksize != -1)
  760.             SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],2,ConvNumber,UpdateInfo -> xpru_blocksize);
  761.  
  762.         if((UpdateInfo -> xpru_updatemask & XPRU_BLOCKCHECK) && UpdateInfo -> xpru_blockcheck)
  763.             SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],3,UpdateInfo -> xpru_blockcheck);
  764.  
  765.         if((UpdateInfo -> xpru_updatemask & XPRU_EXPECTTIME) && UpdateInfo -> xpru_expecttime)
  766.         {
  767.             SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_LEFT2],0,UpdateInfo -> xpru_expecttime);
  768.  
  769.             if(TimeMax = GetSeconds((UBYTE *)UpdateInfo -> xpru_expecttime))
  770.                 NewTime = TRUE;
  771.         }
  772.  
  773.         if((UpdateInfo -> xpru_updatemask & XPRU_ELAPSEDTIME) && UpdateInfo -> xpru_elapsedtime)
  774.         {
  775.             SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_LEFT2],1,UpdateInfo -> xpru_elapsedtime);
  776.  
  777.             TimeVal = GetSeconds((UBYTE *)UpdateInfo -> xpru_elapsedtime);
  778.  
  779.             if(TimeMax)
  780.                 NewTime = TRUE;
  781.         }
  782.  
  783.         if((UpdateInfo -> xpru_updatemask & XPRU_DATARATE) && UpdateInfo -> xpru_datarate != -1)
  784.             SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],0,ConvNumber,UpdateInfo -> xpru_datarate);
  785.  
  786.         if((UpdateInfo -> xpru_updatemask & XPRU_CHARDELAY) && UpdateInfo -> xpru_chardelay != -1)
  787.             SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],1,ConvNumber,UpdateInfo -> xpru_chardelay);
  788.  
  789.         if((UpdateInfo -> xpru_updatemask & XPRU_PACKETDELAY) && UpdateInfo -> xpru_packetdelay != -1)
  790.             SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],2,ConvNumber,UpdateInfo -> xpru_packetdelay);
  791.  
  792.         if((UpdateInfo -> xpru_updatemask & XPRU_PACKETTYPE) && UpdateInfo -> xpru_packettype != -1)
  793.         {
  794.             if(UpdateInfo -> xpru_packettype > 32 && UpdateInfo -> xpru_packettype < 256)
  795.             {
  796.                 if(ValidTab[UpdateInfo -> xpru_packettype])
  797.                     SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],3,"`%lc'",UpdateInfo -> xpru_packettype);
  798.                 else
  799.                     SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],3,ConvNumber,UpdateInfo -> xpru_packettype);
  800.             }
  801.             else
  802.                 SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],3,ConvNumber,UpdateInfo -> xpru_packettype);
  803.         }
  804.  
  805.         if((UpdateInfo -> xpru_updatemask & XPRU_ERRORS) && UpdateInfo -> xpru_errors != -1)
  806.             SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT2],0,ConvNumber,UpdateInfo -> xpru_errors);
  807.  
  808.         if((UpdateInfo -> xpru_updatemask & XPRU_TIMEOUTS) && UpdateInfo -> xpru_timeouts != -1)
  809.             SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT2],1,ConvNumber,UpdateInfo -> xpru_timeouts);
  810.  
  811.         if(TransferWindow)
  812.         {
  813.             if(NewByte)
  814.             {
  815.                 ShowStats(TransferGadgetArray[GAD_TRANSFER_PERCENT],ByteVal,ByteMax);
  816.  
  817.                 if(ByteMax)
  818.                     ShowString(TransferGadgetArray[GAD_TRANSFER_PERCENT],"%ld%%",(100 * ByteVal) / ByteMax);
  819.                 else
  820.                     ShowString(TransferGadgetArray[GAD_TRANSFER_PERCENT],"%ld%%",0);
  821.             }
  822.  
  823.             if(NewTime)
  824.             {
  825.                 LONG TimeDif = (TimeMax - TimeVal) < 0 ? 0 : TimeMax - TimeVal;
  826.  
  827.                 ShowStats(TransferGadgetArray[GAD_TRANSFER_TIME],TimeDif,TimeMax);
  828.  
  829.                 ShowString(TransferGadgetArray[GAD_TRANSFER_TIME],"%2ld:%02ld:%02ld",TimeDif / 3600,(TimeDif / 60) % 60,TimeDif % 60);
  830.             }
  831.         }
  832.     }
  833.  
  834.     return(1);
  835. }
  836.  
  837.     /* xpr_chkabort():
  838.      *
  839.      *    Check if the user has aborted the transfer.
  840.      */
  841.  
  842. LONG __saveds
  843. xpr_chkabort()
  844. {
  845.     LONG Result = 0;
  846.  
  847.     if(TransferWindow)
  848.     {
  849.         struct IntuiMessage    *Massage;
  850.         ULONG             Class,Code;
  851.         struct Gadget        *Gadget;
  852.  
  853.         while(Massage = (struct IntuiMessage *)GT_GetIMsg(TransferWindow -> UserPort))
  854.         {
  855.             Class    = Massage -> Class;
  856.             Code    = Massage -> Code;
  857.             Gadget    = (struct Gadget *)Massage -> IAddress;
  858.  
  859.             GT_ReplyIMsg(Massage);
  860.  
  861.             if(!Result)
  862.             {
  863.                 if(Class == IDCMP_VANILLAKEY)
  864.                     KeySelect(TransferGadgetArray,4,Code,TransferWindow,&Gadget,&Class,&Code);
  865.  
  866.                 if(Class == IDCMP_NEWSIZE)
  867.                 {
  868.                     if(!(TransferWindow -> Flags & WFLG_ZOOMED))
  869.                         RefreshTransferWindow();
  870.                 }
  871.  
  872.                 if(Class == IDCMP_CLOSEWINDOW)
  873.                 {
  874.                     LogAction(LocaleString(MSG_TERMXPR_LOGMSG_TRANSFER_ABORTED_TXT));
  875.  
  876.                     TransferAborted = TRUE;
  877.  
  878.                     Result = -1;
  879.                 }
  880.  
  881.                 if(Class == IDCMP_GADGETUP)
  882.                 {
  883.                     switch(Gadget -> GadgetID)
  884.                     {
  885.                         case GAD_TRANSFER_ABORT:    LogAction(LocaleString(MSG_TERMXPR_LOGMSG_TRANSFER_ABORTED_TXT));
  886.  
  887.                                         TransferAborted = TRUE;
  888.  
  889.                                         Result = -1;
  890.                                         break;
  891.  
  892.                         case GAD_TRANSFER_SKIP:        LogAction(LocaleString(MSG_TERMXPR_LOGMSG_FILE_SKIPPED_TXT));
  893.  
  894.                                         Result = 1;
  895.                                         break;
  896.  
  897.                         default:            break;
  898.                     }
  899.                 }
  900.             }
  901.         }
  902.     }
  903.  
  904.     return(Result);
  905. }
  906.  
  907.     /* The following subroutine creates the gadgets required by
  908.      * xpr_gets().
  909.      */
  910.  
  911. struct Gadget *
  912. CreateAllGetsGadgets(BYTE LoadGadget,UBYTE *String,UBYTE *Prompt,struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge,struct Screen *Screen)
  913. {
  914.     struct Gadget        *Gadget;
  915.     struct NewGadget     NewGadget;
  916.  
  917.     memset(&NewGadget,0,sizeof(struct NewGadget));
  918.  
  919.     SZ_SizeSetup(Screen,&UserFont,TRUE);
  920.  
  921.     if(Gadget = CreateContext(GadgetList))
  922.     {
  923.         WORD Width = SZ_TextWidth(Prompt),Counter = 0;
  924.  
  925.         if(Width < SZ_Width(STRING_KIND,NULL,60,NULL))
  926.             Width = SZ_Width(STRING_KIND,NULL,60,NULL);
  927.  
  928.         SZ_SetWidth(Width);
  929.  
  930.         NewGadget . ng_GadgetText    = Prompt;
  931.         NewGadget . ng_TextAttr        = &UserFont;
  932.         NewGadget . ng_VisualInfo    = VisualInfo;
  933.         NewGadget . ng_GadgetID        = Counter;
  934.         NewGadget . ng_Flags        = PLACETEXT_ABOVE;
  935.  
  936.         GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  937.             SZ_Adjust,    TRUE,
  938.             SZ_AutoWidth,    TRUE,
  939.  
  940.             GTST_MaxChars,    255,
  941.             GTST_String,    String,
  942.             GTST_EditHook,    &CommandHook,
  943.             GA_Immediate,    TRUE,
  944.         TAG_DONE);
  945.  
  946.         if(LoadGadget)
  947.         {
  948.             SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_TERMXPR_OKAY_GAD),0,NULL);
  949.             SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_TERMXPR_LOAD_FILE_GAD),0,NULL);
  950.             SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_CANCEL_GAD),0,NULL);
  951.  
  952.             SZ_SetWidth(SZ_ResetMaxWidth());
  953.  
  954.             NewGadget . ng_GadgetText    = LocaleString(MSG_TERMXPR_OKAY_GAD);
  955.             NewGadget . ng_GadgetID        = Counter;
  956.             NewGadget . ng_Flags        = 0;
  957.  
  958.             GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  959.                 SZ_Adjust,    TRUE,
  960.                 SZ_AutoWidth,    TRUE,
  961.                 SZ_AlignExtra,    TRUE,
  962.                 SZ_AlignBottom,    TRUE,
  963.                 SZ_GroupCount,    3,
  964.  
  965.                 GT_Underscore,    '_',
  966.             TAG_DONE);
  967.  
  968.             NewGadget . ng_GadgetText    = LocaleString(MSG_TERMXPR_LOAD_FILE_GAD);
  969.             NewGadget . ng_GadgetID        = Counter;
  970.  
  971.             GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  972.                 SZ_Adjust,    TRUE,
  973.                 SZ_AutoWidth,    TRUE,
  974.                 SZ_GroupNext,    TRUE,
  975.  
  976.                 GT_Underscore,    '_',
  977.             TAG_DONE);
  978.  
  979.             NewGadget . ng_GadgetText    = LocaleString(MSG_GLOBAL_CANCEL_GAD);
  980.             NewGadget . ng_GadgetID        = Counter;
  981.  
  982.             GadgetArray[Counter] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  983.                 SZ_Adjust,    TRUE,
  984.                 SZ_AutoWidth,    TRUE,
  985.                 SZ_GroupNext,    TRUE,
  986.  
  987.                 GT_Underscore,    '_',
  988.             TAG_DONE);
  989.         }
  990.         else
  991.         {
  992.             SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_TERMXPR_OKAY_GAD),0,NULL);
  993.             SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_CANCEL_GAD),0,NULL);
  994.  
  995.             SZ_SetWidth(SZ_ResetMaxWidth());
  996.  
  997.             NewGadget . ng_GadgetText    = LocaleString(MSG_TERMXPR_OKAY_GAD);
  998.             NewGadget . ng_GadgetID        = Counter;
  999.             NewGadget . ng_Flags        = 0;
  1000.  
  1001.             GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1002.                 SZ_Adjust,    TRUE,
  1003.                 SZ_AutoWidth,    TRUE,
  1004.                 SZ_AlignExtra,    TRUE,
  1005.                 SZ_AlignLeft,    TRUE,
  1006.                 SZ_AlignBottom,    TRUE,
  1007.  
  1008.                 GT_Underscore,    '_',
  1009.             TAG_DONE);
  1010.  
  1011.             Counter++;
  1012.  
  1013.             NewGadget . ng_GadgetText    = LocaleString(MSG_GLOBAL_CANCEL_GAD);
  1014.             NewGadget . ng_GadgetID        = Counter;
  1015.  
  1016.             GadgetArray[Counter] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1017.                 SZ_Adjust,    TRUE,
  1018.                 SZ_AutoWidth,    TRUE,
  1019.                 SZ_AlignRight,    TRUE,
  1020.  
  1021.                 GT_Underscore,    '_',
  1022.             TAG_DONE);
  1023.         }
  1024.     }
  1025.  
  1026.     return(Gadget);
  1027. }
  1028.  
  1029.     /* xpr_gets(UBYTE *Prompt,UBYTE *Buffer):
  1030.      *
  1031.      *    Prompt the user for string input.
  1032.      */
  1033.  
  1034. LONG __saveds __asm
  1035. xpr_gets(register __a0 UBYTE *Prompt,register __a1 UBYTE *Buffer)
  1036. {
  1037.     struct Gadget    *GadgetList = NULL;
  1038.     struct Gadget    *GadgetArray[4];
  1039.     struct Window    *PanelWindow;
  1040.     LONG         Success = FALSE;
  1041.  
  1042.     if(!Prompt)
  1043.         Prompt = LocaleString(MSG_TERMXPR_INPUT_REQUIRED_TXT);
  1044.  
  1045.     if(CreateAllGetsGadgets(FALSE,Buffer,Prompt,&GadgetArray[0],&GadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1,Screen))
  1046.     {
  1047.         if(PanelWindow = OpenWindowTags(NULL,
  1048.             WA_Left,    (Screen -> Width    - SZ_GetWindowWidth())    / 2,
  1049.             WA_Top,        (Screen -> Height    - SZ_GetWindowHeight())    / 2,
  1050.             WA_Width,    SZ_GetWindowWidth(),
  1051.             WA_Height,    SZ_GetWindowHeight(),
  1052.  
  1053.             WA_Activate,    TRUE,
  1054.             WA_DragBar,    TRUE,
  1055.             WA_DepthGadget,    TRUE,
  1056.             WA_CloseGadget,    TRUE,
  1057.             WA_RMBTrap,    TRUE,
  1058.             WA_CustomScreen,Screen,
  1059.  
  1060.             WA_IDCMP,    IDCMP_GADGETDOWN | IDCMP_ACTIVEWINDOW | IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | BUTTONIDCMP | STRINGIDCMP,
  1061.  
  1062.             WA_Title,    LocaleString(MSG_GLOBAL_ENTER_TEXT_TXT),
  1063.         TAG_DONE))
  1064.         {
  1065.             struct IntuiMessage    *Massage;
  1066.             ULONG             Class,Code;
  1067.             struct Gadget        *Gadget;
  1068.             BYTE             Terminated = FALSE;
  1069.  
  1070.             PushWindow(PanelWindow);
  1071.  
  1072.             AddGList(PanelWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
  1073.             RefreshGList(GadgetList,PanelWindow,NULL,(UWORD)-1);
  1074.             GT_RefreshWindow(PanelWindow,NULL);
  1075.  
  1076.             ActiveGadget = NULL;
  1077.  
  1078.             while(!Terminated)
  1079.             {
  1080.                 WaitPort(PanelWindow -> UserPort);
  1081.  
  1082.                 while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> UserPort)))
  1083.                 {
  1084.                     Class    = Massage -> Class;
  1085.                     Code    = Massage -> Code;
  1086.                     Gadget    = (struct Gadget *)Massage -> IAddress;
  1087.  
  1088.                     GT_ReplyIMsg(Massage);
  1089.  
  1090.                     if(Class == IDCMP_VANILLAKEY)
  1091.                         KeySelect(GadgetArray,3,Code,PanelWindow,&Gadget,&Class,&Code);
  1092.  
  1093.                     if(Class == IDCMP_GADGETDOWN)
  1094.                     {
  1095.                         if((Gadget -> GadgetType & GTYP_GTYPEMASK) == GTYP_STRGADGET)
  1096.                             ActiveGadget = Gadget;
  1097.                     }
  1098.  
  1099.                     if(Class == IDCMP_GADGETDOWN)
  1100.                     {
  1101.                         if((Gadget -> GadgetType & GTYP_GTYPEMASK) == GTYP_STRGADGET)
  1102.                             ActiveGadget = Gadget;
  1103.                     }
  1104.  
  1105.                     if(Class == IDCMP_ACTIVEWINDOW && ActiveGadget)
  1106.                         ActivateGadget(ActiveGadget,PanelWindow,NULL);
  1107.  
  1108.                     if(Class == IDCMP_CLOSEWINDOW)
  1109.                         Terminated = TRUE;
  1110.  
  1111.                     if(Class == IDCMP_GADGETUP)
  1112.                     {
  1113.                         switch(Gadget -> GadgetID)
  1114.                         {
  1115.                             case 0: if(Code != '\t')
  1116.                                 {
  1117.                                     strcpy(Buffer,GT_STRING(GadgetArray[0]));
  1118.  
  1119.                                     Success = TRUE;
  1120.  
  1121.                                     Terminated = TRUE;
  1122.                                     break;
  1123.                                 }
  1124.  
  1125.                             case 1:    strcpy(Buffer,GT_STRING(GadgetArray[0]));
  1126.  
  1127.                                 Success = TRUE;
  1128.  
  1129.                                 Terminated = TRUE;
  1130.                                 break;
  1131.  
  1132.                             case 3:    Terminated = TRUE;
  1133.                                 break;
  1134.                         }
  1135.                     }
  1136.                 }
  1137.             }
  1138.  
  1139.             ActiveGadget = NULL;
  1140.  
  1141.             RemoveGList(PanelWindow,GadgetList,(UWORD)-1);
  1142.  
  1143.             PopWindow();
  1144.  
  1145.             CloseWindow(PanelWindow);
  1146.         }
  1147.  
  1148.         FreeGadgets(GadgetList);
  1149.     }
  1150.  
  1151.     return(Success);
  1152. }
  1153.  
  1154.     /* xpr_setserial(LONG Status):
  1155.      *
  1156.      *    Set/read the serial status (parameters).
  1157.      */
  1158.  
  1159. LONG __saveds __asm
  1160. xpr_setserial(register __d0 LONG Status)
  1161. {
  1162.     if(WriteRequest)
  1163.     {
  1164.         STATIC LONG XprBauds[12] =
  1165.         {
  1166.                110,
  1167.                300,
  1168.               1200,
  1169.               2400,
  1170.               4800,
  1171.               9600,
  1172.              19200,
  1173.              31250,
  1174.              38400,
  1175.              57600,
  1176.              76800,
  1177.             115200
  1178.         };
  1179.  
  1180.         LONG Return,i;
  1181.  
  1182.         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  1183.  
  1184.         DoIO(WriteRequest);
  1185.  
  1186.         Return = WriteRequest -> io_SerFlags & 0xFF;
  1187.  
  1188.         if(WriteRequest -> io_ExtFlags & SEXTF_MSPON)
  1189.             Return |= ST_PARTYMARKON;
  1190.  
  1191.         if(WriteRequest -> io_ExtFlags & SEXTF_MARK)
  1192.             Return |= ST_PARTYMARK;
  1193.  
  1194.         if(WriteRequest -> io_StopBits == 2)
  1195.             Return |= ST_2BITS;
  1196.  
  1197.         if(WriteRequest -> io_ReadLen == 7)
  1198.             Return |= ST_READ7;
  1199.  
  1200.         if(WriteRequest -> io_WriteLen == 7)
  1201.             Return |= ST_WRITE7;
  1202.  
  1203.         for(i = 0 ; i < 12 ; i++)
  1204.         {
  1205.             if(WriteRequest -> io_Baud <= XprBauds[i])
  1206.             {
  1207.                 Return |= (i << 16);
  1208.  
  1209.                 break;
  1210.             }
  1211.         }
  1212.  
  1213.         if(Status != -1)
  1214.         {
  1215.             WriteRequest -> IOSer . io_Command    = SDCMD_SETPARAMS;
  1216.  
  1217.             WriteRequest -> io_SerFlags        = Status & 0xFF;
  1218.             WriteRequest -> io_ExtFlags        = 0;
  1219.  
  1220.             if(Status & ST_PARTYMARKON)
  1221.                 WriteRequest -> io_ExtFlags |= SEXTF_MSPON;
  1222.  
  1223.             if(Status & ST_PARTYMARK)
  1224.                 WriteRequest -> io_ExtFlags |= SEXTF_MARK;
  1225.  
  1226.             if(Status & ST_2BITS)
  1227.                 WriteRequest -> io_StopBits = 2;
  1228.             else
  1229.                 WriteRequest -> io_StopBits = 1;
  1230.  
  1231.             if(Status & ST_READ7)
  1232.                 WriteRequest -> io_ReadLen = 7;
  1233.             else
  1234.                 WriteRequest -> io_ReadLen = 8;
  1235.  
  1236.             if(Status & ST_WRITE7)
  1237.                 WriteRequest -> io_WriteLen = 7;
  1238.             else
  1239.                 WriteRequest -> io_WriteLen = 8;
  1240.  
  1241.             DoIO(WriteRequest);
  1242.  
  1243.             ReadRequest -> io_SerFlags    = WriteRequest -> io_SerFlags;
  1244.             ReadRequest -> io_ExtFlags    = WriteRequest -> io_ExtFlags;
  1245.  
  1246.             ReadRequest -> io_StopBits    = WriteRequest -> io_StopBits;
  1247.             ReadRequest -> io_ReadLen    = WriteRequest -> io_ReadLen;
  1248.             ReadRequest -> io_WriteLen    = WriteRequest -> io_WriteLen;
  1249.         }
  1250.  
  1251.         return(Return);
  1252.     }
  1253.     else
  1254.         return(-1);
  1255. }
  1256.  
  1257.     /* xpr_ffirst(UBYTE *Buffer,UBYTE *Pattern):
  1258.      *
  1259.      *    Batch file upload: find the first matching file and return
  1260.      *    its name.
  1261.      */
  1262.  
  1263. LONG __saveds __asm
  1264. xpr_ffirst(register __a0 UBYTE *Buffer,register __a1 UBYTE *Pattern)
  1265. {
  1266.     if(MultipleFiles)
  1267.     {
  1268.         FileCount = 0;
  1269.  
  1270.         strcpy(Buffer,FileArg[FileCount++] . wa_Name);
  1271.  
  1272.         return(1);
  1273.     }
  1274.     else
  1275.     {
  1276.         FileMatch = TRUE;
  1277.  
  1278.         if(!MatchFirst(Pattern,FileAnchor))
  1279.         {
  1280.             if(FileAnchor -> ap_Info . fib_DirEntryType < 0)
  1281.             {
  1282.                 strcpy(Buffer,FileAnchor -> ap_Info . fib_FileName);
  1283.  
  1284.                 return(1);
  1285.             }
  1286.             else
  1287.             {
  1288.                 while(!MatchNext(FileAnchor))
  1289.                 {
  1290.                     if(FileAnchor -> ap_Info . fib_DirEntryType < 0)
  1291.                     {
  1292.                         strcpy(Buffer,FileAnchor -> ap_Info . fib_FileName);
  1293.  
  1294.                         return(1);
  1295.                     }
  1296.                 }
  1297.             }
  1298.         }
  1299.     }
  1300.  
  1301.     return(0);
  1302. }
  1303.  
  1304.     /* xpr_fnext(LONG OldState,UBYTE *Buffer,UBYTE *Pattern):
  1305.      *
  1306.      *    Batch file upload: find the next matching file
  1307.      *    - if any - and return its name.
  1308.      */
  1309.  
  1310. LONG __saveds __asm
  1311. xpr_fnext(register __d0 LONG OldState,register __a0 UBYTE *Buffer,register __a1 UBYTE *Pattern)
  1312. {
  1313.     if(MultipleFiles)
  1314.     {
  1315.         if(FileCount < FileCountMax)
  1316.         {
  1317.             strcpy(Buffer,FileArg[FileCount++] . wa_Name);
  1318.  
  1319.             return(1);
  1320.         }
  1321.     }
  1322.     else
  1323.     {
  1324.         FileMatch = TRUE;
  1325.  
  1326.         while(!MatchNext(FileAnchor))
  1327.         {
  1328.             if(FileAnchor -> ap_Info . fib_DirEntryType < 0)
  1329.             {
  1330.                 strcpy(Buffer,FileAnchor -> ap_Info . fib_FileName);
  1331.  
  1332.                 return(1);
  1333.             }
  1334.         }
  1335.     }
  1336.  
  1337.     return(0);
  1338. }
  1339.  
  1340.     /* xpr_finfo(UBYTE *FileName,LONG InfoType):
  1341.      *
  1342.      *    Return information on a given file.
  1343.      */
  1344.  
  1345. LONG __saveds __asm
  1346. xpr_finfo(register __a0 UBYTE *FileName,register __d0 LONG InfoType)
  1347. {
  1348.     BPTR FileLock;
  1349.  
  1350.     switch(InfoType)
  1351.     {
  1352.         case 1:    if(Config . OverridePath && !Uploading)
  1353.             {
  1354.                 if(!DownloadPath)
  1355.                 {
  1356.                     if(!Config . BinaryDownloadPath[0])
  1357.                     {
  1358.                         if(!GetCurrentDirName(RealName,256))
  1359.                             RealName[0] = 0;
  1360.                     }
  1361.                     else
  1362.                         strcpy(RealName,Config . BinaryDownloadPath);
  1363.                 }
  1364.                 else
  1365.                 {
  1366.                     if(!DownloadPath[0])
  1367.                     {
  1368.                         if(!GetCurrentDirName(RealName,256))
  1369.                             RealName[0] = 0;
  1370.                     }
  1371.                     else
  1372.                         strcpy(RealName,DownloadPath);
  1373.                 }
  1374.  
  1375.                 if(AddPart(RealName,FilePart(FileName),256))
  1376.                     FileName = RealName;
  1377.             }
  1378.  
  1379.             if(FileLock = Lock(FileName,ACCESS_READ))
  1380.             {
  1381.                 struct FileInfoBlock __aligned    FileInfo;
  1382.                 register LONG            Size;
  1383.  
  1384.                 if(Examine(FileLock,&FileInfo))
  1385.                     Size = FileInfo . fib_Size;
  1386.                 else
  1387.                     Size = 0;
  1388.  
  1389.                 UnLock(FileLock);
  1390.  
  1391.                 return(Size);
  1392.             }
  1393.  
  1394.             break;
  1395.  
  1396.         case 2:    return(BinaryTransfer ? 1 : 2);
  1397.     }
  1398.  
  1399.     return(0);
  1400. }
  1401.  
  1402.     /* The following routines are to support the xpr_options function. */
  1403.  
  1404. STATIC BYTE __regargs
  1405. GetOptionMode(struct xpr_option *Option)
  1406. {
  1407.     if(Option)
  1408.     {
  1409.         if(!Stricmp(Option -> xpro_value,"OFF"))
  1410.             return(FALSE);
  1411.  
  1412.         if(!Stricmp(Option -> xpro_value,"FALSE"))
  1413.             return(FALSE);
  1414.  
  1415.         if(!Stricmp(Option -> xpro_value,"F"))
  1416.             return(FALSE);
  1417.  
  1418.         if(!Stricmp(Option -> xpro_value,"NO"))
  1419.             return(FALSE);
  1420.  
  1421.         if(!Stricmp(Option -> xpro_value,"N"))
  1422.             return(FALSE);
  1423.  
  1424.  
  1425.         if(!Stricmp(Option -> xpro_value,"ON"))
  1426.             return(TRUE);
  1427.  
  1428.         if(!Stricmp(Option -> xpro_value,"TRUE"))
  1429.             return(TRUE);
  1430.  
  1431.         if(!Stricmp(Option -> xpro_value,"T"))
  1432.             return(TRUE);
  1433.  
  1434.         if(!Stricmp(Option -> xpro_value,"YES"))
  1435.             return(TRUE);
  1436.  
  1437.         if(!Stricmp(Option -> xpro_value,"Y"))
  1438.             return(TRUE);
  1439.     }
  1440.  
  1441.     return(FALSE);
  1442. }
  1443.  
  1444. STATIC struct Gadget *
  1445. CreateAllOptionGadgets(LONG *Count,LONG NumOpts,struct xpr_option *Opts[],struct Gadget *GadgetArray[],struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge)
  1446. {
  1447.     struct Gadget        *Gadget;
  1448.     struct NewGadget     NewGadget;
  1449.     LONG             i,MaxLength = 0,MaxLength1 = 0,MaxWidth,MaxWidth1,Len,NumOptsSmall;
  1450.     BYTE             WrapIt = FALSE;
  1451.  
  1452.     SZ_SizeSetup(Screen,&UserFont,TRUE);
  1453.  
  1454.     memset(&NewGadget,0,sizeof(struct NewGadget));
  1455.  
  1456.     *Count = 0;
  1457.  
  1458.     SZ_ResetMaxWidth();
  1459.  
  1460.     if(Gadget = CreateContext(GadgetList))
  1461.     {
  1462.         NewGadget . ng_TextAttr        = &UserFont;
  1463.         NewGadget . ng_VisualInfo    = VisualInfo;
  1464.         NewGadget . ng_Flags        = NG_HIGHLABEL;
  1465.  
  1466.             /* Precalculate gadget left edge offset. */
  1467.  
  1468.         if((NumOptsSmall = NumOpts) > OPTION_WRAP)
  1469.             NumOptsSmall = OPTION_WRAP;
  1470.  
  1471.         for(i = 0 ; i < NumOptsSmall ; i++)
  1472.         {
  1473.             if(Opts[i])
  1474.             {
  1475.                 switch(Opts[i] -> xpro_type)
  1476.                 {
  1477.                     case XPRO_BOOLEAN:
  1478.  
  1479.                         if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength)
  1480.                             MaxLength = Len;
  1481.  
  1482.                         SZ_UpdateMaxWidth(CHECKBOX_KIND,NULL,0,NULL);
  1483.  
  1484.                         break;
  1485.  
  1486.                     case XPRO_HEADER:
  1487.  
  1488.                         if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength)
  1489.                             MaxLength = Len;
  1490.  
  1491.                         break;
  1492.  
  1493.                     case XPRO_LONG:
  1494.                     case XPRO_STRING:
  1495.                     case XPRO_COMMPAR:
  1496.  
  1497.                         if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength)
  1498.                             MaxLength = Len;
  1499.  
  1500.                         SZ_UpdateMaxWidth(STRING_KIND,NULL,20,NULL);
  1501.  
  1502.                         break;
  1503.  
  1504.                     case XPRO_COMMAND:
  1505.  
  1506.                         SZ_UpdateMaxWidth(TEXT_KIND,Opts[i] -> xpro_description,0,NULL);
  1507.  
  1508.                         break;
  1509.  
  1510.                     default:
  1511.  
  1512.                         break;
  1513.                 }
  1514.             }
  1515.         }
  1516.  
  1517.         MaxWidth = SZ_ResetMaxWidth();
  1518.  
  1519.         SZ_AddLeftOffset(MaxLength + INTERWIDTH);
  1520.  
  1521.         for(i = OPTION_WRAP ; i < NumOpts ; i++)
  1522.         {
  1523.             if(Opts[i])
  1524.             {
  1525.                 switch(Opts[i] -> xpro_type)
  1526.                 {
  1527.                     case XPRO_BOOLEAN:
  1528.  
  1529.                         if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength1)
  1530.                             MaxLength1 = Len;
  1531.  
  1532.                         SZ_UpdateMaxWidth(CHECKBOX_KIND,NULL,0,NULL);
  1533.  
  1534.                         break;
  1535.  
  1536.                     case XPRO_HEADER:
  1537.  
  1538.                         if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength1)
  1539.                             MaxLength1 = Len;
  1540.  
  1541.                         break;
  1542.  
  1543.                     case XPRO_LONG:
  1544.                     case XPRO_STRING:
  1545.                     case XPRO_COMMPAR:
  1546.  
  1547.                         if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength1)
  1548.                             MaxLength1 = Len;
  1549.  
  1550.                         SZ_UpdateMaxWidth(STRING_KIND,NULL,20,NULL);
  1551.  
  1552.                         break;
  1553.  
  1554.                     case XPRO_COMMAND:
  1555.  
  1556.                         SZ_UpdateMaxWidth(TEXT_KIND,Opts[i] -> xpro_description,0,NULL);
  1557.  
  1558.                         break;
  1559.  
  1560.                     default:
  1561.  
  1562.                         break;
  1563.                 }
  1564.             }
  1565.         }
  1566.  
  1567.         MaxWidth1 = SZ_ResetMaxWidth();
  1568.  
  1569.         SZ_SetWidth(MaxWidth);
  1570.  
  1571.         for(i = 0 ; i < NumOpts ; i++)
  1572.         {
  1573.             if(i == OPTION_WRAP + 1)
  1574.                 WrapIt = TRUE;
  1575.  
  1576.             if(!Opts[i])
  1577.                 continue;
  1578.  
  1579.             if(WrapIt)
  1580.             {
  1581.                 SZ_SetWidth(MaxWidth1);
  1582.                 SZ_AddLeftOffset(MaxLength1 + INTERWIDTH);
  1583.             }
  1584.  
  1585.             switch(Opts[i] -> xpro_type)
  1586.             {
  1587.                 case XPRO_BOOLEAN:
  1588.  
  1589.                     NewGadget . ng_GadgetText    = Opts[i] -> xpro_description;
  1590.                     NewGadget . ng_GadgetID        = i;
  1591.  
  1592.                     GadgetArray[i] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget,
  1593.                         SZ_Adjust,    TRUE,
  1594.                         SZ_AutoWidth,    TRUE,
  1595.                         SZ_NewColumn,    WrapIt,
  1596.  
  1597.                         GTCB_Checked,    GetOptionMode(Opts[i]),
  1598.                     TAG_DONE);
  1599.  
  1600.                     break;
  1601.  
  1602.                 case XPRO_LONG:
  1603.  
  1604.                     NewGadget . ng_GadgetText    = Opts[i] -> xpro_description;
  1605.                     NewGadget . ng_GadgetID        = i;
  1606.  
  1607.                     GadgetArray[i] = Gadget = CreateGadget(INTEGER_KIND,Gadget,&NewGadget,
  1608.                         SZ_Adjust,    TRUE,
  1609.                         SZ_AutoWidth,    TRUE,
  1610.                         SZ_NewColumn,    WrapIt,
  1611.  
  1612.                         GTIN_Number,    atol(Opts[i] -> xpro_value),
  1613.                         GTST_EditHook,    &CommandHook,
  1614.                         GA_Immediate,    TRUE,
  1615.                     TAG_DONE);
  1616.  
  1617.                     break;
  1618.  
  1619.                 case XPRO_STRING:
  1620.                 case XPRO_COMMPAR:
  1621.  
  1622.                     NewGadget . ng_GadgetText    = Opts[i] -> xpro_description;
  1623.                     NewGadget . ng_GadgetID        = i;
  1624.  
  1625.                     GadgetArray[i] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  1626.                         SZ_Adjust,    TRUE,
  1627.                         SZ_AutoWidth,    TRUE,
  1628.                         SZ_NewColumn,    WrapIt,
  1629.  
  1630.                         GTST_String,    Opts[i] -> xpro_value,
  1631.                         GTST_MaxChars,    Opts[i] -> xpro_length - 1,
  1632.                         GTST_EditHook,    &CommandHook,
  1633.                         GA_Immediate,    TRUE,
  1634.                     TAG_DONE);
  1635.  
  1636.                     break;
  1637.  
  1638.                 case XPRO_HEADER:
  1639.  
  1640.                     NewGadget . ng_GadgetText    = Opts[i] -> xpro_description,;
  1641.                     NewGadget . ng_GadgetID        = i;
  1642.                     NewGadget . ng_Flags        = NG_HIGHLABEL;
  1643.  
  1644.                     GadgetArray[i] = Gadget = CreateGadget(TEXT_KIND,Gadget,&NewGadget,
  1645.                         SZ_Adjust,    TRUE,
  1646.                         SZ_AutoWidth,    TRUE,
  1647.  
  1648.                         GTTX_Text,    " ",
  1649.                     TAG_DONE);
  1650.  
  1651.                     NewGadget . ng_Flags = 0;
  1652.  
  1653.                     break;
  1654.  
  1655.                 case XPRO_COMMAND:
  1656.  
  1657.                     NewGadget . ng_GadgetText    = Opts[i] -> xpro_description;
  1658.                     NewGadget . ng_GadgetID        = i;
  1659.  
  1660.                     GadgetArray[i] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1661.                         SZ_Adjust,    TRUE,
  1662.                         SZ_AutoWidth,    TRUE,
  1663.                     TAG_DONE);
  1664.  
  1665.                     break;
  1666.  
  1667.                 default:break;
  1668.             }
  1669.  
  1670.             WrapIt = FALSE;
  1671.         }
  1672.  
  1673.         SZ_ResetMaxWidth();
  1674.  
  1675.         SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_USE_GAD),0,NULL);
  1676.         SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_CANCEL_GAD),0,NULL);
  1677.  
  1678.         SZ_SetWidth(SZ_ResetMaxWidth());
  1679.  
  1680.         NewGadget . ng_GadgetText    = LocaleString(MSG_GLOBAL_USE_GAD);
  1681.         NewGadget . ng_GadgetID        = -1;
  1682.  
  1683.         GadgetArray[i++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1684.             SZ_AlignExtra,    TRUE,
  1685.             SZ_Adjust,    TRUE,
  1686.             SZ_AutoWidth,    TRUE,
  1687.             SZ_AlignLeft,    TRUE,
  1688.             SZ_AlignBottom,    TRUE,
  1689.  
  1690.             GT_Underscore,    '_',
  1691.         TAG_DONE);
  1692.  
  1693.         NewGadget . ng_GadgetText    = LocaleString(MSG_GLOBAL_CANCEL_GAD);
  1694.         NewGadget . ng_GadgetID        = -2;
  1695.  
  1696.         GadgetArray[i++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1697.             SZ_Adjust,    TRUE,
  1698.             SZ_AutoWidth,    TRUE,
  1699.             SZ_AlignRight,    TRUE,
  1700.  
  1701.             GT_Underscore,    '_',
  1702.         TAG_DONE);
  1703.  
  1704.         if(Gadget)
  1705.             *Count = i;
  1706.     }
  1707.  
  1708.     return(Gadget);
  1709. }
  1710.  
  1711.     /* xpr_options(LONG NumOpts,struct xpr_option **Opts):
  1712.      *
  1713.      *    Provide a more polished user interface to set the
  1714.      *    transfer protocol options.
  1715.      */
  1716.  
  1717. ULONG __saveds __asm
  1718. xpr_options(register __d0 LONG NumOpts,register __a0 struct xpr_option **Opts)
  1719. {
  1720.     struct Gadget    *GadgetList = NULL;
  1721.     struct Gadget    *GadgetArray[36];
  1722.     struct Window    *PanelWindow;
  1723.     LONG         i,Count;
  1724.  
  1725.     ULONG         Flags = 0;
  1726.  
  1727.     if(CreateAllOptionGadgets(&Count,NumOpts,Opts,&GadgetArray[0],&GadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
  1728.     {
  1729.         if(PanelWindow = OpenWindowTags(NULL,
  1730.             WA_Left,    (Screen -> Width    - SZ_GetWindowWidth())    / 2,
  1731.             WA_Top,        (Screen -> Height    - SZ_GetWindowHeight())    / 2,
  1732.             WA_Width,    SZ_GetWindowWidth(),
  1733.             WA_Height,    SZ_GetWindowHeight(),
  1734.  
  1735.             WA_Activate,    TRUE,
  1736.             WA_DragBar,    TRUE,
  1737.             WA_DepthGadget,    TRUE,
  1738.             WA_CloseGadget,    TRUE,
  1739.             WA_RMBTrap,    TRUE,
  1740.             WA_CustomScreen,Screen,
  1741.  
  1742.             WA_IDCMP,    IDCMP_GADGETDOWN | IDCMP_ACTIVEWINDOW | IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | CHECKBOXIDCMP | STRINGIDCMP | INTEGERIDCMP | BUTTONIDCMP,
  1743.  
  1744.             WA_Title,    OptionTitle ? OptionTitle : LocaleString(MSG_TERMXPR_TRANSFER_OPTIONS_TXT),
  1745.         TAG_DONE))
  1746.         {
  1747.             struct IntuiMessage    *Massage;
  1748.             ULONG             Class,Code;
  1749.             struct Gadget        *Gadget;
  1750.             BYTE             Terminated = FALSE,
  1751.                          CheckFlags = FALSE;
  1752.  
  1753.             PushWindow(PanelWindow);
  1754.  
  1755.             AddGList(PanelWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
  1756.             RefreshGList(GadgetList,PanelWindow,NULL,(UWORD)-1);
  1757.             GT_RefreshWindow(PanelWindow,NULL);
  1758.  
  1759.             ActiveGadget = NULL;
  1760.  
  1761.             while(!Terminated)
  1762.             {
  1763.                 WaitPort(PanelWindow -> UserPort);
  1764.  
  1765.                 while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> UserPort)))
  1766.                 {
  1767.                     Class    = Massage -> Class;
  1768.                     Code    = Massage -> Code;
  1769.                     Gadget    = (struct Gadget *)Massage -> IAddress;
  1770.  
  1771.                     GT_ReplyIMsg(Massage);
  1772.  
  1773.                     if(Class == IDCMP_VANILLAKEY)
  1774.                         KeySelect(GadgetArray,Count,Code,PanelWindow,&Gadget,&Class,&Code);
  1775.  
  1776.                     if(Class == IDCMP_GADGETDOWN)
  1777.                     {
  1778.                         if((Gadget -> GadgetType & GTYP_GTYPEMASK) == GTYP_STRGADGET)
  1779.                             ActiveGadget = Gadget;
  1780.                     }
  1781.  
  1782.                     if(Class == IDCMP_ACTIVEWINDOW && ActiveGadget)
  1783.                         ActivateGadget(ActiveGadget,PanelWindow,NULL);
  1784.  
  1785.                     if(Class == IDCMP_CLOSEWINDOW)
  1786.                         Terminated = TRUE;
  1787.  
  1788.                     if(Class == IDCMP_GADGETUP)
  1789.                     {
  1790.                         switch(Gadget -> GadgetID)
  1791.                         {
  1792.                             case -1:    Terminated = CheckFlags = TRUE;
  1793.                                     break;
  1794.  
  1795.                             case -2:    Terminated = TRUE;
  1796.                                     break;
  1797.  
  1798.                             default:    if(Gadget -> GadgetID < NumOpts)
  1799.                                     {
  1800.                                         if(Opts[Gadget -> GadgetID] -> xpro_type == XPRO_COMMAND)
  1801.                                         {
  1802.                                             Flags |= (1 << Gadget -> GadgetID);
  1803.  
  1804.                                             Terminated = CheckFlags = TRUE;
  1805.                                         }
  1806.                                     }
  1807.  
  1808.                                     break;
  1809.                         }
  1810.                     }
  1811.                 }
  1812.             }
  1813.  
  1814.             if(CheckFlags)
  1815.             {
  1816.                 for(i = 0 ; i < NumOpts ; i++)
  1817.                 {
  1818.                     switch(Opts[i] -> xpro_type)
  1819.                     {
  1820.                         case XPRO_BOOLEAN:    if(GT_CHECKED(GadgetArray[i]) != GetOptionMode(Opts[i]))
  1821.                                     {
  1822.                                         Flags |= (1 << i);
  1823.  
  1824.                                         if(GT_CHECKED(GadgetArray[i]))
  1825.                                             strcpy(Opts[i] -> xpro_value,"yes");
  1826.                                         else
  1827.                                             strcpy(Opts[i] -> xpro_value,"no");
  1828.  
  1829.                                         NewOptions = TRUE;
  1830.                                     }
  1831.  
  1832.                                     break;
  1833.  
  1834.                         case XPRO_COMMPAR:
  1835.                         case XPRO_LONG:
  1836.                         case XPRO_STRING:    if(strcmp(Opts[i] -> xpro_value,GT_STRING(GadgetArray[i])))
  1837.                                     {
  1838.                                         Flags |= (1 << i);
  1839.  
  1840.                                         strcpy(Opts[i] -> xpro_value,GT_STRING(GadgetArray[i]));
  1841.  
  1842.                                         NewOptions = TRUE;
  1843.                                     }
  1844.  
  1845.                                     break;
  1846.  
  1847.                         default:        break;
  1848.                     }
  1849.                 }
  1850.             }
  1851.             else
  1852.             {
  1853.                 NewOptions    = FALSE;
  1854.                 Flags        = NULL;
  1855.             }
  1856.  
  1857.             ActiveGadget = NULL;
  1858.  
  1859.             RemoveGList(PanelWindow,GadgetList,(UWORD)-1);
  1860.  
  1861.             PopWindow();
  1862.  
  1863.             CloseWindow(PanelWindow);
  1864.         }
  1865.     }
  1866.  
  1867.     FreeGadgets(GadgetList);
  1868.  
  1869.     return(Flags);
  1870. }
  1871.  
  1872.     /* xpr_unlink(UBYTE *FileName):
  1873.      *
  1874.      *    Remove (delete) a given file.
  1875.      */
  1876.  
  1877. LONG __saveds __asm
  1878. xpr_unlink(register __a0 UBYTE *FileName)
  1879. {
  1880.     LONG Success = DeleteFile(FileName) ? 0 : -1;
  1881.  
  1882.     if(Success)
  1883.         LogAction(LocaleString(MSG_TERMXPR_LOGMSG_DELETE_FILE_TXT),FileName);
  1884.  
  1885.     return(Success);
  1886. }
  1887.  
  1888.     /* xpr_squery():
  1889.      *
  1890.      *    Check how many characters are present in the serial buffer.
  1891.      */
  1892.  
  1893. LONG __saveds
  1894. xpr_squery()
  1895. {
  1896.     if(WriteRequest)
  1897.     {
  1898.         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  1899.  
  1900.         if(!DoIO(WriteRequest))
  1901.         {
  1902.                 /* Return error if carrier is lost. */
  1903.  
  1904.             if(Config . CheckCarrier && (WriteRequest -> io_Status & (1 << 5)))
  1905.             {
  1906.                 Online = FALSE;
  1907.  
  1908.                 return(-1);
  1909.             }
  1910.  
  1911.             return((LONG)WriteRequest -> IOSer . io_Actual);
  1912.         }
  1913.     }
  1914.  
  1915.     return(-1);
  1916. }
  1917.  
  1918.     /* xpr_getptr(LONG InfoType):
  1919.      *
  1920.      *    Return a pointer to the term custom screen.
  1921.      */
  1922.  
  1923. LONG __saveds __asm
  1924. xpr_getptr(register __d0 LONG InfoType)
  1925. {
  1926.     if(InfoType == 1)
  1927.         return((LONG)Screen);
  1928.     else
  1929.         return(-1);
  1930. }
  1931.  
  1932.     /* xpr_stealopts(UBYTE *Prompt,UBYTE *Buffer):
  1933.      *
  1934.      *    Steal the contents of the options buffer (replacement
  1935.      *    for xpr_gets).
  1936.      */
  1937.  
  1938. LONG __saveds __asm
  1939. xpr_stealopts(register __a0 UBYTE *Prompt,register __a1 UBYTE *Buffer)
  1940. {
  1941.     if(Buffer)
  1942.         strcpy(ProtocolOptsBuffer,Buffer);
  1943.  
  1944.     return(1);
  1945. }
  1946.  
  1947.     /* ProtocolSetup():
  1948.      *
  1949.      *    Set up the library and options for the external protocol.
  1950.      */
  1951.  
  1952. BYTE
  1953. ProtocolSetup()
  1954. {
  1955.     UBYTE NameBuffer[40],i;
  1956.  
  1957.         /* Close the old library if still open. */
  1958.  
  1959.     if(XProtocolBase)
  1960.     {
  1961.         XProtocolCleanup(XprIO);
  1962.  
  1963.         CloseLibrary(XProtocolBase);
  1964.     }
  1965.  
  1966.         /* Clear the XPR interface buffer. */
  1967.  
  1968.     memset(XprIO,0,sizeof(struct XPR_IO));
  1969.  
  1970.         /* Copy the name of the library. */
  1971.  
  1972.     strcpy(NameBuffer,FilePart(LastXprLibrary));
  1973.  
  1974.         /* Extract the name itself (strip the `.library'). */
  1975.  
  1976.     for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
  1977.     {
  1978.         if(NameBuffer[i] == '.')
  1979.         {
  1980.             NameBuffer[i] = 0;
  1981.             break;
  1982.         }
  1983.     }
  1984.  
  1985.         /* Check if the transfer protocol is a sort of ZModem. */
  1986.  
  1987.     UsesZModem = FALSE;
  1988.  
  1989.     for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  1990.     {
  1991.         if(!Stricmp(&NameBuffer[i],"zmodem"))
  1992.             UsesZModem = TRUE;
  1993.     }
  1994.  
  1995.         /* Obtain the protocol default settings. */
  1996.  
  1997.     if(!GetEnvDOS(NameBuffer,ProtocolOptsBuffer))
  1998.         ProtocolOptsBuffer[0] = 0;
  1999.  
  2000.         /* Initialize the interface structure. */
  2001.  
  2002.     XprIO -> xpr_filename    = ProtocolOptsBuffer;
  2003.     XprIO -> xpr_fopen    = (APTR)xpr_fopen;
  2004.     XprIO -> xpr_fclose    = (APTR)xpr_fclose;
  2005.     XprIO -> xpr_fread    = (APTR)xpr_fread;
  2006.     XprIO -> xpr_fwrite    = (APTR)xpr_fwrite;
  2007.     XprIO -> xpr_sread    = (APTR)xpr_sread;
  2008.     XprIO -> xpr_swrite    = (APTR)xpr_swrite;
  2009.     XprIO -> xpr_sflush    = (APTR)xpr_sflush;
  2010.     XprIO -> xpr_update    = (APTR)xpr_update;
  2011.     XprIO -> xpr_chkabort    = (APTR)xpr_chkabort;
  2012.     XprIO -> xpr_gets    = (APTR)xpr_gets;
  2013.     XprIO -> xpr_setserial    = (APTR)xpr_setserial;
  2014.     XprIO -> xpr_ffirst    = (APTR)xpr_ffirst;
  2015.     XprIO -> xpr_fnext    = (APTR)xpr_fnext;
  2016.     XprIO -> xpr_finfo    = (APTR)xpr_finfo;
  2017.     XprIO -> xpr_fseek    = (APTR)xpr_fseek;
  2018.     XprIO -> xpr_extension    = 4;
  2019.     XprIO -> xpr_options    = (APTR)xpr_options;
  2020.     XprIO -> xpr_unlink    = (APTR)xpr_unlink;
  2021.     XprIO -> xpr_squery    = (APTR)xpr_squery;
  2022.     XprIO -> xpr_getptr    = (APTR)xpr_getptr;
  2023.  
  2024.         /* Try to open the library. */
  2025.  
  2026.     if(XProtocolBase = (struct Library *)OpenLibrary(LastXprLibrary,0))
  2027.     {
  2028.             /* Set up the library. */
  2029.  
  2030.         TransferBits = XProtocolSetup(XprIO);
  2031.  
  2032.             /* Successful initialization? */
  2033.  
  2034.         if(!(TransferBits & XPRS_SUCCESS))
  2035.         {
  2036.             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
  2037.  
  2038.             CloseLibrary(XProtocolBase);
  2039.  
  2040.             XProtocolBase = NULL;
  2041.  
  2042.             LastXprLibrary[0] = 0;
  2043.  
  2044.             TransferBits = 0;
  2045.  
  2046.             return(FALSE);
  2047.         }
  2048.  
  2049.         if(TransferBits & XPRS_HOSTNOWAIT)
  2050.         {
  2051.             if(!HostReadBuffer)
  2052.                 HostReadBuffer = AllocVec(Config . SerBuffSize,MEMF_ANY);
  2053.         }
  2054.         else
  2055.         {
  2056.             if(HostReadBuffer)
  2057.             {
  2058.                 FreeVec(HostReadBuffer);
  2059.  
  2060.                 HostReadBuffer = NULL;
  2061.             }
  2062.         }
  2063.     }
  2064.     else
  2065.         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_OPEN_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
  2066.  
  2067.     return(TRUE);
  2068. }
  2069.  
  2070.     /* SaveProtocolOpts():
  2071.      *
  2072.      *    Save the current protocol settings to an environment variable.
  2073.      */
  2074.  
  2075. VOID
  2076. SaveProtocolOpts()
  2077. {
  2078.         /* It's time to save the altered options. */
  2079.  
  2080.     if(NewOptions && XProtocolBase)
  2081.     {
  2082.         UBYTE NameBuffer[40],i;
  2083.  
  2084.             /* Strip the `.library' part. */
  2085.  
  2086.         strcpy(NameBuffer,FilePart(LastXprLibrary));
  2087.  
  2088.         for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
  2089.         {
  2090.             if(NameBuffer[i] == '.')
  2091.             {
  2092.                 NameBuffer[i] = 0;
  2093.                 break;
  2094.             }
  2095.         }
  2096.  
  2097.             /* Cause the xpr.library to prompt for
  2098.              * input. We expect the library to fill
  2099.              * the prompt string with the default
  2100.              * settings. The resulting string is
  2101.              * intercepted by xpr_stealopts, saved
  2102.              * to an environment variable and will
  2103.              * serve as a reinitialization string
  2104.              * later.
  2105.              */
  2106.  
  2107.         XprIO -> xpr_filename    = NULL;
  2108.         XprIO -> xpr_gets    = (APTR)xpr_stealopts;
  2109.         XprIO -> xpr_extension    = 4;
  2110.         XprIO -> xpr_options    = (APTR)NULL;
  2111.  
  2112.         XProtocolSetup(XprIO);
  2113.  
  2114.             /* Save the options in case anything goes
  2115.              * wrong.
  2116.              */
  2117.  
  2118.         NewOptions = FALSE;
  2119.  
  2120.         SetEnvDOS(NameBuffer,ProtocolOptsBuffer);
  2121.  
  2122.             /* Reinitialize the library. */
  2123.  
  2124.         XprIO -> xpr_filename    = ProtocolOptsBuffer;
  2125.         XprIO -> xpr_gets    = (APTR)xpr_gets;
  2126.         XprIO -> xpr_extension    = 4;
  2127.         XprIO -> xpr_options    = (APTR)xpr_options;
  2128.  
  2129.         XProtocolSetup(XprIO);
  2130.     }
  2131. }
  2132.  
  2133.     /* SelectProtocol(UBYTE *Name,struct Window *ParentWindow):
  2134.      *
  2135.      *    Select a different transfer protocol library using
  2136.      *    the asl.library file requester.
  2137.      */
  2138.  
  2139. BYTE
  2140. SelectProtocol(UBYTE *Name,struct Window *ParentWindow)
  2141. {
  2142.     struct FileRequester    *AslFileRequest;
  2143.     UBYTE            *File;
  2144.     BYTE             UseNewLibrary = FALSE;
  2145.  
  2146.     File = Name;
  2147.  
  2148.     if(FilePart(File) == File)
  2149.         strcpy(SharedBuffer,"Libs:");
  2150.     else
  2151.     {
  2152.         UBYTE *Temp;
  2153.  
  2154.         strcpy(SharedBuffer,File);
  2155.  
  2156.         Temp = PathPart(SharedBuffer);
  2157.  
  2158.         Temp[0] = 0;
  2159.  
  2160.         File = FilePart(File);
  2161.     }
  2162.  
  2163.     if(AslFileRequest = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest,
  2164.         ASL_Window,    ParentWindow,
  2165.         ASL_File,    File,
  2166.         ASL_Dir,    SharedBuffer,
  2167.         ASL_Hail,    LocaleString(MSG_TERMXPR_SELECT_TRANSFER_PROTOCOL_TXT),
  2168.         ASL_FuncFlags,    FILF_NEWIDCMP,
  2169.         ASL_Pattern,    "xpr#?.library",
  2170.         ASL_OKText,    LocaleString(MSG_GLOBAL_SELECT_TXT),
  2171.     TAG_END))
  2172.     {
  2173.         if(AslRequestTags(AslFileRequest,TAG_DONE))
  2174.         {
  2175.             if(AslFileRequest -> rf_File[0])
  2176.             {
  2177.                 if(Stricmp("Libs:",AslFileRequest -> rf_Dir))
  2178.                 {
  2179.                     strcpy(SharedBuffer,AslFileRequest -> rf_Dir);
  2180.  
  2181.                     if(!AddPart(SharedBuffer,AslFileRequest -> rf_File,256))
  2182.                         strcpy(SharedBuffer,AslFileRequest -> rf_File);
  2183.                 }
  2184.                 else
  2185.                     strcpy(SharedBuffer,AslFileRequest -> rf_File);
  2186.  
  2187.                 if(SharedBuffer[0] && Stricmp(SharedBuffer,Name))
  2188.                 {
  2189.                     strcpy(LastXprLibrary,SharedBuffer);
  2190.  
  2191.                     UseNewLibrary = TRUE;
  2192.                 }
  2193.             }
  2194.         }
  2195.  
  2196.         FreeAslRequest(AslFileRequest);
  2197.     }
  2198.  
  2199.     return(UseNewLibrary);
  2200. }
  2201.