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

  1. /*
  2. **    Transfer.c
  3. **
  4. **    File transfer routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #ifndef _GLOBAL_H
  11. #include "Global.h"
  12. #endif
  13.  
  14.     /* The action strings to display. */
  15.  
  16. STATIC STRPTR    SendQuery[3],
  17.         ReceiveQuery[3],
  18.         TransferTypes[3];
  19.  
  20.     /* CreateArgName(STRPTR String):
  21.      *
  22.      *    Create another node based upon a string given.
  23.      *    Encloses parameters in quotes if necessary and
  24.      *    `escapes' quotes.
  25.      */
  26.  
  27. STATIC struct Node *
  28. CreateArgName(STRPTR String)
  29. {
  30.     struct Node    *Node;
  31.     STRPTR         Index = String;
  32.     LONG         Len,NewLen;
  33.     BOOL      Quotes = FALSE;
  34.  
  35.     Len = NewLen = strlen(String);
  36.  
  37.     while(*Index)
  38.     {
  39.         if(*Index == '\"')
  40.             NewLen++;
  41.  
  42.         if(*Index == ' ' && !Quotes)
  43.         {
  44.             NewLen += 2;
  45.  
  46.             Quotes = TRUE;
  47.         }
  48.  
  49.         Index++;
  50.     }
  51.  
  52.     if(!Len)
  53.     {
  54.         NewLen += 2;
  55.  
  56.         Quotes = TRUE;
  57.     }
  58.  
  59.     if(NewLen > Len)
  60.     {
  61.         if(Node = (struct Node *)AllocVecPooled(sizeof(struct Node) + NewLen + 1,MEMF_ANY))
  62.         {
  63.             STRPTR Dest;
  64.  
  65.             Node -> ln_Name = (STRPTR)(Node + 1);
  66.  
  67.             Dest    = Node -> ln_Name;
  68.             Index    = String;
  69.  
  70.             if(Quotes)
  71.                 *Dest++ = '\"';
  72.  
  73.             while(*Index)
  74.             {
  75.                 if(*Index == '\"')
  76.                     *Dest++ = '*';
  77.  
  78.                 *Dest++ = *Index++;
  79.             }
  80.  
  81.             if(Quotes)
  82.                 *Dest++ = '\"';
  83.  
  84.             *Dest = 0;
  85.         }
  86.     }
  87.     else
  88.     {
  89.         if(Node = (struct Node *)AllocVecPooled(sizeof(struct Node) + Len + 1,MEMF_ANY))
  90.             strcpy(Node -> ln_Name = (STRPTR)(Node + 1),String);
  91.     }
  92.  
  93.     return(Node);
  94. }
  95.  
  96.     /* BuildString():
  97.      *
  98.      *    Build a command line based upon a template and
  99.      *    existing file transfer info.
  100.      */
  101.  
  102. STATIC STRPTR
  103. BuildString(STRPTR Source,STRPTR From,STRPTR To,BYTE Type,BOOL ReceiveMode,STRPTR SingleFile,struct FileTransferInfo *Info,LONG *Error)
  104. {
  105.     struct List    *List;
  106.     STRPTR         Result = NULL;
  107.  
  108.     if(Info)
  109.     {
  110.         if(Info -> FileList . mlh_Head -> mln_Succ)
  111.             Info -> CurrentFile = (struct FileTransferNode *)Info -> FileList . mlh_Head;
  112.         else
  113.             Info = NULL;
  114.     }
  115.  
  116.     *Error = 0;
  117.  
  118.     if(List = CreateList())
  119.     {
  120.         struct Node        *Node;
  121.         UBYTE             LocalBuffer[MAX_FILENAME_LENGTH],
  122.                      TempBuffer[MAX_FILENAME_LENGTH];
  123.         STRPTR             Index = Source,
  124.                      Dest = LocalBuffer;
  125.         struct FileRequester    *FileRequest;
  126.  
  127.         while(*Index && !(*Error))
  128.         {
  129.             if(*Index == '%')
  130.             {
  131.                 struct Node    *InsertHere = List -> lh_TailPred;
  132.                 BOOL      InsertBefore = TRUE;
  133.  
  134.                 Index++;
  135.  
  136.                 if(!(*Index))
  137.                 {
  138.                     *Dest = 0;
  139.  
  140.                     if(LocalBuffer[0])
  141.                     {
  142.                         if(Node = CreateNode(LocalBuffer))
  143.                         {
  144.                             AddTail(List,Node);
  145.  
  146.                             LocalBuffer[0] = 0;
  147.                         }
  148.                         else
  149.                             *Error = ERR_NO_MEM;
  150.                     }
  151.  
  152.                     break;
  153.                 }
  154.  
  155.                 switch(*Index)
  156.                 {
  157.                     case 'f':
  158.  
  159.                         if(SingleFile)
  160.                         {
  161.                             if(Node = CreateArgName(SingleFile))
  162.                                 AddTail(List,Node);
  163.                             else
  164.                                 *Error = ERR_NO_MEM;
  165.  
  166.                             SingleFile = NULL;
  167.  
  168.                             break;
  169.                         }
  170.  
  171.                         if(Info)
  172.                         {
  173.                             if(Node = CreateArgName(Info -> CurrentFile -> Name))
  174.                                 AddTail(List,Node);
  175.                             else
  176.                                 *Error = ERR_NO_MEM;
  177.  
  178.                             if(Info -> CurrentFile -> Node . mln_Succ)
  179.                                 Info -> CurrentFile = (struct FileTransferNode *)Info -> CurrentFile -> Node . mln_Succ;
  180.                             else
  181.                                 Info = NULL;
  182.  
  183.                             break;
  184.                         }
  185.  
  186.                         LT_LockWindow(Window);
  187.  
  188.                         if(ReceiveMode)
  189.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),To,"",TempBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE);
  190.                         else
  191.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),From,"",TempBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),FALSE);
  192.  
  193.                         if(FileRequest)
  194.                         {
  195.                             if(Node = CreateArgName(TempBuffer))
  196.                                 AddTail(List,Node);
  197.                             else
  198.                                 *Error = ERR_NO_MEM;
  199.  
  200.                             FreeAslRequest(FileRequest);
  201.                         }
  202.                         else
  203.                             *Error = ERR_ABORTED;
  204.  
  205.                         LT_UnlockWindow(Window);
  206.  
  207.                         break;
  208.  
  209.                     case 'F':
  210.  
  211.                         if(SingleFile)
  212.                         {
  213.                             if(Node = CreateArgName(FilePart(SingleFile)))
  214.                                 AddTail(List,Node);
  215.                             else
  216.                                 *Error = ERR_NO_MEM;
  217.  
  218.                             SingleFile = NULL;
  219.  
  220.                             break;
  221.                         }
  222.  
  223.                         if(Info)
  224.                         {
  225.                             if(Node = CreateArgName(FilePart(Info -> CurrentFile -> Name)))
  226.                                 AddTail(List,Node);
  227.                             else
  228.                                 *Error = ERR_NO_MEM;
  229.  
  230.                             if(Info -> CurrentFile -> Node . mln_Succ)
  231.                                 Info -> CurrentFile = (struct FileTransferNode *)Info -> CurrentFile -> Node . mln_Succ;
  232.                             else
  233.                                 Info = NULL;
  234.  
  235.                             break;
  236.                         }
  237.  
  238.                         LT_LockWindow(Window);
  239.  
  240.                         if(ReceiveMode)
  241.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),To,"",TempBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE);
  242.                         else
  243.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),From,"",TempBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),FALSE);
  244.  
  245.                         if(FileRequest)
  246.                         {
  247.                             if(Node = CreateArgName(FilePart(TempBuffer)))
  248.                                 AddTail(List,Node);
  249.                             else
  250.                                 *Error = ERR_NO_MEM;
  251.  
  252.                             FreeAslRequest(FileRequest);
  253.                         }
  254.                         else
  255.                             *Error = ERR_ABORTED;
  256.  
  257.                         LT_UnlockWindow(Window);
  258.  
  259.                         break;
  260.  
  261.                     case 'm':
  262.  
  263.                         if(SingleFile)
  264.                         {
  265.                             if(Node = CreateArgName(SingleFile))
  266.                                 AddTail(List,Node);
  267.                             else
  268.                                 *Error = ERR_NO_MEM;
  269.  
  270.                             SingleFile = NULL;
  271.  
  272.                             break;
  273.                         }
  274.  
  275.                         if(Info)
  276.                         {
  277.                             struct FileTransferNode *SomeNode = Info -> CurrentFile;
  278.  
  279.                             while(SomeNode -> Node . mln_Succ && !(*Error))
  280.                             {
  281.                                 if(Node = CreateArgName(SomeNode -> Name))
  282.                                     AddTail(List,Node);
  283.                                 else
  284.                                     *Error = ERR_NO_MEM;
  285.  
  286.                                 SomeNode = (struct FileTransferNode *)SomeNode -> Node . mln_Succ;
  287.                             }
  288.  
  289.                             Info = NULL;
  290.  
  291.                             break;
  292.                         }
  293.  
  294.                         LT_LockWindow(Window);
  295.  
  296.                         TempBuffer[0] = 0;
  297.  
  298.                         if(ReceiveMode)
  299.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),To,"",TempBuffer,NULL,TRUE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE);
  300.                         else
  301.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),From,"",TempBuffer,NULL,FALSE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),FALSE);
  302.  
  303.                         LT_UnlockWindow(Window);
  304.  
  305.                         if(FileRequest)
  306.                         {
  307.                             LONG i;
  308.  
  309.                             if(TempBuffer[0] && FileRequest -> fr_NumArgs == 1)
  310.                             {
  311.                                 if(Node = CreateArgName(TempBuffer))
  312.                                 {
  313.                                     AddTail(List,Node);
  314.  
  315.                                     break;
  316.                                 }
  317.                                 else
  318.                                     *Error = ERR_NO_MEM;
  319.                             }
  320.  
  321.                             for(i = 0 ; i < FileRequest -> fr_NumArgs && !(*Error) ; i++)
  322.                             {
  323.                                 if(FileRequest -> fr_ArgList[i] . wa_Lock)
  324.                                 {
  325.                                     if(NameFromLock(FileRequest -> fr_ArgList[i] . wa_Lock,TempBuffer,MAX_FILENAME_LENGTH))
  326.                                     {
  327.                                         if(AddPart(TempBuffer,FileRequest -> fr_ArgList[i] . wa_Name,MAX_FILENAME_LENGTH))
  328.                                         {
  329.                                             if(Node = CreateArgName(TempBuffer))
  330.                                                 AddTail(List,Node);
  331.                                             else
  332.                                                 *Error = ERR_NO_MEM;
  333.                                         }
  334.                                         else
  335.                                             *Error = IoErr();
  336.                                     }
  337.                                     else
  338.                                         *Error = IoErr();
  339.                                 }
  340.                                 else
  341.                                 {
  342.                                     strcpy(TempBuffer,FileRequest -> fr_Drawer);
  343.  
  344.                                     if(AddPart(TempBuffer,FileRequest -> fr_ArgList[i] . wa_Name,MAX_FILENAME_LENGTH))
  345.                                     {
  346.                                         if(Node = CreateArgName(TempBuffer))
  347.                                             AddTail(List,Node);
  348.                                         else
  349.                                             *Error = ERR_NO_MEM;
  350.                                     }
  351.                                     else
  352.                                         *Error = IoErr();
  353.                                 }
  354.                             }
  355.  
  356.                             FreeAslRequest(FileRequest);
  357.                         }
  358.                         else
  359.                             *Error = ERR_ABORTED;
  360.  
  361.                         break;
  362.  
  363.                     case 'M':
  364.  
  365.                         if(SingleFile)
  366.                         {
  367.                             if(Node = CreateArgName(FilePart(SingleFile)))
  368.                                 AddTail(List,Node);
  369.                             else
  370.                                 *Error = ERR_NO_MEM;
  371.  
  372.                             SingleFile = NULL;
  373.  
  374.                             break;
  375.                         }
  376.  
  377.                         if(Info)
  378.                         {
  379.                             struct FileTransferNode *SomeNode = Info -> CurrentFile;
  380.  
  381.                             while(SomeNode -> Node . mln_Succ && !(*Error))
  382.                             {
  383.                                 if(Node = CreateArgName(FilePart(SomeNode -> Name)))
  384.                                     AddTail(List,Node);
  385.                                 else
  386.                                     *Error = ERR_NO_MEM;
  387.  
  388.                                 SomeNode = (struct FileTransferNode *)SomeNode -> Node . mln_Succ;
  389.                             }
  390.  
  391.                             Info = NULL;
  392.  
  393.                             break;
  394.                         }
  395.  
  396.                         LT_LockWindow(Window);
  397.  
  398.                         TempBuffer[0] = 0;
  399.  
  400.                         if(ReceiveMode)
  401.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),To,"",TempBuffer,NULL,TRUE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE);
  402.                         else
  403.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),From,"",TempBuffer,NULL,FALSE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),FALSE);
  404.  
  405.                         LT_UnlockWindow(Window);
  406.  
  407.                         if(FileRequest)
  408.                         {
  409.                             LONG i;
  410.  
  411.                             if(TempBuffer[0] && FileRequest -> fr_NumArgs == 1)
  412.                             {
  413.                                 if(Node = CreateArgName(FilePart(TempBuffer)))
  414.                                 {
  415.                                     AddTail(List,Node);
  416.  
  417.                                     break;
  418.                                 }
  419.                                 else
  420.                                     *Error = ERR_NO_MEM;
  421.                             }
  422.  
  423.                             for(i = 0 ; i < FileRequest -> fr_NumArgs && !(*Error) ; i++)
  424.                             {
  425.                                 if(FileRequest -> fr_ArgList[i] . wa_Lock)
  426.                                 {
  427.                                     if(AddPart(TempBuffer,FileRequest -> fr_ArgList[i] . wa_Name,MAX_FILENAME_LENGTH))
  428.                                     {
  429.                                         if(Node = CreateArgName(TempBuffer))
  430.                                             AddTail(List,Node);
  431.                                         else
  432.                                             *Error = ERR_NO_MEM;
  433.                                     }
  434.                                     else
  435.                                         *Error = IoErr();
  436.                                 }
  437.                                 else
  438.                                 {
  439.                                     if(Node = CreateArgName(FileRequest -> fr_ArgList[i] . wa_Name))
  440.                                         AddTail(List,Node);
  441.                                     else
  442.                                         *Error = ERR_NO_MEM;
  443.                                 }
  444.                             }
  445.  
  446.                             FreeAslRequest(FileRequest);
  447.                         }
  448.                         else
  449.                             *Error = ERR_ABORTED;
  450.  
  451.                         break;
  452.  
  453.                     case 'b':
  454.                     case 'B':
  455.  
  456.                         SPrintf(SharedBuffer,"%ld",Config -> SerialConfig -> BaudRate);
  457.  
  458.                         if(Node = CreateNode(SharedBuffer))
  459.                             AddTail(List,Node);
  460.                         else
  461.                             *Error = ERR_NO_MEM;
  462.  
  463.                         break;
  464.  
  465.                     case 'c':
  466.                     case 'C':
  467.  
  468.                         SPrintf(SharedBuffer,"%ld",DTERate ? DTERate : Config -> SerialConfig -> BaudRate);
  469.  
  470.                         if(Node = CreateNode(SharedBuffer))
  471.                             AddTail(List,Node);
  472.                         else
  473.                             *Error = ERR_NO_MEM;
  474.  
  475.                         break;
  476.  
  477.                     case 'p':
  478.                     case 'P':
  479.  
  480.                         if(Node = CreateArgName(RexxPortName))
  481.                             AddTail(List,Node);
  482.                         else
  483.                             *Error = ERR_NO_MEM;
  484.  
  485.                         break;
  486.  
  487.                     case 'd':
  488.                     case 'D':
  489.  
  490.                         if(Node = CreateArgName(Config -> SerialConfig -> SerialDevice))
  491.                             AddTail(List,Node);
  492.                         else
  493.                             *Error = ERR_NO_MEM;
  494.  
  495.                         break;
  496.  
  497.                     case 'u':
  498.                     case 'U':
  499.  
  500.                         SPrintf(SharedBuffer,"%ld",Config -> SerialConfig -> UnitNumber);
  501.  
  502.                         if(Node = CreateNode(SharedBuffer))
  503.                             AddTail(List,Node);
  504.                         else
  505.                             *Error = ERR_NO_MEM;
  506.  
  507.                         break;
  508.  
  509.                     case '<':
  510.  
  511.                         if(Node = CreateArgName(From))
  512.                             AddTail(List,Node);
  513.                         else
  514.                             *Error = ERR_NO_MEM;
  515.  
  516.                         break;
  517.  
  518.                     case '>':
  519.  
  520.                         if(Node = CreateArgName(To))
  521.                             AddTail(List,Node);
  522.                         else
  523.                             *Error = ERR_NO_MEM;
  524.  
  525.                         break;
  526.  
  527.                     case 's':
  528.                     case 'S':
  529.  
  530.                         if(!GetPubScreenName(Window -> WScreen,SharedBuffer))
  531.                             SharedBuffer[0] = 0;
  532.  
  533.                         if(Node = CreateArgName(SharedBuffer))
  534.                             AddTail(List,Node);
  535.                         else
  536.                             *Error = ERR_NO_MEM;
  537.  
  538.                         break;
  539.  
  540.                     default:
  541.  
  542.                         *Dest = *Index;
  543.  
  544.                         InsertBefore = FALSE;
  545.  
  546.                         break;
  547.                 }
  548.  
  549.                 if(InsertBefore && Node)
  550.                 {
  551.                     struct Node *OtherNode;
  552.  
  553.                     *Dest = 0;
  554.  
  555.                     if(LocalBuffer[0])
  556.                     {
  557.                         if(OtherNode = CreateNode(LocalBuffer))
  558.                         {
  559.                             Insert(List,OtherNode,InsertHere);
  560.  
  561.                             LocalBuffer[0] = 0;
  562.                         }
  563.                         else
  564.                             *Error = ERR_NO_MEM;
  565.                     }
  566.  
  567.                     Dest = LocalBuffer;
  568.                 }
  569.             }
  570.             else
  571.                 *Dest++ = *Index;
  572.  
  573.             Index++;
  574.         }
  575.  
  576.         *Dest = 0;
  577.  
  578.         if(LocalBuffer[0] && !(*Error))
  579.         {
  580.             if(Node = CreateNode(LocalBuffer))
  581.                 AddTail(List,Node);
  582.             else
  583.                 *Error = ERR_NO_MEM;
  584.         }
  585.  
  586.         if(!(*Error))
  587.         {
  588.             if(List -> lh_Head -> ln_Succ)
  589.             {
  590.                 LONG Total = 0,Len;
  591.  
  592.                 for(Node = List -> lh_Head ; Node -> ln_Succ ; Node = Node -> ln_Succ)
  593.                     Total += strlen(Node -> ln_Name) + 1;
  594.  
  595.                 if(Result = (STRPTR)AllocVecPooled(Total,MEMF_ANY))
  596.                 {
  597.                     STRPTR Buffer = Result;
  598.  
  599.                     for(Node = List -> lh_Head ; Node -> ln_Succ ; Node = Node -> ln_Succ)
  600.                     {
  601.                         Len = strlen(Node -> ln_Name);
  602.  
  603.                         CopyMem(Node -> ln_Name,Buffer,Len);
  604.  
  605.                         Buffer += Len;
  606.  
  607.                         *Buffer++ = ' ';
  608.                     }
  609.  
  610.                     Buffer[-1] = 0;
  611.                 }
  612.             }
  613.             else
  614.                 Result = "";
  615.         }
  616.  
  617.         DeleteList(List);
  618.     }
  619.     else
  620.         *Error = ERR_NO_MEM;
  621.  
  622.     return(Result);
  623. }
  624.  
  625.     /* ReplaceName(STRPTR Original):
  626.      *
  627.      *    Replace a filename with a mangled version for
  628.      *    file uploads.
  629.      */
  630.  
  631. STATIC STRPTR
  632. ReplaceName(STRPTR Source)
  633. {
  634.     if(Config -> TransferConfig -> MangleFileNames)
  635.     {
  636.         UBYTE LocalName[MAX_FILENAME_LENGTH],*Char;
  637.  
  638.         strcpy(OriginalName,Source);
  639.  
  640.         ShrinkName(FilePart(Source),LocalName,12,TRUE);
  641.  
  642.         strcpy(ShrunkenName,Source);
  643.  
  644.         Char = PathPart(ShrunkenName);
  645.  
  646.         *Char = 0;
  647.  
  648.         AddPart(ShrunkenName,LocalName,MAX_FILENAME_LENGTH);
  649.  
  650.         return(ShrunkenName);
  651.     }
  652.     else
  653.     {
  654.         OriginalName[0] = 0;
  655.  
  656.         return(Source);
  657.     }
  658. }
  659.  
  660.     /* FreeFileTransferInfo(struct FileTransferInfo *Info):
  661.      *
  662.      *    Free a file transfer info list as allocated
  663.      *    by AllocFileTransferInfo() and AddFileTransferNode().
  664.      */
  665.  
  666. VOID
  667. FreeFileTransferInfo(struct FileTransferInfo *Info)
  668. {
  669.     if(Info)
  670.     {
  671.         struct FileTransferNode *Node,
  672.                     *Next;
  673.  
  674.         Node = (struct FileTransferNode *)Info -> FileList . mlh_Head;
  675.  
  676.         while(Next = (struct FileTransferNode *)Node -> Node . mln_Succ)
  677.         {
  678.             FreeVecPooled(Node);
  679.  
  680.             Node = Next;
  681.         }
  682.  
  683.         FreeVecPooled(Info);
  684.     }
  685. }
  686.  
  687.     /* AllocFileTransferInfo():
  688.      *
  689.      *    Allocate a FileTransferInfo structure for use with
  690.      *    AddFileTransferNode().
  691.      */
  692.  
  693. struct FileTransferInfo *
  694. AllocFileTransferInfo()
  695. {
  696.     struct FileTransferInfo *Info;
  697.  
  698.     if(Info = (struct FileTransferInfo *)AllocVecPooled(sizeof(struct FileTransferInfo),MEMF_ANY | MEMF_CLEAR))
  699.     {
  700.         NewList((struct List *)&Info -> FileList);
  701.  
  702.         return(Info);
  703.     }
  704.  
  705.     return(NULL);
  706. }
  707.  
  708.     /* AddFileTransferNode(struct FileTransferInfo *Info,STRPTR Name,ULONG Size):
  709.      *
  710.      *    Allocate a file transfer information node.
  711.      */
  712.  
  713. BOOL
  714. AddFileTransferNode(struct FileTransferInfo *Info,STRPTR Name,ULONG Size)
  715. {
  716.     struct FileTransferNode *Node;
  717.     LONG             Len = strlen(Name) + 1;
  718.  
  719.     if(Node = (struct FileTransferNode *)AllocVecPooled(sizeof(struct FileTransferNode) + Len,MEMF_ANY))
  720.     {
  721.         Node -> Size    = Size;
  722.         Node -> Name    = (STRPTR)(Node + 1);
  723.  
  724.         strcpy(Node -> Name,Name);
  725.  
  726.         AddTail((struct List *)&Info -> FileList,(struct Node *)Node);
  727.  
  728.         Info -> TotalSize += Size;
  729.  
  730.         Info -> TotalFiles++;
  731.  
  732.         return(TRUE);
  733.     }
  734.     else
  735.         return(FALSE);
  736. }
  737.  
  738.     /* TransferCompare(struct FileTransferNode **A,struct FileTransferNode **B):
  739.      *
  740.      *    Local subroutine required by QuickSort().
  741.      */
  742.  
  743. STATIC LONG __stdargs
  744. TransferCompare(struct FileTransferNode **A,struct FileTransferNode **B)
  745. {
  746.     return(Strcoll(FilePart((*A) -> Name),FilePart((*B) -> Name)));
  747. }
  748.  
  749.     /* SortFileTransferInfo(struct FileTransferInfo *Info):
  750.      *
  751.      *    Sorts the file transfer information list in ascending
  752.      *    order, but makes sure that the files are sorted
  753.      *    in descending order (i.e. the larger files come
  754.      *    first and files of equal size are sorted
  755.      *    lexically).
  756.      */
  757.  
  758. VOID
  759. SortFileTransferInfo(struct FileTransferInfo *Info)
  760. {
  761.     if(Info -> TotalFiles > 1)
  762.     {
  763.         struct FileTransferNode **NodeList;
  764.  
  765.         if(NodeList = (struct FileTransferNode **)AllocVecPooled(sizeof(struct FileTransferNode *) * Info -> TotalFiles,MEMF_ANY))
  766.         {
  767.             struct FileTransferNode *Node;
  768.             LONG             i = 0;
  769.  
  770.             for(Node = (struct FileTransferNode *)Info -> FileList . mlh_Head ; Node -> Node . mln_Succ ; Node = (struct FileTransferNode *)Node -> Node . mln_Succ)
  771.                 NodeList[i++] = Node;
  772.  
  773.             QuickSort((APTR)NodeList,Info -> TotalFiles,sizeof(struct FileTransferNode *),TransferCompare);
  774.  
  775.             NewList((struct List *)&Info -> FileList);
  776.  
  777.             for(i = 0 ; i < Info -> TotalFiles ; i++)
  778.                 AddTail((struct List *)&Info -> FileList,(struct Node *)&NodeList[i] -> Node);
  779.  
  780.             FreeVecPooled(NodeList);
  781.         }
  782.     }
  783.  
  784.     Info -> DoneSize    = 0;
  785.     Info -> DoneFiles    = 0;
  786.  
  787.     Info -> CurrentFile    = (struct FileTransferNode *)Info -> FileList . mlh_Head;
  788.     Info -> CurrentSize    = Info -> CurrentFile -> Size;
  789. }
  790.  
  791.     /* BuildFileTransferInfo(struct FileRequester *FileRequester):
  792.      *
  793.      *    Build a file transfer information list from
  794.      *    information provided by a FileRequester structure.
  795.      */
  796.  
  797. struct FileTransferInfo *
  798. BuildFileTransferInfo(struct FileRequester *FileRequester)
  799. {
  800.     struct FileTransferInfo *Info;
  801.     LONG             FilesFound = 0;
  802.  
  803.     if(Info = AllocFileTransferInfo())
  804.     {
  805.         BOOL    Success = FALSE;
  806.         BPTR    NewLock,
  807.             OldLock;
  808.  
  809.         if(NewLock = Lock(FileRequester -> fr_Drawer,ACCESS_READ))
  810.         {
  811.             OldLock = CurrentDir(NewLock);
  812.  
  813.             if(FileRequester -> fr_NumArgs)
  814.             {
  815.                 struct FileInfoBlock *FileInfo;
  816.  
  817.                 if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  818.                 {
  819.                     BPTR         FileLock;
  820.                     struct WBArg    *ArgList = FileRequester -> fr_ArgList;
  821.                     LONG         i;
  822.  
  823.                     Success = TRUE;
  824.  
  825.                     for(i = 0 ; Success && i < FileRequester -> fr_NumArgs ; i++)
  826.                     {
  827.                         if(ArgList[i] . wa_Name)
  828.                         {
  829.                             if(ArgList[i] . wa_Lock)
  830.                             {
  831.                                 CurrentDir(ArgList[i] . wa_Lock);
  832.  
  833.                                 if(FileLock = Lock(ArgList[i] . wa_Name,ACCESS_READ))
  834.                                 {
  835.                                     if(Examine(FileLock,FileInfo))
  836.                                     {
  837.                                         if(FileInfo -> fib_DirEntryType < 0)
  838.                                         {
  839.                                             if(NameFromLock(FileLock,SharedBuffer,512))
  840.                                             {
  841.                                                 if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  842.                                                     Success = FALSE;
  843.                                                 else
  844.                                                     FilesFound++;
  845.                                             }
  846.                                         }
  847.                                     }
  848.  
  849.                                     UnLock(FileLock);
  850.                                 }
  851.  
  852.                                 CurrentDir(NewLock);
  853.                             }
  854.                             else
  855.                             {
  856.                                 if(FileLock = Lock(ArgList[i] . wa_Name,ACCESS_READ))
  857.                                 {
  858.                                     if(Examine(FileLock,FileInfo))
  859.                                     {
  860.                                         if(FileInfo -> fib_DirEntryType < 0)
  861.                                         {
  862.                                             if(NameFromLock(FileLock,SharedBuffer,512))
  863.                                             {
  864.                                                 if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  865.                                                     Success = FALSE;
  866.                                                 else
  867.                                                     FilesFound++;
  868.                                             }
  869.                                         }
  870.                                     }
  871.  
  872.                                     UnLock(FileLock);
  873.                                 }
  874.                             }
  875.                         }
  876.                     }
  877.                 }
  878.  
  879.                 FreeDosObject(DOS_FIB,FileInfo);
  880.             }
  881.             else
  882.             {
  883.                 struct AnchorPath *Anchor;
  884.  
  885.                 STRPTR FileName;
  886.  
  887.                 if(FileRequester -> fr_NumArgs > 1 && FileRequester -> fr_ArgList)
  888.                     FileName = FileRequester -> fr_ArgList -> wa_Name;
  889.                 else
  890.                     FileName = FileRequester -> fr_File;
  891.  
  892.                 if(Anchor = (struct AnchorPath *)AllocVecPooled(sizeof(struct AnchorPath),MEMF_ANY | MEMF_CLEAR))
  893.                 {
  894.                     if(!MatchFirst(FileName,Anchor))
  895.                     {
  896.                         Success = TRUE;
  897.  
  898.                         if(Anchor -> ap_Info . fib_DirEntryType < 0)
  899.                         {
  900.                             if(NameFromLock(NewLock,SharedBuffer,512))
  901.                             {
  902.                                 if(AddPart(SharedBuffer,Anchor -> ap_Info . fib_FileName,512))
  903.                                 {
  904.                                     if(!AddFileTransferNode(Info,SharedBuffer,Anchor -> ap_Info . fib_Size))
  905.                                         Success = FALSE;
  906.                                     else
  907.                                         FilesFound++;
  908.                                 }
  909.                             }
  910.                         }
  911.  
  912.                         if(Success)
  913.                         {
  914.                             while(!MatchNext(Anchor))
  915.                             {
  916.                                 if(NameFromLock(NewLock,SharedBuffer,512))
  917.                                 {
  918.                                     if(AddPart(SharedBuffer,Anchor -> ap_Info . fib_FileName,512))
  919.                                     {
  920.                                         if(!AddFileTransferNode(Info,SharedBuffer,Anchor -> ap_Info . fib_Size))
  921.                                         {
  922.                                             Success = FALSE;
  923.  
  924.                                             break;
  925.                                         }
  926.                                         else
  927.                                             FilesFound++;
  928.                                     }
  929.                                 }
  930.                             }
  931.                         }
  932.  
  933.                         if(IoErr() != ERROR_NO_MORE_ENTRIES)
  934.                             Success = FALSE;
  935.                     }
  936.  
  937.                     MatchEnd(Anchor);
  938.  
  939.                     FreeVecPooled(Anchor);
  940.                 }
  941.             }
  942.  
  943.             CurrentDir(OldLock);
  944.  
  945.             UnLock(NewLock);
  946.         }
  947.  
  948.         if(Success && FilesFound)
  949.         {
  950.             SortFileTransferInfo(Info);
  951.  
  952.             return(Info);
  953.         }
  954.         else
  955.             FreeFileTransferInfo(Info);
  956.     }
  957.  
  958.     return(NULL);
  959. }
  960.  
  961.     /* SendTextFile(STRPTR TheFile):
  962.      *
  963.      *    Send a single text file via xpr.
  964.      */
  965.  
  966. VOID
  967. SendTextFile(LONG Type,STRPTR TheFile)
  968. {
  969.     STRPTR    From,To,Name;
  970.     LONG    Mode;
  971.  
  972.     TheFile = ReplaceName(TheFile);
  973.  
  974.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> ASCIIUploadType == XFER_INTERNAL)
  975.     {
  976.         InternalASCIIUpload(TheFile,TRUE);
  977.  
  978.         return;
  979.     }
  980.  
  981.     switch(Type)
  982.     {
  983.         case TRANSFER_BINARY:
  984.  
  985.             Name    = Config -> TransferConfig -> BinaryUploadLibrary;
  986.             Mode    = Config -> TransferConfig -> BinaryUploadType;
  987.             From    = Config -> PathConfig -> BinaryUploadPath;
  988.             To    = Config -> PathConfig -> BinaryDownloadPath;
  989.             break;
  990.  
  991.         case TRANSFER_TEXT:
  992.  
  993.             Name    = Config -> TransferConfig -> TextUploadLibrary;
  994.             Mode    = Config -> TransferConfig -> TextUploadType;
  995.             From    = Config -> PathConfig -> TextUploadPath;
  996.             To    = Config -> PathConfig -> TextDownloadPath;
  997.             break;
  998.  
  999.         case TRANSFER_ASCII:
  1000.  
  1001.             Name    = Config -> TransferConfig -> ASCIIUploadLibrary;
  1002.             Mode    = Config -> TransferConfig -> ASCIIUploadType;
  1003.             From    = Config -> PathConfig -> ASCIIUploadPath;
  1004.             To    = Config -> PathConfig -> ASCIIDownloadPath;
  1005.             break;
  1006.     }
  1007.  
  1008.     if(Mode == XFER_DEFAULT && Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  1009.     {
  1010.         Name    = Config -> TransferConfig -> DefaultLibrary;
  1011.         Mode    = XFER_EXTERNALPROGRAM;
  1012.     }
  1013.  
  1014.     if(Mode == XFER_EXTERNALPROGRAM)
  1015.     {
  1016.         STRPTR    String;
  1017.         LONG    Error;
  1018.  
  1019.         BlockWindows();
  1020.  
  1021.         if(String = BuildString(Name,From,To,Type,FALSE,TheFile,NULL,&Error))
  1022.         {
  1023.             ClearSerial();
  1024.  
  1025.             LaunchCommand(String);
  1026.  
  1027.             RestartSerial();
  1028.  
  1029.             FreeVecPooled(String);
  1030.         }
  1031.  
  1032.         ReleaseWindows();
  1033.     }
  1034.     else
  1035.     {
  1036.         BYTE OldStatus = Status;
  1037.         BPTR NewDir,OldDir;
  1038.  
  1039.         if(Type == TRANSFER_ASCII)
  1040.             NewDir = Lock(Config -> PathConfig -> ASCIIUploadPath,ACCESS_READ);
  1041.         else
  1042.             NewDir = Lock(Config -> PathConfig -> TextUploadPath,ACCESS_READ);
  1043.  
  1044.         if(NewDir)
  1045.             OldDir = CurrentDir(NewDir);
  1046.         else
  1047.             OldDir = NULL;
  1048.  
  1049.         Uploading = TRUE;
  1050.  
  1051.         LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
  1052.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  1053.  
  1054.             /* If not initialized, try to set up a new
  1055.              * external transfer protocol.
  1056.              */
  1057.  
  1058.         if(!XProtocolBase)
  1059.         {
  1060.             if(SelectProtocol(LastXprLibrary,Window))
  1061.             {
  1062.                 if(ProtocolSetup(FALSE))
  1063.                     SaveProtocolOpts();
  1064.             }
  1065.         }
  1066.  
  1067.         if(XProtocolBase)
  1068.         {
  1069.             SetTransferMenu(TRUE);
  1070.  
  1071.             XprIO -> xpr_filename = TheFile;
  1072.  
  1073.             if(TransferPanel(SendQuery[TRANSFER_TEXT]))
  1074.             {
  1075.                 Status = STATUS_UPLOAD;
  1076.  
  1077.                 ClearSerial();
  1078.  
  1079.                 LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[TRANSFER_TEXT]);
  1080.  
  1081.                 if(ReadRequest && WriteRequest)
  1082.                 {
  1083.                     if(XProtocolSend(XprIO))
  1084.                         TransferFailed = FALSE;
  1085.                     else
  1086.                         TransferFailed = TRUE;
  1087.                 }
  1088.                 else
  1089.                     TransferFailed = TRUE;
  1090.  
  1091.                 if(TransferFailed || TransferAborted)
  1092.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1093.                 else
  1094.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1095.  
  1096.                 if(TransferFailed || TransferError)
  1097.                 {
  1098.                     if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1099.                         WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1100.  
  1101.                     DeleteTransferPanel(TRUE);
  1102.                 }
  1103.                 else
  1104.                 {
  1105.                     if(TransferWindow)
  1106.                     {
  1107.                         if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1108.                             WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1109.  
  1110.                         DelayTime(2,0);
  1111.                     }
  1112.  
  1113.                     DeleteTransferPanel(FALSE);
  1114.                 }
  1115.  
  1116.                 Status = OldStatus;
  1117.  
  1118.                 RestartSerial();
  1119.             }
  1120.         }
  1121.         else
  1122.             SetTransferMenu(TRUE);
  1123.  
  1124.         if(OldDir)
  1125.             CurrentDir(OldDir);
  1126.  
  1127.         if(NewDir)
  1128.             UnLock(NewDir);
  1129.  
  1130.         if(SendAbort && UsesZModem)
  1131.             SerWrite(ZModemCancel,20);
  1132.  
  1133.         SendAbort = FALSE;
  1134.  
  1135.         Uploading = FALSE;
  1136.  
  1137.         if(Config -> CommandConfig -> UploadMacro[0])
  1138.             SerialCommand(Config -> CommandConfig -> UploadMacro);
  1139.  
  1140.         DidTransfer = FALSE;
  1141.     }
  1142. }
  1143.  
  1144.     /* StartXprReceive():
  1145.      *
  1146.      *    Receive files via xpr.
  1147.      */
  1148.  
  1149. VOID
  1150. StartXprReceive(LONG Type,STRPTR Name,BOOL WaitForIt)
  1151. {
  1152.     STRPTR    From,To,Cmd;
  1153.     LONG    Mode;
  1154.  
  1155.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> ASCIIDownloadType == XFER_INTERNAL)
  1156.     {
  1157.         InternalASCIIDownload(Name,WaitForIt);
  1158.  
  1159.         return;
  1160.     }
  1161.  
  1162.     switch(Type)
  1163.     {
  1164.         case TRANSFER_BINARY:
  1165.  
  1166.             Cmd    = Config -> TransferConfig -> BinaryDownloadLibrary;
  1167.             Mode    = Config -> TransferConfig -> BinaryDownloadType;
  1168.             From    = Config -> PathConfig -> BinaryUploadPath;
  1169.             To    = Config -> PathConfig -> BinaryDownloadPath;
  1170.             break;
  1171.  
  1172.         case TRANSFER_TEXT:
  1173.  
  1174.             Cmd    = Config -> TransferConfig -> TextDownloadLibrary;
  1175.             Mode    = Config -> TransferConfig -> TextDownloadType;
  1176.             From    = Config -> PathConfig -> TextUploadPath;
  1177.             To    = Config -> PathConfig -> TextDownloadPath;
  1178.             break;
  1179.  
  1180.         case TRANSFER_ASCII:
  1181.  
  1182.             Cmd    = Config -> TransferConfig -> ASCIIDownloadLibrary;
  1183.             Mode    = Config -> TransferConfig -> ASCIIDownloadType;
  1184.             From    = Config -> PathConfig -> ASCIIUploadPath;
  1185.             To    = Config -> PathConfig -> ASCIIDownloadPath;
  1186.             break;
  1187.     }
  1188.  
  1189.     if(Mode == XFER_DEFAULT && Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  1190.     {
  1191.         Cmd    = Config -> TransferConfig -> DefaultLibrary;
  1192.         Mode    = XFER_EXTERNALPROGRAM;
  1193.     }
  1194.  
  1195.     if(Mode == XFER_EXTERNALPROGRAM)
  1196.     {
  1197.         STRPTR    String;
  1198.         LONG    Error;
  1199.  
  1200.         BlockWindows();
  1201.  
  1202.         if(String = BuildString(Cmd,From,To,Type,TRUE,Name,NULL,&Error))
  1203.         {
  1204.             ClearSerial();
  1205.  
  1206.             LaunchCommand(String);
  1207.  
  1208.             RestartSerial();
  1209.  
  1210.             FreeVecPooled(String);
  1211.         }
  1212.  
  1213.         ReleaseWindows();
  1214.     }
  1215.     else
  1216.     {
  1217.         struct FileRequester    *FileRequest;
  1218.         UBYTE             DummyBuffer[MAX_FILENAME_LENGTH];
  1219.         BYTE             OldStatus = Status;
  1220.         BPTR             NewDir = NULL,
  1221.                      OldDir = NULL;
  1222.  
  1223.         DB(kprintf("[ receiver\n"));
  1224.         DB(kprintf("[ cleargenericlist\n"));
  1225.  
  1226.         ClearGenericList(GenericListTable[GLIST_DOWNLOAD]);
  1227.  
  1228.         LocalizeString(ReceiveQuery,MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT,MSG_TERMTRANSFER_DOWNLOAD_ASCII_TXT);
  1229.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  1230.  
  1231.             /* Select the download path. */
  1232.  
  1233.         switch(Type)
  1234.         {
  1235.             case TRANSFER_BINARY:
  1236.  
  1237.                 DownloadPath = Config -> PathConfig -> BinaryDownloadPath;
  1238.                 break;
  1239.  
  1240.             case TRANSFER_TEXT:
  1241.  
  1242.                 DownloadPath = Config -> PathConfig -> TextDownloadPath;
  1243.                 break;
  1244.  
  1245.             case TRANSFER_ASCII:
  1246.  
  1247.                 DownloadPath = Config -> PathConfig -> ASCIIDownloadPath;
  1248.                 break;
  1249.         }
  1250.  
  1251.         DB(kprintf("[ doing path\n"));
  1252.  
  1253.         if(DownloadPath[0])
  1254.         {
  1255.             if(NewDir = Lock(DownloadPath,ACCESS_READ))
  1256.                 OldDir = CurrentDir(NewDir);
  1257.         }
  1258.  
  1259.         DB(kprintf("[ blockwindows\n"));
  1260.         BlockWindows();
  1261.  
  1262.             /* Set up the library if necessary. */
  1263.  
  1264.         if(!XProtocolBase)
  1265.         {
  1266.             DB(kprintf("[ selectprotocol\n"));
  1267.             if(SelectProtocol(LastXprLibrary,Window))
  1268.             {
  1269.                 DB(kprintf("[ protocolsetup\n"));
  1270.                 if(ProtocolSetup(FALSE))
  1271.                     SaveProtocolOpts();
  1272.             }
  1273.         }
  1274.  
  1275.         if(XProtocolBase)
  1276.         {
  1277.             DB(kprintf("[ settransfermenu"));
  1278.             SetTransferMenu(TRUE);
  1279.  
  1280.                 /* Do we need to ask the user for
  1281.                  * the destination file name?
  1282.                  */
  1283.  
  1284.             if(TransferBits & XPRS_NORECREQ)
  1285.             {
  1286.                 DB(kprintf("[ no filerequester\n"));
  1287.  
  1288.                     /* Obviously not, let's open
  1289.                      * the transfer info window as
  1290.                      * usual and download the file(s).
  1291.                      */
  1292.  
  1293.                 DB(kprintf("[ transferpanel\n"));
  1294.                 if(TransferPanel(ReceiveQuery[Type]))
  1295.                 {
  1296.                     Status = STATUS_DOWNLOAD;
  1297.  
  1298.                     DB(kprintf("[ clearserial\n"));
  1299.                     ClearSerial();
  1300.  
  1301.                     LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_DOWNLOAD_TXT),TransferTypes[Type]);
  1302.  
  1303.                         /* Receive the data. */
  1304.  
  1305.                     if(ReadRequest && WriteRequest)
  1306.                     {
  1307.                         DB(kprintf("[ going in\n"));
  1308.                         if(XProtocolReceive(XprIO))
  1309.                             TransferFailed = FALSE;
  1310.                         else
  1311.                             TransferFailed = TRUE;
  1312.                     }
  1313.                     else
  1314.                         TransferFailed = TRUE;
  1315.  
  1316.                         /* In case the transfer has been aborted,
  1317.                          * flush the input buffer of dirty data.
  1318.                          */
  1319.  
  1320.                     if(TransferAborted)
  1321.                     {
  1322.                         DB(kprintf("[ xpr_sflush()\n"));
  1323.                         xpr_sflush();
  1324.                     }
  1325.  
  1326.                     if(TransferAborted || TransferFailed)
  1327.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1328.                     else
  1329.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1330.  
  1331.                     if(TransferFailed || TransferError)
  1332.                     {
  1333.                         DB(kprintf("[ wakeup\n"));
  1334.                         if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1335.                             WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1336.  
  1337.                         DB(kprintf("[ deletetransferpanel %ld\n",WaitForIt));
  1338.                         DeleteTransferPanel(WaitForIt);
  1339.                     }
  1340.                     else
  1341.                     {
  1342.                         if(TransferWindow)
  1343.                         {
  1344.                             DB(kprintf("[ wakeup\n"));
  1345.                             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1346.                                 WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1347.  
  1348.                             DB(kprintf("[ waittime\n"));
  1349.                             DelayTime(2,0);
  1350.                         }
  1351.  
  1352.                         DB(kprintf("[ deletetransferpanel false\n"));
  1353.                         DeleteTransferPanel(FALSE);
  1354.                     }
  1355.  
  1356.                     Status = OldStatus;
  1357.  
  1358.                         /* Queue another read request. */
  1359.  
  1360.                     DB(kprintf("[ restartserial\n"));
  1361.                     RestartSerial();
  1362.                 }
  1363.             }
  1364.             else
  1365.             {
  1366.                 if(!Name)
  1367.                 {
  1368.                     if(FileRequest = GetFile(Window,ReceiveQuery[Type],DownloadPath,"",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE))
  1369.                     {
  1370.                             /* Save the download path. */
  1371.  
  1372.                         strcpy(DownloadPath,FileRequest -> fr_Drawer);
  1373.  
  1374.                         ConfigChanged = TRUE;
  1375.  
  1376.                             /* Install the name of the file to receive. */
  1377.  
  1378.                         XprIO -> xpr_filename = DummyBuffer;
  1379.  
  1380.                         FreeAslRequest(FileRequest);
  1381.  
  1382.                         Name = DummyBuffer;
  1383.                     }
  1384.                 }
  1385.                 else
  1386.                 {
  1387.                     STRPTR Index;
  1388.  
  1389.                     strcpy(DownloadPath,Name);
  1390.  
  1391.                     ConfigChanged = TRUE;
  1392.  
  1393.                     Index = PathPart(DownloadPath);
  1394.  
  1395.                     *Index = 0;
  1396.  
  1397.                     XprIO -> xpr_filename = Name;
  1398.                 }
  1399.  
  1400.                     /* Download the file(s). */
  1401.  
  1402.                 if(Name)
  1403.                 {
  1404.                         /* Open the transfer panel. */
  1405.  
  1406.                     if(TransferPanel(ReceiveQuery[Type]))
  1407.                     {
  1408.                         Status = STATUS_DOWNLOAD;
  1409.  
  1410.                         ClearSerial();
  1411.  
  1412.                         LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_DOWNLOAD_TXT),TransferTypes[Type]);
  1413.  
  1414.                             /* Receive the file. */
  1415.  
  1416.                         if(ReadRequest && WriteRequest)
  1417.                         {
  1418.                             if(XProtocolReceive(XprIO))
  1419.                                 TransferFailed = FALSE;
  1420.                             else
  1421.                                 TransferFailed = TRUE;
  1422.                         }
  1423.                         else
  1424.                             TransferFailed = TRUE;
  1425.  
  1426.                             /* In case the transfer has been aborted,
  1427.                              * flush the input buffer of dirty data.
  1428.                              */
  1429.  
  1430.                         if(TransferAborted)
  1431.                             xpr_sflush();
  1432.  
  1433.                         if(TransferAborted || TransferFailed)
  1434.                             Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1435.                         else
  1436.                             Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1437.  
  1438.                         if(TransferFailed || TransferError)
  1439.                         {
  1440.                             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1441.                                 WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1442.  
  1443.                             DeleteTransferPanel(WaitForIt);
  1444.                         }
  1445.                         else
  1446.                         {
  1447.                             if(TransferWindow)
  1448.                             {
  1449.                                 if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1450.                                     WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1451.  
  1452.                                 DelayTime(2,0);
  1453.                             }
  1454.  
  1455.                             DeleteTransferPanel(FALSE);
  1456.                         }
  1457.  
  1458.                         Status = OldStatus;
  1459.  
  1460.                             /* Queue another read
  1461.                              * request.
  1462.                              */
  1463.  
  1464.                         RestartSerial();
  1465.                     }
  1466.                 }
  1467.             }
  1468.         }
  1469.         else
  1470.             SetTransferMenu(TRUE);
  1471.  
  1472.         DB(kprintf("[ olddir\n"));
  1473.         if(OldDir)
  1474.             CurrentDir(OldDir);
  1475.  
  1476.         DB(kprintf("[ newdir\n"));
  1477.         if(NewDir)
  1478.             UnLock(NewDir);
  1479.  
  1480.         DB(kprintf("[ zmodemcancel\n"));
  1481.         if(SendAbort && UsesZModem)
  1482.             SerWrite(ZModemCancel,20);
  1483.  
  1484.         SendAbort = FALSE;
  1485.  
  1486.         DB(kprintf("[ releasewindows\n"));
  1487.         ReleaseWindows();
  1488.  
  1489.         DownloadPath = NULL;
  1490.  
  1491.         DidTransfer = FALSE;
  1492.  
  1493.         if(WaitForIt)
  1494.         {
  1495.             DB(kprintf("[ downloadmacro\n"));
  1496.             if(Config -> CommandConfig -> DownloadMacro[0])
  1497.                 SerialCommand(Config -> CommandConfig -> DownloadMacro);
  1498.         }
  1499.  
  1500.         DB(kprintf("[ finished.\n"));
  1501.     }
  1502. }
  1503.  
  1504.     /* StartXprSend():
  1505.      *
  1506.      *    Send files via xpr.
  1507.      */
  1508.  
  1509. BOOL
  1510. StartXprSend(LONG Type,BOOL WaitForIt)
  1511. {
  1512.     STRPTR    From,To,Name;
  1513.     LONG    Mode;
  1514.  
  1515.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> ASCIIDownloadType == XFER_INTERNAL)
  1516.         return(InternalASCIIUpload(NULL,WaitForIt));
  1517.  
  1518.     switch(Type)
  1519.     {
  1520.         case TRANSFER_BINARY:
  1521.  
  1522.             Name    = Config -> TransferConfig -> BinaryUploadLibrary;
  1523.             Mode    = Config -> TransferConfig -> BinaryUploadType;
  1524.             From    = Config -> PathConfig -> BinaryUploadPath;
  1525.             To    = Config -> PathConfig -> BinaryDownloadPath;
  1526.             break;
  1527.  
  1528.         case TRANSFER_TEXT:
  1529.  
  1530.             Name    = Config -> TransferConfig -> TextUploadLibrary;
  1531.             Mode    = Config -> TransferConfig -> TextUploadType;
  1532.             From    = Config -> PathConfig -> TextUploadPath;
  1533.             To    = Config -> PathConfig -> TextDownloadPath;
  1534.             break;
  1535.  
  1536.         case TRANSFER_ASCII:
  1537.  
  1538.             Name    = Config -> TransferConfig -> ASCIIUploadLibrary;
  1539.             Mode    = Config -> TransferConfig -> ASCIIUploadType;
  1540.             From    = Config -> PathConfig -> ASCIIUploadPath;
  1541.             To    = Config -> PathConfig -> ASCIIDownloadPath;
  1542.             break;
  1543.     }
  1544.  
  1545.     if(Mode == XFER_DEFAULT && Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  1546.     {
  1547.         Name    = Config -> TransferConfig -> DefaultLibrary;
  1548.         Mode    = XFER_EXTERNALPROGRAM;
  1549.     }
  1550.  
  1551.     if(Mode == XFER_EXTERNALPROGRAM)
  1552.     {
  1553.         STRPTR    String;
  1554.         LONG    Error;
  1555.         BOOL    Result;
  1556.  
  1557.         BlockWindows();
  1558.  
  1559.         if(String = BuildString(Name,From,To,Type,FALSE,NULL,NULL,&Error))
  1560.         {
  1561.             ClearSerial();
  1562.  
  1563.             if(LaunchCommand(String))
  1564.                 Result = FALSE;
  1565.             else
  1566.                 Result = TRUE;
  1567.  
  1568.             RestartSerial();
  1569.  
  1570.             FreeVecPooled(String);
  1571.         }
  1572.         else
  1573.             Result = FALSE;
  1574.  
  1575.         ReleaseWindows();
  1576.  
  1577.         return(Result);
  1578.     }
  1579.     else
  1580.     {
  1581.         struct FileRequester    *FileRequest;
  1582.         UBYTE             DummyBuffer[MAX_FILENAME_LENGTH];
  1583.         BYTE             OldStatus = Status;
  1584.         STRPTR             UploadPath;
  1585.         BOOL             DidSend = TRUE;
  1586.         BPTR             NewDir = NULL,
  1587.                      OldDir = NULL;
  1588.  
  1589.         LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
  1590.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  1591.  
  1592.             /* We are uploading data. */
  1593.  
  1594.         Uploading = TRUE;
  1595.  
  1596.             /* Select the upload path. */
  1597.  
  1598.         switch(Type)
  1599.         {
  1600.             case TRANSFER_BINARY:
  1601.  
  1602.                 UploadPath = Config -> PathConfig -> BinaryUploadPath;
  1603.                 break;
  1604.  
  1605.             case TRANSFER_TEXT:
  1606.  
  1607.                 UploadPath = Config -> PathConfig -> TextUploadPath;
  1608.                 break;
  1609.  
  1610.             case TRANSFER_ASCII:
  1611.  
  1612.                 UploadPath = Config -> PathConfig -> ASCIIUploadPath;
  1613.                 break;
  1614.         }
  1615.  
  1616.         DB(kprintf("-> sender\n"));
  1617.  
  1618.         if(UploadPath[0])
  1619.         {
  1620.             if(NewDir = Lock(UploadPath,ACCESS_READ))
  1621.                 OldDir = CurrentDir(NewDir);
  1622.         }
  1623.  
  1624.         DB(kprintf("-> blockwindows\n"));
  1625.         BlockWindows();
  1626.  
  1627.             /* If not initialized, try to set up a new
  1628.              * external transfer protocol.
  1629.              */
  1630.  
  1631.         DB(kprintf("-> xprotocolbase 0x%08lx\n",XProtocolBase));
  1632.         if(!XProtocolBase)
  1633.         {
  1634.             if(SelectProtocol(LastXprLibrary,Window))
  1635.             {
  1636.                 if(ProtocolSetup(FALSE))
  1637.                     SaveProtocolOpts();
  1638.             }
  1639.         }
  1640.  
  1641.         if(XProtocolBase)
  1642.         {
  1643.             DB(kprintf("-> SetTransfermenu\n"));
  1644.             SetTransferMenu(TRUE);
  1645.  
  1646.                 /* Do we need to use our own file requester or
  1647.                  * will xpr handle this job for us?
  1648.                  */
  1649.  
  1650.             if(TransferBits & XPRS_NOSNDREQ)
  1651.             {
  1652.                 DB(kprintf("-> no file requester\n"));
  1653.  
  1654.                     /* Open the transfer info window. */
  1655.  
  1656.                 DB(kprintf("-> transferpanel\n"));
  1657.                 if(TransferPanel(SendQuery[Type]))
  1658.                 {
  1659.                     Status = STATUS_UPLOAD;
  1660.  
  1661.                         /* Shut up the serial line. */
  1662.  
  1663.                     DB(kprintf("-> clearserial\n"));
  1664.                     ClearSerial();
  1665.  
  1666.                     LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
  1667.  
  1668.                         /* Perform upload. */
  1669.  
  1670.                     if(ReadRequest && WriteRequest)
  1671.                     {
  1672.                         DB(kprintf("-> going in\n"));
  1673.                         if(XProtocolSend(XprIO))
  1674.                             TransferFailed = FALSE;
  1675.                         else
  1676.                             TransferFailed = TRUE;
  1677.                     }
  1678.                     else
  1679.                         TransferFailed = TRUE;
  1680.  
  1681.                     if(TransferFailed || TransferAborted)
  1682.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1683.                     else
  1684.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1685.  
  1686.                     if(TransferFailed || TransferError)
  1687.                     {
  1688.                         DB(kprintf("-> waking up\n"));
  1689.                         if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1690.                             WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1691.  
  1692.                         DB(kprintf("-> deletetransferpanel %ld\n",WaitForIt));
  1693.                         DeleteTransferPanel(WaitForIt);
  1694.                     }
  1695.                     else
  1696.                     {
  1697.                         if(TransferWindow)
  1698.                         {
  1699.                             DB(kprintf("-> waking up\n"));
  1700.                             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1701.                                 WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1702.  
  1703.                             DB(kprintf("-> waiting a bit\n"));
  1704.                             DelayTime(2,0);
  1705.                         }
  1706.  
  1707.                         DB(kprintf("-> deletetransferpanel false\n"));
  1708.                         DeleteTransferPanel(FALSE);
  1709.                     }
  1710.  
  1711.                     Status = OldStatus;
  1712.  
  1713.                         /* And request another character. */
  1714.  
  1715.                     DB(kprintf("->restartserial\n"));
  1716.                     RestartSerial();
  1717.                 }
  1718.             }
  1719.             else
  1720.             {
  1721.                     /* We will need the file requester to find
  1722.                      * out which file(s) are to be transferred.
  1723.                      * Multiple files and wildcards are
  1724.                      * supported as well as plain file names.
  1725.                      */
  1726.  
  1727.                 if(FileRequest = GetFile(Window,SendQuery[Type],UploadPath,"",DummyBuffer,"",FALSE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),TRUE))
  1728.                 {
  1729.                     strcpy(UploadPath,FileRequest -> fr_Drawer);
  1730.  
  1731.                     ConfigChanged = TRUE;
  1732.  
  1733.                     if(FileTransferInfo = BuildFileTransferInfo(FileRequest))
  1734.                     {
  1735.                             /* Make sure that at least the
  1736.                              * first file gets transferred
  1737.                              * in case the protocol does
  1738.                              * no support batch upload.
  1739.                              */
  1740.  
  1741.                         XprIO -> xpr_filename = ReplaceName(FileTransferInfo -> CurrentFile -> Name);
  1742.  
  1743.                         if(TransferPanel(SendQuery[Type]))
  1744.                         {
  1745.                             Status = STATUS_UPLOAD;
  1746.  
  1747.                             ClearSerial();
  1748.  
  1749.                             LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
  1750.  
  1751.                             if(ReadRequest && WriteRequest)
  1752.                             {
  1753.                                 if(XProtocolSend(XprIO))
  1754.                                     TransferFailed = FALSE;
  1755.                                 else
  1756.                                     TransferFailed = TRUE;
  1757.                             }
  1758.                             else
  1759.                                 TransferFailed = TRUE;
  1760.  
  1761.                             if(TransferFailed || TransferAborted)
  1762.                                 Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1763.                             else
  1764.                                 Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1765.  
  1766.                             if(TransferFailed || TransferError)
  1767.                             {
  1768.                                 if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1769.                                     WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1770.  
  1771.                                 DeleteTransferPanel(WaitForIt);
  1772.                             }
  1773.                             else
  1774.                             {
  1775.                                 if(TransferWindow)
  1776.                                 {
  1777.                                     if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1778.                                         WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1779.  
  1780.                                     DelayTime(2,0);
  1781.                                 }
  1782.  
  1783.                                 DeleteTransferPanel(FALSE);
  1784.                             }
  1785.  
  1786.                             Status = OldStatus;
  1787.  
  1788.                             RestartSerial();
  1789.                         }
  1790.  
  1791.                         if(FileTransferInfo)
  1792.                         {
  1793.                             FreeFileTransferInfo(FileTransferInfo);
  1794.  
  1795.                             FileTransferInfo = NULL;
  1796.                         }
  1797.                     }
  1798.  
  1799.                     FreeAslRequest(FileRequest);
  1800.                 }
  1801.                 else
  1802.                     DidSend = FALSE;
  1803.             }
  1804.         }
  1805.         else
  1806.             SetTransferMenu(TRUE);
  1807.  
  1808.         DB(kprintf("-> olddir\n"));
  1809.         if(OldDir)
  1810.             CurrentDir(OldDir);
  1811.  
  1812.         DB(kprintf("-> newdir\n"));
  1813.         if(NewDir)
  1814.             UnLock(NewDir);
  1815.  
  1816.         DB(kprintf("-> serwrite\n"));
  1817.         if(SendAbort && UsesZModem)
  1818.             SerWrite(ZModemCancel,20);
  1819.  
  1820.         SendAbort = FALSE;
  1821.  
  1822.         DB(kprintf("-> releasewindows\n"));
  1823.         ReleaseWindows();
  1824.  
  1825.         Uploading = FALSE;
  1826.  
  1827.         if(WaitForIt)
  1828.         {
  1829.             DB(kprintf("-> serialcommand\n"));
  1830.             if(Config -> CommandConfig -> UploadMacro[0])
  1831.                 SerialCommand(Config -> CommandConfig -> UploadMacro);
  1832.         }
  1833.  
  1834.         DidTransfer = FALSE;
  1835.  
  1836.         DB(kprintf("-> didsend %ld\n",DidSend));
  1837.         return(DidSend);
  1838.     }
  1839. }
  1840.  
  1841.     /* StartXprSendFromList():
  1842.      *
  1843.      *    Send files via xpr.
  1844.      */
  1845.  
  1846. BOOL
  1847. StartXprSendFromList(LONG Type,BOOL WaitForIt)
  1848. {
  1849.     STRPTR    From,To,Name;
  1850.     LONG    Mode;
  1851.  
  1852.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> ASCIIDownloadType == XFER_INTERNAL)
  1853.         return(InternalASCIIUpload(NULL,WaitForIt));
  1854.  
  1855.     switch(Type)
  1856.     {
  1857.         case TRANSFER_BINARY:
  1858.  
  1859.             Name    = Config -> TransferConfig -> BinaryUploadLibrary;
  1860.             Mode    = Config -> TransferConfig -> BinaryUploadType;
  1861.             From    = Config -> PathConfig -> BinaryUploadPath;
  1862.             To    = Config -> PathConfig -> BinaryDownloadPath;
  1863.             break;
  1864.  
  1865.         case TRANSFER_TEXT:
  1866.  
  1867.             Name    = Config -> TransferConfig -> TextUploadLibrary;
  1868.             Mode    = Config -> TransferConfig -> TextUploadType;
  1869.             From    = Config -> PathConfig -> TextUploadPath;
  1870.             To    = Config -> PathConfig -> TextDownloadPath;
  1871.             break;
  1872.  
  1873.         case TRANSFER_ASCII:
  1874.  
  1875.             Name    = Config -> TransferConfig -> ASCIIUploadLibrary;
  1876.             Mode    = Config -> TransferConfig -> ASCIIUploadType;
  1877.             From    = Config -> PathConfig -> ASCIIUploadPath;
  1878.             To    = Config -> PathConfig -> ASCIIDownloadPath;
  1879.             break;
  1880.     }
  1881.  
  1882.     if(Mode == XFER_DEFAULT && Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  1883.     {
  1884.         Name    = Config -> TransferConfig -> DefaultLibrary;
  1885.         Mode    = XFER_EXTERNALPROGRAM;
  1886.     }
  1887.  
  1888.     if(Mode == XFER_EXTERNALPROGRAM)
  1889.     {
  1890.         STRPTR    String;
  1891.         LONG    Error;
  1892.         BOOL    Result;
  1893.  
  1894.         BlockWindows();
  1895.  
  1896.         if(String = BuildString(Name,From,To,Type,FALSE,NULL,FileTransferInfo,&Error))
  1897.         {
  1898.             ClearSerial();
  1899.  
  1900.             if(LaunchCommand(String))
  1901.                 Result = FALSE;
  1902.             else
  1903.                 Result = TRUE;
  1904.  
  1905.             RestartSerial();
  1906.  
  1907.             FreeVecPooled(String);
  1908.         }
  1909.         else
  1910.             Result = FALSE;
  1911.  
  1912.         if(FileTransferInfo)
  1913.         {
  1914.             FreeFileTransferInfo(FileTransferInfo);
  1915.  
  1916.             FileTransferInfo = NULL;
  1917.         }
  1918.  
  1919.         ReleaseWindows();
  1920.  
  1921.         return(Result);
  1922.     }
  1923.     else
  1924.     {
  1925.         BYTE    OldStatus    = Status;
  1926.         BOOL    DidSend     = TRUE;
  1927.         BPTR    NewDir        = NULL,
  1928.             OldDir;
  1929.         STRPTR    UploadPath;
  1930.  
  1931.         LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
  1932.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  1933.  
  1934.             /* We are uploading data. */
  1935.  
  1936.         Uploading = TRUE;
  1937.  
  1938.         switch(Type)
  1939.         {
  1940.             case TRANSFER_BINARY:
  1941.  
  1942.                 UploadPath = Config -> PathConfig -> BinaryUploadPath;
  1943.                 break;
  1944.  
  1945.             case TRANSFER_TEXT:
  1946.  
  1947.                 UploadPath = Config -> PathConfig -> TextUploadPath;
  1948.                 break;
  1949.  
  1950.             case TRANSFER_ASCII:
  1951.  
  1952.                 UploadPath = Config -> PathConfig -> ASCIIUploadPath;
  1953.                 break;
  1954.         }
  1955.  
  1956.         if(UploadPath[0])
  1957.         {
  1958.             if(NewDir = Lock(UploadPath,ACCESS_READ))
  1959.                 OldDir = CurrentDir(NewDir);
  1960.         }
  1961.  
  1962.         BlockWindows();
  1963.  
  1964.             /* If not initialized, try to set up a new
  1965.              * external transfer protocol.
  1966.              */
  1967.  
  1968.         if(!XProtocolBase)
  1969.         {
  1970.             if(WaitForIt)
  1971.             {
  1972.                 if(SelectProtocol(LastXprLibrary,Window))
  1973.                 {
  1974.                     if(ProtocolSetup(FALSE))
  1975.                         SaveProtocolOpts();
  1976.                 }
  1977.             }
  1978.         }
  1979.  
  1980.         if(XProtocolBase)
  1981.         {
  1982.             SetTransferMenu(TRUE);
  1983.  
  1984.                 /* Make sure that at least the
  1985.                  * first file gets transferred
  1986.                  * in case the protocol does
  1987.                  * no support batch upload.
  1988.                  */
  1989.  
  1990.             XprIO -> xpr_filename = ReplaceName(FileTransferInfo -> CurrentFile -> Name);
  1991.  
  1992.             if(TransferPanel(SendQuery[Type]))
  1993.             {
  1994.                 Status = STATUS_UPLOAD;
  1995.  
  1996.                 ClearSerial();
  1997.  
  1998.                 LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
  1999.  
  2000.                 if(ReadRequest && WriteRequest)
  2001.                 {
  2002.                     DB(kprintf("going in\n"));
  2003.  
  2004.                     if(XProtocolSend(XprIO))
  2005.                         TransferFailed = FALSE;
  2006.                     else
  2007.                         TransferFailed = TRUE;
  2008.                 }
  2009.                 else
  2010.                     TransferFailed = TRUE;
  2011.  
  2012.                 DB(kprintf("ok, done\n"));
  2013.  
  2014.                 if(TransferFailed || TransferAborted)
  2015.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  2016.                 else
  2017.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  2018.  
  2019.                 DB(kprintf("cleaning up...\n"));
  2020.  
  2021.                 if(TransferFailed || TransferError)
  2022.                 {
  2023.                     if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2024.                         WakeUp(TransferWindow,SOUND_BADTRANSFER);
  2025.  
  2026.                     DeleteTransferPanel(WaitForIt);
  2027.                 }
  2028.                 else
  2029.                 {
  2030.                     if(TransferWindow)
  2031.                     {
  2032.                         if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2033.                             WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  2034.  
  2035.                         DelayTime(2,0);
  2036.                     }
  2037.  
  2038.                     DeleteTransferPanel(FALSE);
  2039.                 }
  2040.  
  2041.                 DB(kprintf("cleaned up\n"));
  2042.  
  2043.                 Status = OldStatus;
  2044.  
  2045.                 RestartSerial();
  2046.             }
  2047.  
  2048.             DB(kprintf("discarding filetransferinfo\n"));
  2049.  
  2050.             if(FileTransferInfo)
  2051.             {
  2052.                 FreeFileTransferInfo(FileTransferInfo);
  2053.  
  2054.                 FileTransferInfo = NULL;
  2055.             }
  2056.  
  2057.             DB(kprintf("did that\n"));
  2058.         }
  2059.         else
  2060.         {
  2061.             SetTransferMenu(TRUE);
  2062.  
  2063.             DidSend = FALSE;
  2064.         }
  2065.  
  2066.         DB(kprintf("now for the rest\n"));
  2067.  
  2068.         if(NewDir)
  2069.         {
  2070.             DB(kprintf("currentdir\n"));
  2071.             CurrentDir(OldDir);
  2072.             DB(kprintf("newdir\n"));
  2073.             UnLock(NewDir);
  2074.         }
  2075.  
  2076.         if(SendAbort && UsesZModem)
  2077.         {
  2078.             DB(kprintf("zmodemcancel\n"));
  2079.             SerWrite(ZModemCancel,20);
  2080.         }
  2081.  
  2082.         SendAbort = FALSE;
  2083.  
  2084.         DB(kprintf("releasewindows\n"));
  2085.         ReleaseWindows();
  2086.  
  2087.         Uploading = FALSE;
  2088.  
  2089.         if(WaitForIt)
  2090.         {
  2091.             if(Config -> CommandConfig -> UploadMacro[0])
  2092.             {
  2093.                 DB(kprintf("uploadmacro\n"));
  2094.                 SerialCommand(Config -> CommandConfig -> UploadMacro);
  2095.             }
  2096.         }
  2097.  
  2098.         DidTransfer = FALSE;
  2099.  
  2100.         DB(kprintf("through. didsend=%ld\n",DidSend));
  2101.  
  2102.         return(DidSend);
  2103.     }
  2104. }
  2105.  
  2106.     /* ChangeProtocol(STRPTR ProtocolName):
  2107.      *
  2108.      *    Select a different file transfer protocol.
  2109.      */
  2110.  
  2111. BOOL
  2112. ChangeProtocol(STRPTR ProtocolName,LONG Type)
  2113. {
  2114.     UBYTE    NameBuffer[40];
  2115.     LONG    i;
  2116.  
  2117.     if(Type == XFER_DEFAULT)
  2118.     {
  2119.         ProtocolName = Config -> TransferConfig -> DefaultLibrary;
  2120.  
  2121.         Type = Config -> TransferConfig -> DefaultType;
  2122.     }
  2123.  
  2124.     if(Type == XFER_XPR)
  2125.     {
  2126.         if(!ProtocolName || !ProtocolName[0])
  2127.             ProtocolName = Config -> TransferConfig -> DefaultLibrary;
  2128.  
  2129.         if(!Stricmp(ProtocolName,LastXprLibrary) && XProtocolBase)
  2130.             return(TRUE);
  2131.     }
  2132.  
  2133.         /* Close the old library if still open. */
  2134.  
  2135.     CloseXPR();
  2136.  
  2137.     if(Type == XFER_INTERNAL)
  2138.     {
  2139.         UsesZModem = FALSE;
  2140.  
  2141.         SetTransferMenu(TRUE);
  2142.  
  2143.         strcpy(TransferProtocolName,"ASCII");
  2144.  
  2145.         return(TRUE);
  2146.     }
  2147.  
  2148.     if(Type == XFER_EXTERNALPROGRAM)
  2149.     {
  2150.         LONG i;
  2151.         STRPTR Buffer = ProtocolName;
  2152.  
  2153.         while(*Buffer == ' ')
  2154.             Buffer++;
  2155.  
  2156.         if(!Strnicmp(Buffer,"run",3))
  2157.             Buffer += 3;
  2158.  
  2159.         while(*Buffer == ' ')
  2160.             Buffer++;
  2161.  
  2162.         CopyMem(FilePart(Buffer),NameBuffer,40);
  2163.  
  2164.         NameBuffer[39] = 0;
  2165.  
  2166.         for(i = 0 ; i < 40 ; i++)
  2167.         {
  2168.             if(NameBuffer[i] == ' ')
  2169.             {
  2170.                 NameBuffer[i] = 0;
  2171.  
  2172.                 break;
  2173.             }
  2174.         }
  2175.  
  2176.         strcpy(TransferProtocolName,NameBuffer);
  2177.  
  2178.         NameBuffer[0] = ToUpper(NameBuffer[0]);
  2179.  
  2180.         UsesZModem = FALSE;
  2181.  
  2182.         for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  2183.         {
  2184.             if(!Stricmp(&NameBuffer[i],"zmodem"))
  2185.                 UsesZModem = TRUE;
  2186.         }
  2187.  
  2188.         SetTransferMenu(TRUE);
  2189.  
  2190.         return(TRUE);
  2191.     }
  2192.  
  2193.         /* Clear the XPR interface buffer. */
  2194.  
  2195.     memset(XprIO,0,sizeof(struct XPR_IO));
  2196.  
  2197.         /* Copy the name of the library. */
  2198.  
  2199.     CopyMem(FilePart(ProtocolName),NameBuffer,40);
  2200.     NameBuffer[39] = 0;
  2201.  
  2202.         /* Extract the name itself (strip the `.library'). */
  2203.  
  2204.     for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
  2205.     {
  2206.         if(NameBuffer[i] == '.')
  2207.         {
  2208.             NameBuffer[i] = 0;
  2209.  
  2210.             break;
  2211.         }
  2212.     }
  2213.  
  2214.         /* Check if the transfer protocol is a sort of ZModem. */
  2215.  
  2216.     UsesZModem = FALSE;
  2217.  
  2218.     for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  2219.     {
  2220.         if(!Stricmp(&NameBuffer[i],"zmodem"))
  2221.             UsesZModem = TRUE;
  2222.     }
  2223.  
  2224.         /* Reset the scanner. */
  2225.  
  2226.     FlowInit(TRUE);
  2227.  
  2228.         /* Obtain the protocol default settings. */
  2229.  
  2230.     if(!GetEnvDOS(NameBuffer,ProtocolOptsBuffer))
  2231.         ProtocolOptsBuffer[0] = 0;
  2232.  
  2233.     NameBuffer[3] = ToUpper(NameBuffer[3]);
  2234.  
  2235.         /* Initialize the interface structure. */
  2236.  
  2237.     XprIO -> xpr_filename    = ProtocolOptsBuffer;
  2238.     XprIO -> xpr_fopen    = xpr_fopen;
  2239.     XprIO -> xpr_fclose    = xpr_fclose;
  2240.     XprIO -> xpr_fread    = xpr_fread;
  2241.     XprIO -> xpr_fwrite    = xpr_fwrite;
  2242.     XprIO -> xpr_sread    = xpr_sread;
  2243.     XprIO -> xpr_swrite    = xpr_swrite;
  2244.     XprIO -> xpr_sflush    = xpr_sflush;
  2245.     XprIO -> xpr_update    = xpr_update;
  2246.     XprIO -> xpr_chkabort    = xpr_chkabort;
  2247.     XprIO -> xpr_gets    = xpr_gets;
  2248.     XprIO -> xpr_setserial    = xpr_setserial;
  2249.     XprIO -> xpr_ffirst    = xpr_ffirst;
  2250.     XprIO -> xpr_fnext    = xpr_fnext;
  2251.     XprIO -> xpr_finfo    = xpr_finfo;
  2252.     XprIO -> xpr_fseek    = xpr_fseek;
  2253.     XprIO -> xpr_extension    = 4;
  2254.     XprIO -> xpr_options    = xpr_options;
  2255.     XprIO -> xpr_unlink    = xpr_unlink;
  2256.     XprIO -> xpr_squery    = xpr_squery;
  2257.     XprIO -> xpr_getptr    = xpr_getptr;
  2258.  
  2259.         /* Try to open the library. */
  2260.  
  2261.     if(XProtocolBase = (struct Library *)OpenLibrary(ProtocolName,0))
  2262.     {
  2263.             /* Set up the library. */
  2264.  
  2265.         ClearSerial();
  2266.  
  2267.         TransferBits = XProtocolSetup(XprIO);
  2268.  
  2269.         RestartSerial();
  2270.  
  2271.         DeleteTransferPanel(TRUE);
  2272.  
  2273.             /* Successful initialization? */
  2274.  
  2275.         if(TransferBits & XPRS_SUCCESS)
  2276.         {
  2277.             SetTransferMenu(TRUE);
  2278.  
  2279.             strcpy(LastXprLibrary,ProtocolName);
  2280.  
  2281.             if(TransferBits & XPRS_HOSTMON)
  2282.                 ConTransfer = ConTransferHost;
  2283.             else
  2284.                 ConTransfer = ConProcess;
  2285.  
  2286.             if(TransferBits & XPRS_HOSTNOWAIT)
  2287.             {
  2288.                 if(!HostReadBuffer)
  2289.                     HostReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY);
  2290.             }
  2291.             else
  2292.             {
  2293.                 FreeVecPooled(HostReadBuffer);
  2294.                 HostReadBuffer = NULL;
  2295.             }
  2296.  
  2297.             strcpy(TransferProtocolName,&NameBuffer[3]);
  2298.  
  2299.             return(TRUE);
  2300.         }
  2301.         else
  2302.         {
  2303.             ShowRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FilePart(ProtocolName));
  2304.  
  2305.             CloseLibrary(XProtocolBase);
  2306.  
  2307.             XProtocolBase = NULL;
  2308.  
  2309.             SetTransferMenu(TRUE);
  2310.  
  2311.             LastXprLibrary[0] = 0;
  2312.  
  2313.             TransferBits = 0;
  2314.  
  2315.             ConTransfer = ConProcess;
  2316.  
  2317.             TransferProtocolName[0] = 0;
  2318.         }
  2319.     }
  2320.     else
  2321.     {
  2322.         ConTransfer = ConProcess;
  2323.  
  2324.         ShowRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_OPEN_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FilePart(ProtocolName));
  2325.  
  2326.         SetTransferMenu(TRUE);
  2327.  
  2328.         TransferBits = 0;
  2329.  
  2330.         LastXprLibrary[0] = 0;
  2331.  
  2332.         TransferProtocolName[0] = 0;
  2333.     }
  2334.  
  2335.     return(FALSE);
  2336. }
  2337.  
  2338.     /* ResetProtocol():
  2339.      *
  2340.      *    Return to the previously selected file
  2341.      *    transfer protocol.
  2342.      */
  2343.  
  2344. VOID
  2345. ResetProtocol()
  2346. {
  2347.     ChangeProtocol(NULL,XFER_DEFAULT);
  2348. }
  2349.  
  2350.     /* ProtocolSetup(BOOL IgnoreOptions):
  2351.      *
  2352.      *    Set up the library and options for the external protocol.
  2353.      */
  2354.  
  2355. BOOL
  2356. ProtocolSetup(BOOL IgnoreOptions)
  2357. {
  2358.     UBYTE    NameBuffer[40];
  2359.     LONG    i;
  2360.  
  2361.         /* Close the old library if still open. */
  2362.  
  2363.     CloseXPR();
  2364.  
  2365.     if(Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  2366.     {
  2367.         if(Config -> TransferConfig -> DefaultLibrary[0])
  2368.         {
  2369.             LONG i;
  2370.             STRPTR Buffer = Config -> TransferConfig -> DefaultLibrary;
  2371.  
  2372.             while(*Buffer == ' ')
  2373.                 Buffer++;
  2374.  
  2375.             if(!Strnicmp(Buffer,"run",3))
  2376.                 Buffer += 3;
  2377.  
  2378.             while(*Buffer == ' ')
  2379.                 Buffer++;
  2380.  
  2381.             CopyMem(FilePart(Buffer),NameBuffer,40);
  2382.  
  2383.             NameBuffer[39] = 0;
  2384.  
  2385.             for(i = 0 ; i < 40 ; i++)
  2386.             {
  2387.                 if(NameBuffer[i] == ' ')
  2388.                 {
  2389.                     NameBuffer[i] = 0;
  2390.  
  2391.                     break;
  2392.                 }
  2393.             }
  2394.  
  2395.             NameBuffer[0] = ToUpper(NameBuffer[0]);
  2396.  
  2397.             strcpy(TransferProtocolName,NameBuffer);
  2398.  
  2399.             UsesZModem = FALSE;
  2400.  
  2401.             for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  2402.             {
  2403.                 if(!Stricmp(&NameBuffer[i],"zmodem"))
  2404.                     UsesZModem = TRUE;
  2405.             }
  2406.  
  2407.             SetTransferMenu(TRUE);
  2408.  
  2409.             return(TRUE);
  2410.         }
  2411.         else
  2412.             return(FALSE);
  2413.     }
  2414.  
  2415.         /* Clear the XPR interface buffer. */
  2416.  
  2417.     memset(XprIO,0,sizeof(struct XPR_IO));
  2418.  
  2419.         /* Copy the name of the library. */
  2420.  
  2421.     CopyMem(FilePart(LastXprLibrary),NameBuffer,40);
  2422.     NameBuffer[39] = 0;
  2423.  
  2424.         /* Extract the name itself (strip the `.library'). */
  2425.  
  2426.     for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
  2427.     {
  2428.         if(NameBuffer[i] == '.')
  2429.         {
  2430.             NameBuffer[i] = 0;
  2431.             break;
  2432.         }
  2433.     }
  2434.  
  2435.         /* Check if the transfer protocol is a sort of ZModem. */
  2436.  
  2437.     UsesZModem = FALSE;
  2438.  
  2439.     for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  2440.     {
  2441.         if(!Stricmp(&NameBuffer[i],"zmodem"))
  2442.             UsesZModem = TRUE;
  2443.     }
  2444.  
  2445.     NameBuffer[3] = ToUpper(NameBuffer[3]);
  2446.  
  2447.         /* Reset the scanner. */
  2448.  
  2449.     FlowInit(TRUE);
  2450.  
  2451.         /* Obtain the protocol default settings. */
  2452.  
  2453.     if(!IgnoreOptions)
  2454.     {
  2455.         if(!GetEnvDOS(NameBuffer,ProtocolOptsBuffer))
  2456.             ProtocolOptsBuffer[0] = 0;
  2457.     }
  2458.  
  2459.         /* Initialize the interface structure. */
  2460.  
  2461.     XprIO -> xpr_filename    = ProtocolOptsBuffer;
  2462.     XprIO -> xpr_fopen    = xpr_fopen;
  2463.     XprIO -> xpr_fclose    = xpr_fclose;
  2464.     XprIO -> xpr_fread    = xpr_fread;
  2465.     XprIO -> xpr_fwrite    = xpr_fwrite;
  2466.     XprIO -> xpr_sread    = xpr_sread;
  2467.     XprIO -> xpr_swrite    = xpr_swrite;
  2468.     XprIO -> xpr_sflush    = xpr_sflush;
  2469.     XprIO -> xpr_update    = xpr_update;
  2470.     XprIO -> xpr_chkabort    = xpr_chkabort;
  2471.     XprIO -> xpr_gets    = xpr_gets;
  2472.     XprIO -> xpr_setserial    = xpr_setserial;
  2473.     XprIO -> xpr_ffirst    = xpr_ffirst;
  2474.     XprIO -> xpr_fnext    = xpr_fnext;
  2475.     XprIO -> xpr_finfo    = xpr_finfo;
  2476.     XprIO -> xpr_fseek    = xpr_fseek;
  2477.     XprIO -> xpr_extension    = 4;
  2478.     XprIO -> xpr_options    = xpr_options;
  2479.     XprIO -> xpr_unlink    = xpr_unlink;
  2480.     XprIO -> xpr_squery    = xpr_squery;
  2481.     XprIO -> xpr_getptr    = xpr_getptr;
  2482.  
  2483.         /* Try to open the library. */
  2484.  
  2485.     if(XProtocolBase = (struct Library *)OpenLibrary(LastXprLibrary,0))
  2486.     {
  2487.             /* Set up the library. */
  2488.  
  2489.         ClearSerial();
  2490.  
  2491.         TransferBits = XProtocolSetup(XprIO);
  2492.  
  2493.         RestartSerial();
  2494.  
  2495.         DeleteTransferPanel(IgnoreOptions != TRUE);
  2496.  
  2497.             /* Successful initialization? */
  2498.  
  2499.         if(TransferBits & XPRS_SUCCESS)
  2500.         {
  2501.             SetTransferMenu(TRUE);
  2502.  
  2503.             if(TransferBits & XPRS_HOSTMON)
  2504.                 ConTransfer = ConTransferHost;
  2505.             else
  2506.                 ConTransfer = ConProcess;
  2507.  
  2508.             if(TransferBits & XPRS_HOSTNOWAIT)
  2509.             {
  2510.                 if(!HostReadBuffer)
  2511.                     HostReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY);
  2512.             }
  2513.             else
  2514.             {
  2515.                 FreeVecPooled(HostReadBuffer);
  2516.                 HostReadBuffer = NULL;
  2517.             }
  2518.  
  2519.             strcpy(TransferProtocolName,&NameBuffer[3]);
  2520.  
  2521.             return(TRUE);
  2522.         }
  2523.         else
  2524.         {
  2525.             ShowRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FilePart(LastXprLibrary));
  2526.  
  2527.             CloseLibrary(XProtocolBase);
  2528.  
  2529.             XProtocolBase = NULL;
  2530.  
  2531.             LastXprLibrary[0] = 0;
  2532.  
  2533.             TransferBits = 0;
  2534.  
  2535.             ConTransfer = ConProcess;
  2536.  
  2537.             SetTransferMenu(TRUE);
  2538.  
  2539.             TransferProtocolName[0] = 0;
  2540.         }
  2541.     }
  2542.     else
  2543.     {
  2544.         ConTransfer = ConProcess;
  2545.  
  2546.         ShowRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_OPEN_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FilePart(LastXprLibrary));
  2547.  
  2548.         LastXprLibrary[0] = 0;
  2549.  
  2550.         TransferBits = 0;
  2551.  
  2552.         SetTransferMenu(TRUE);
  2553.  
  2554.         TransferProtocolName[0] = 0;
  2555.     }
  2556.  
  2557.     return(FALSE);
  2558. }
  2559.  
  2560.     /* SaveProtocolOpts():
  2561.      *
  2562.      *    Save the current protocol settings to an environment variable.
  2563.      */
  2564.  
  2565. VOID
  2566. SaveProtocolOpts()
  2567. {
  2568.         /* It's time to save the altered options. */
  2569.  
  2570.     if(NewOptions && XProtocolBase)
  2571.     {
  2572.         UBYTE    NameBuffer[40];
  2573.         LONG    i;
  2574.  
  2575.             /* Strip the `.library' part. */
  2576.  
  2577.         CopyMem(FilePart(LastXprLibrary),NameBuffer,40);
  2578.         NameBuffer[39] = 0;
  2579.  
  2580.         for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
  2581.         {
  2582.             if(NameBuffer[i] == '.')
  2583.             {
  2584.                 NameBuffer[i] = 0;
  2585.                 break;
  2586.             }
  2587.         }
  2588.  
  2589.             /* Cause the xpr.library to prompt for
  2590.              * input. We expect the library to fill
  2591.              * the prompt string with the default
  2592.              * settings. The resulting string is
  2593.              * intercepted by xpr_stealopts, saved
  2594.              * to an environment variable and will
  2595.              * serve as a reinitialization string
  2596.              * later.
  2597.              */
  2598.  
  2599.         XprIO -> xpr_filename    = NULL;
  2600.         XprIO -> xpr_gets    = xpr_stealopts;
  2601.         XprIO -> xpr_extension    = 0;
  2602.         XprIO -> xpr_options    = NULL;
  2603.  
  2604.         ClearSerial();
  2605.  
  2606.         XProtocolSetup(XprIO);
  2607.  
  2608.         DeleteTransferPanel(FALSE);
  2609.  
  2610.             /* Save the options in case anything goes
  2611.              * wrong.
  2612.              */
  2613.  
  2614.         NewOptions = FALSE;
  2615.  
  2616.         SetEnvDOS(NameBuffer,ProtocolOptsBuffer);
  2617.  
  2618.             /* Reinitialize the library. */
  2619.  
  2620.         XprIO -> xpr_filename    = ProtocolOptsBuffer;
  2621.         XprIO -> xpr_gets    = xpr_gets;
  2622.         XprIO -> xpr_extension    = 4;
  2623.         XprIO -> xpr_options    = xpr_options;
  2624.  
  2625.         XProtocolSetup(XprIO);
  2626.  
  2627.         RestartSerial();
  2628.  
  2629.         DeleteTransferPanel(FALSE);
  2630.     }
  2631. }
  2632.  
  2633.     /* SelectProtocol(STRPTR Name,struct Window *ParentWindow):
  2634.      *
  2635.      *    Select a different transfer protocol library using
  2636.      *    the asl.library file requester.
  2637.      */
  2638.  
  2639. BOOL
  2640. SelectProtocol(STRPTR Name,struct Window *ParentWindow)
  2641. {
  2642.     strcpy(SharedBuffer,LastXprLibrary);
  2643.  
  2644.     if(PickFile(Window,"Libs:","xpr#?.library",LocaleString(MSG_TERMXPR_SELECT_TRANSFER_PROTOCOL_TXT),SharedBuffer,NT_LIBRARY))
  2645.     {
  2646.         if(Stricmp(SharedBuffer,LastXprLibrary))
  2647.         {
  2648.             strcpy(LastXprLibrary,SharedBuffer);
  2649.  
  2650.             return(TRUE);
  2651.         }
  2652.     }
  2653.  
  2654.     return(FALSE);
  2655. }
  2656.  
  2657.     /* TransferCleanup():
  2658.      *
  2659.      *    We did a file transfer (auto-download?) and
  2660.      *    will need to close the transfer window.
  2661.      */
  2662.  
  2663. VOID
  2664. TransferCleanup()
  2665. {
  2666.     if(DidTransfer)
  2667.     {
  2668.         if(TransferFailed || TransferError)
  2669.         {
  2670.             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2671.                 WakeUp(TransferWindow,SOUND_BADTRANSFER);
  2672.  
  2673.             DeleteTransferPanel(TRUE);
  2674.         }
  2675.         else
  2676.         {
  2677.             if(TransferWindow)
  2678.             {
  2679.                 if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2680.                     WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  2681.  
  2682.                 DelayTime(2,0);
  2683.             }
  2684.  
  2685.             DeleteTransferPanel(FALSE);
  2686.         }
  2687.  
  2688.         if(SendAbort && UsesZModem)
  2689.             SerWrite(ZModemCancel,20);
  2690.  
  2691.         SendAbort = FALSE;
  2692.  
  2693.         if(Config -> CommandConfig -> DownloadMacro[0])
  2694.             SerialCommand(Config -> CommandConfig -> DownloadMacro);
  2695.  
  2696.         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  2697.  
  2698.         DidTransfer = FALSE;
  2699.     }
  2700.     else
  2701.     {
  2702.         if(TransferFailed || TransferError)
  2703.         {
  2704.             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2705.                 WakeUp(TransferWindow,SOUND_BADTRANSFER);
  2706.  
  2707.             DeleteTransferPanel(TRUE);
  2708.         }
  2709.         else
  2710.         {
  2711.             if(TransferWindow)
  2712.             {
  2713.                 if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2714.                     WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  2715.  
  2716.                 DelayTime(2,0);
  2717.             }
  2718.  
  2719.             DeleteTransferPanel(FALSE);
  2720.         }
  2721.     }
  2722.  
  2723.     BinaryTransfer = TRUE;
  2724.  
  2725.     Status = STATUS_READY;
  2726.  
  2727.     ReleaseWindows();
  2728. }
  2729.  
  2730.     /* RemoveUploadListItem(STRPTR Name):
  2731.      *
  2732.      *    Remove a named item from the upload list.
  2733.      */
  2734.  
  2735. VOID
  2736. RemoveUploadListItem(STRPTR Name)
  2737. {
  2738.     BPTR NameLock;
  2739.  
  2740.     if(NameLock = Lock(Name,ACCESS_READ))
  2741.     {
  2742.         struct GenericList    *List = GenericListTable[GLIST_UPLOAD];
  2743.         struct Node        *Node;
  2744.         STRPTR             Base = FilePart(Name);
  2745.  
  2746.         ObtainSemaphore(&List -> ListSemaphore);
  2747.  
  2748.         Node = (struct Node *)List -> ListHeader . mlh_Head;
  2749.  
  2750.         while(Node -> ln_Succ)
  2751.         {
  2752.             if(!Stricmp(Base,FilePart(Node -> ln_Name)))
  2753.             {
  2754.                 BPTR ListLock;
  2755.  
  2756.                 if(ListLock = Lock(Node -> ln_Name,ACCESS_READ))
  2757.                 {
  2758.                     if(SameLock(ListLock,NameLock) == LOCK_SAME)
  2759.                     {
  2760.                         Forbid();
  2761.  
  2762.                         ReleaseSemaphore(&List -> ListSemaphore);
  2763.  
  2764.                         DeleteGenericListNode(List,Node);
  2765.  
  2766.                         Permit();
  2767.  
  2768.                         UnLock(ListLock);
  2769.  
  2770.                         UnLock(NameLock);
  2771.  
  2772.                         return;
  2773.                     }
  2774.  
  2775.                     UnLock(ListLock);
  2776.                 }
  2777.             }
  2778.  
  2779.             Node = Node -> ln_Succ;
  2780.         }
  2781.  
  2782.         ReleaseSemaphore(&List -> ListSemaphore);
  2783.  
  2784.         UnLock(NameLock);
  2785.     }
  2786. }
  2787.  
  2788.     /* CloseXPR():
  2789.      *
  2790.      *    Close the XPR library if it is still open.
  2791.      */
  2792.  
  2793. VOID
  2794. CloseXPR()
  2795. {
  2796.     if(XProtocolBase)
  2797.     {
  2798.         XProtocolCleanup(XprIO);
  2799.  
  2800.         CloseLibrary(XProtocolBase);
  2801.  
  2802.         XProtocolBase = NULL;
  2803.  
  2804.         SetTransferMenu(TRUE);
  2805.  
  2806.         ConTransfer = ConProcess;
  2807.     }
  2808. }
  2809.