home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 500-599 / ff589.lza / Term / TermSrc.lha / termXPR.c < prev    next >
C/C++ Source or Header  |  1991-12-10  |  43KB  |  1,933 lines

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