home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / comm / term33so.lha / termARexxCommands.c < prev    next >
C/C++ Source or Header  |  1993-04-30  |  89KB  |  5,060 lines

  1. /*
  2. **    termARexxCommands.c
  3. **
  4. **    ARexx interface command support routines
  5. **
  6. **    Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termARexxGlobal.h"
  11.  
  12.     /* Number of bytes already processed by ScanNodeFilter(). */
  13.  
  14. STATIC LONG WaitCount = 0;
  15.  
  16.     /* Cheapo shortcuts ;-) */
  17.  
  18. #define Args    Pkt -> Array
  19. #define Results    Pkt -> Results
  20.  
  21.     /* ScanNodeFilter():
  22.      *
  23.      *    Scan memory for a certain sequence.
  24.      */
  25.  
  26. STATIC STRPTR __regargs
  27. ScanNodeFilter(register STRPTR Data,register LONG Size,register struct WaitNode *Node)
  28. {
  29.     register UBYTE c,Mask;
  30.  
  31.     if(Config -> SerialConfig -> StripBit8)
  32.         Mask = 0x7F;
  33.     else
  34.         Mask = 0xFF;
  35.  
  36.     if(Node)
  37.     {
  38.         do
  39.         {
  40.             if(c = ToUpper((*Data++) & Mask))
  41.             {
  42.                 register BYTE MatchMade;
  43.  
  44.                 do
  45.                 {
  46.                     MatchMade = FALSE;
  47.  
  48.                     if(Node -> Count == WaitCount)
  49.                     {
  50.                         if(c == Node -> Node . ln_Name[WaitCount] & Mask)
  51.                         {
  52.                             MatchMade = TRUE;
  53.  
  54.                             if(!Node -> Node . ln_Name[++Node -> Count])
  55.                                 return(Node -> Node . ln_Name);
  56.                         }
  57.                     }
  58.  
  59.                     if(MatchMade)
  60.                         WaitCount++;
  61.                     else
  62.                     {
  63.                         if(WaitCount)
  64.                         {
  65.                             WaitCount = 0;
  66.  
  67.                             Node -> Count = 0;
  68.                         }
  69.                         else
  70.                             break;
  71.                     }
  72.                 }
  73.                 while(!WaitCount);
  74.             }
  75.         }
  76.         while(--Size);
  77.     }
  78.     else
  79.     {
  80.         do
  81.         {
  82.             if(c = ToUpper((*Data++) & Mask))
  83.             {
  84.                 register BYTE MatchMade;
  85.  
  86.                 do
  87.                 {
  88.                     MatchMade = FALSE;
  89.  
  90.                     Node = (struct WaitNode *)GenericListTable[GLIST_WAIT] -> ListHeader . mlh_Head;
  91.  
  92.                     while(Node -> Node . ln_Succ)
  93.                     {
  94.                         if(Node -> Count == WaitCount)
  95.                         {
  96.                             if(c == Node -> Node . ln_Name[WaitCount] & Mask)
  97.                             {
  98.                                 Node -> Count++;
  99.  
  100.                                 MatchMade = TRUE;
  101.  
  102.                                 if(!Node -> Node . ln_Name[Node -> Count])
  103.                                     return(Node -> Node . ln_Name);
  104.                             }
  105.                         }
  106.  
  107.                         Node = (struct WaitNode *)Node -> Node . ln_Succ;
  108.                     }
  109.  
  110.                     if(MatchMade)
  111.                         WaitCount++;
  112.                     else
  113.                     {
  114.                         if(WaitCount)
  115.                         {
  116.                             WaitCount = 0;
  117.  
  118.                             Node = (struct WaitNode *)GenericListTable[GLIST_WAIT] -> ListHeader . mlh_Head;
  119.  
  120.                             while(Node -> Node . ln_Succ)
  121.                             {
  122.                                 Node -> Count = 0;
  123.  
  124.                                 Node = (struct WaitNode *)Node -> Node . ln_Succ;
  125.                             }
  126.                         }
  127.                         else
  128.                             break;
  129.                     }
  130.                 }
  131.                 while(!WaitCount);
  132.             }
  133.         }
  134.         while(--Size);
  135.     }
  136.  
  137.     return(NULL);
  138. }
  139.  
  140.     /* LocalRexxSerialCommandServer(VOID):
  141.      *
  142.      *    Asynchronous process to execute SerialCommand() style
  143.      *    ARexx commands.
  144.      */
  145.  
  146. STATIC VOID __saveds
  147. LocalRexxSerialCommandServer(VOID)
  148. {
  149.     struct Process    *ThisProcess = (struct Process *)SysBase -> ThisTask;
  150.     struct Message    *Message;
  151.     BPTR         OldCOS,
  152.              NewCOS    = NULL;
  153.     struct MsgPort    *RexxPort;
  154.  
  155.     WaitPort(&ThisProcess -> pr_MsgPort);
  156.  
  157.     Message = GetMsg(&ThisProcess -> pr_MsgPort);
  158.  
  159.     ObtainSemaphore(&RexxLaunchSemaphore);
  160.  
  161.     RexxLaunchCount++;
  162.  
  163.     ReleaseSemaphore(&RexxLaunchSemaphore);
  164.  
  165.     if(!ThisProcess -> pr_COS && ThisProcess -> pr_ConsoleTask)
  166.     {
  167.         if(NewCOS = Open("*",MODE_NEWFILE))
  168.         {
  169.             OldCOS = ThisProcess -> pr_COS;
  170.  
  171.             ThisProcess -> pr_COS = NewCOS;
  172.         }
  173.     }
  174.  
  175.     if(RexxPort = FindPort(RXSDIR))
  176.     {
  177.         struct MsgPort __aligned     SinglePort;
  178.         struct RexxMsg            *HostMessage;
  179.  
  180.         InitSinglePort(&SinglePort);
  181.  
  182.         if(HostMessage = CreateRexxMsg(&SinglePort,"term",RexxPortName))
  183.         {
  184.             if(HostMessage -> rm_Args[0] = CreateArgstring(Message -> mn_Node . ln_Name,strlen(Message -> mn_Node . ln_Name)))
  185.             {
  186.                 HostMessage -> rm_Action = RXCOMM;
  187.  
  188.                 if(!GoodStream(NULL))
  189.                     HostMessage -> rm_Action |= RXFF_NOIO;
  190.  
  191.                 Forbid();
  192.  
  193.                 PutMsg(RexxPort,HostMessage);
  194.  
  195.                 ClrSignal(SIGF_SINGLE);
  196.  
  197.                 WaitPort(&SinglePort);
  198.  
  199.                 Permit();
  200.  
  201.                 GetMsg(&SinglePort);
  202.             }
  203.  
  204.             DeleteRexxMsg(HostMessage);
  205.         }
  206.     }
  207.  
  208.     Forbid();
  209.  
  210.     ObtainSemaphore(&RexxLaunchSemaphore);
  211.  
  212.     RexxLaunchCount--;
  213.  
  214.     ReleaseSemaphore(&RexxLaunchSemaphore);
  215.  
  216.     if(NewCOS)
  217.     {
  218.         ThisProcess -> pr_COS = OldCOS;
  219.  
  220.         Close(NewCOS);
  221.     }
  222.  
  223.     ReplyMsg(Message);
  224. }
  225.  
  226.     /* LocalAmigaDOSSerialCommandServer(VOID):
  227.      *
  228.      *    Asynchronous process to execute SerialCommand() style
  229.      *    AmigaDOS commands.
  230.      */
  231.  
  232. STATIC VOID __saveds
  233. LocalAmigaDOSSerialCommandServer(VOID)
  234. {
  235.     struct Process    *ThisProcess = (struct Process *)SysBase -> ThisTask;
  236.     struct Message    *Message;
  237.     BPTR         OldCOS,
  238.              NewCOS    = NULL;
  239.  
  240.     WaitPort(&ThisProcess -> pr_MsgPort);
  241.  
  242.     Message = GetMsg(&ThisProcess -> pr_MsgPort);
  243.  
  244.     ObtainSemaphore(&RexxLaunchSemaphore);
  245.  
  246.     RexxLaunchCount++;
  247.  
  248.     ReleaseSemaphore(&RexxLaunchSemaphore);
  249.  
  250.     if(!ThisProcess -> pr_COS && ThisProcess -> pr_ConsoleTask)
  251.     {
  252.         if(NewCOS = Open("*",MODE_NEWFILE))
  253.         {
  254.             OldCOS = ThisProcess -> pr_COS;
  255.  
  256.             ThisProcess -> pr_COS = NewCOS;
  257.         }
  258.     }
  259.  
  260.     SystemTags(Message -> mn_Node . ln_Name,TAG_DONE);
  261.  
  262.     Forbid();
  263.  
  264.     ObtainSemaphore(&RexxLaunchSemaphore);
  265.  
  266.     RexxLaunchCount--;
  267.  
  268.     ReleaseSemaphore(&RexxLaunchSemaphore);
  269.  
  270.     if(NewCOS)
  271.     {
  272.         ThisProcess -> pr_COS = OldCOS;
  273.  
  274.         Close(NewCOS);
  275.     }
  276.  
  277.     ReplyMsg(Message);
  278. }
  279.  
  280.     /* LocalRexxSerialCommand(STRPTR Command,struct RexxPkt *Pkt):
  281.      *
  282.      *    Executes SerialCommand() style strings.
  283.      */
  284.  
  285. STATIC VOID __regargs
  286. LocalRexxSerialCommand(STRPTR Command,struct RexxPkt *Pkt)
  287. {
  288.     LONG Len = strlen(Command);
  289.  
  290.     if(Len)
  291.     {
  292.         BYTE    GotCommand = FALSE;
  293.         LONG    RexxIndex = -1,
  294.             AmigaDOSIndex = -1,
  295.             i;
  296.  
  297.             /* Check for embedded commands. */
  298.  
  299.         for(i = 0 ; i < Len ; i++)
  300.         {
  301.                 /* Found an escape symbol? */
  302.  
  303.             if(Command[i] == '\\')
  304.             {
  305.                     /* Is an ARexx command to be executed? */
  306.  
  307.                 switch(Command[i + 1])
  308.                 {
  309.                     case 'a':
  310.                     case 'A':
  311.                             /* Cut off the remaining string. */
  312.  
  313.                         Len = i;
  314.  
  315.                             /* Remember where to look for the rexx command. */
  316.  
  317.                         RexxIndex = i + 2;
  318.  
  319.                             /* Skip blanks. */
  320.  
  321.                         while((Command[RexxIndex] == '\t' || Command[RexxIndex] == ' ') && Command[RexxIndex])
  322.                             RexxIndex++;
  323.  
  324.                             /* No remaining data? */
  325.  
  326.                         if(!Command[RexxIndex])
  327.                             RexxIndex = -1;
  328.  
  329.                         break;
  330.  
  331.                     case 'd':
  332.                     case 'D':
  333.                             /* Cut off the remaining string. */
  334.  
  335.                         Len = i;
  336.  
  337.                             /* Remember where to look for the rexx command. */
  338.  
  339.                         AmigaDOSIndex = i + 2;
  340.  
  341.                             /* Skip blanks. */
  342.  
  343.                         while((Command[AmigaDOSIndex] == '\t' || Command[AmigaDOSIndex] == ' ') && Command[AmigaDOSIndex])
  344.                             AmigaDOSIndex++;
  345.  
  346.                             /* No remaining data? */
  347.  
  348.                         if(!Command[AmigaDOSIndex])
  349.                             AmigaDOSIndex = -1;
  350.  
  351.                         break;
  352.  
  353.                     default:
  354.  
  355.                         GotCommand = TRUE;
  356.                         break;
  357.                 }
  358.             }
  359.             else
  360.             {
  361.                     /* Found an escape symbol? */
  362.  
  363.                 if(Command[i] == '^')
  364.                     GotCommand = TRUE;
  365.             }
  366.         }
  367.  
  368.             /* Any text to be processed? */
  369.  
  370.         if(Len)
  371.         {
  372.                 /* Found a command? */
  373.  
  374.             if(GotCommand)
  375.             {
  376.                 STRPTR Buffer;
  377.  
  378.                     /* Allocate a temporary buffer. */
  379.  
  380.                 if(Buffer = (STRPTR)AllocVec(Len + 1,MEMF_ANY))
  381.                 {
  382.                         /* Copy the buffer. */
  383.  
  384.                     CopyMem(Command,Buffer,Len);
  385.  
  386.                         /* Null-terminate it. */
  387.  
  388.                     Buffer[Len] = 0;
  389.  
  390.                         /* Execute the commands. */
  391.  
  392.                     SerialCommand(Buffer);
  393.  
  394.                         /* Release the temporary buffers. */
  395.  
  396.                     FreeVec(Buffer);
  397.                 }
  398.                 else
  399.                 {
  400.                     if(Pkt)
  401.                     {
  402.                         Results[0] = RC_ERROR;
  403.                         Results[1] = ERROR_NO_FREE_STORE;
  404.                     }
  405.                 }
  406.             }
  407.             else
  408.                 (*SendLine)(Command,Len);
  409.         }
  410.  
  411.             /* Are we to execute any embedded ARexx commands? */
  412.  
  413.         if(RexxIndex != -1)
  414.         {
  415.             struct Message *Message;
  416.  
  417.                 /* Move up in the string. */
  418.  
  419.             Command += RexxIndex;
  420.  
  421.                 /* Determine remaining length. */
  422.  
  423.             Len = strlen(Command);
  424.  
  425.                 /* Allocate command message. */
  426.  
  427.             if(Message = (struct Message *)AllocVec(sizeof(struct Message) + Len + 1,MEMF_ANY | MEMF_PUBLIC | MEMF_CLEAR))
  428.             {
  429.                 struct Process    *NewProcess;
  430.                 BPTR         Stream;
  431.  
  432.                     /* Initialize the message. */
  433.  
  434.                 Message -> mn_Node . ln_Name    = (STRPTR)(Message + 1);
  435.                 Message -> mn_ReplyPort        = RexxPort;
  436.                 Message -> mn_Length        = sizeof(struct Message) + Len + 1;
  437.  
  438.                 strcpy(Message -> mn_Node . ln_Name,Command);
  439.  
  440.                     /* Open proper output stream. */
  441.  
  442.                 if(WindowName[0])
  443.                     Stream = Open(WindowName,MODE_NEWFILE);
  444.                 else
  445.                     Stream = NULL;
  446.  
  447.                     /* Spawn the server process. */
  448.  
  449.                 if(Stream && GoodStream(Stream))
  450.                 {
  451.                     struct FileHandle *Handle = (struct FileHandle *)BADDR(Stream);
  452.  
  453.                     NewProcess = CreateNewProcTags(
  454.                         NP_Entry,    LocalRexxSerialCommandServer,
  455.                         NP_Input,    Stream,
  456.                         NP_Output,    NULL,
  457.                         NP_ConsoleTask,    Handle -> fh_Type,
  458.                         NP_StackSize,    8000,
  459.                         NP_Name,    "term Rexx serial command process",
  460.                         NP_Cli,        TRUE,
  461.                     TAG_DONE);
  462.                 }
  463.                 else
  464.                 {
  465.                     NewProcess = CreateNewProcTags(
  466.                         NP_Entry,    LocalRexxSerialCommandServer,
  467.                         NP_StackSize,    8000,
  468.                         NP_ConsoleTask,    NULL,
  469.                         NP_Name,    "term Rexx serial command process",
  470.                         NP_Cli,        TRUE,
  471.                     TAG_DONE);
  472.                 }
  473.  
  474.                     /* Send the command message. */
  475.  
  476.                 if(NewProcess)
  477.                     PutMsg(&NewProcess -> pr_MsgPort,Message);
  478.                 else
  479.                 {
  480.                     if(Pkt)
  481.                     {
  482.                         Results[0] = RC_ERROR;
  483.                         Results[1] = IoErr();
  484.                     }
  485.  
  486.                     FreeVec(Message);
  487.  
  488.                     if(Stream)
  489.                         Close(Stream);
  490.                 }
  491.             }
  492.             else
  493.             {
  494.                 if(Pkt)
  495.                 {
  496.                     Results[0] = RC_ERROR;
  497.                     Results[1] = ERROR_NO_FREE_STORE;
  498.                 }
  499.             }
  500.         }
  501.  
  502.             /* Are we to execute an embedded AmigaDOS command? */
  503.  
  504.         if(AmigaDOSIndex != -1)
  505.         {
  506.             struct Message *Message;
  507.  
  508.                 /* Move up in the string. */
  509.  
  510.             Command += AmigaDOSIndex;
  511.  
  512.                 /* Determine remaining length. */
  513.  
  514.             Len = strlen(Command);
  515.  
  516.                 /* Allocate command message. */
  517.  
  518.             if(Message = (struct Message *)AllocVec(sizeof(struct Message) + Len + 1,MEMF_ANY | MEMF_PUBLIC | MEMF_CLEAR))
  519.             {
  520.                 struct Process    *NewProcess;
  521.                 BPTR         Stream;
  522.  
  523.                     /* Initialize the message. */
  524.  
  525.                 Message -> mn_Node . ln_Name    = (STRPTR)(Message + 1);
  526.                 Message -> mn_ReplyPort        = RexxPort;
  527.                 Message -> mn_Length        = sizeof(struct Message) + Len + 1;
  528.  
  529.                 strcpy(Message -> mn_Node . ln_Name,Command);
  530.  
  531.                     /* Open proper output stream. */
  532.  
  533.                 if(WindowName[0])
  534.                     Stream = Open(WindowName,MODE_NEWFILE);
  535.                 else
  536.                     Stream = NULL;
  537.  
  538.                     /* Spawn the server process. */
  539.  
  540.                 if(Stream && GoodStream(Stream))
  541.                 {
  542.                     struct FileHandle *Handle = (struct FileHandle *)BADDR(Stream);
  543.  
  544.                     NewProcess = CreateNewProcTags(
  545.                         NP_Entry,    LocalAmigaDOSSerialCommandServer,
  546.                         NP_Input,    Stream,
  547.                         NP_Output,    NULL,
  548.                         NP_ConsoleTask,    Handle -> fh_Type,
  549.                         NP_StackSize,    8000,
  550.                         NP_Name,    "term AmigaDOS serial command process",
  551.                         NP_Cli,        TRUE,
  552.                     TAG_DONE);
  553.                 }
  554.                 else
  555.                 {
  556.                     NewProcess = CreateNewProcTags(
  557.                         NP_Entry,    LocalAmigaDOSSerialCommandServer,
  558.                         NP_StackSize,    8000,
  559.                         NP_ConsoleTask,    NULL,
  560.                         NP_Name,    "term AmigaDOS serial command process",
  561.                         NP_Cli,        TRUE,
  562.                     TAG_DONE);
  563.                 }
  564.  
  565.                     /* Send the command message. */
  566.  
  567.                 if(NewProcess)
  568.                     PutMsg(&NewProcess -> pr_MsgPort,Message);
  569.                 else
  570.                 {
  571.                     if(Pkt)
  572.                     {
  573.                         Results[0] = RC_ERROR;
  574.                         Results[1] = IoErr();
  575.                     }
  576.  
  577.                     if(Stream)
  578.                         Close(Stream);
  579.  
  580.                     FreeVec(Message);
  581.                 }
  582.             }
  583.             else
  584.             {
  585.                 if(Pkt)
  586.                 {
  587.                     Results[0] = RC_ERROR;
  588.                     Results[1] = ERROR_NO_FREE_STORE;
  589.                 }
  590.             }
  591.         }
  592.     }
  593. }
  594.  
  595. STRPTR __regargs
  596. RexxActivate(struct RexxPkt *Pkt)
  597. {
  598.     if(Window)
  599.         BumpWindow(Window);
  600.     else
  601.     {
  602.         if(!IconTerminated)
  603.             IconTerminated = TRUE;
  604.     }
  605.  
  606.     return(NULL);
  607. }
  608.  
  609. STRPTR __regargs
  610. RexxAdd(struct RexxPkt *Pkt)
  611. {
  612.     enum    {    ARG_ADD_FROM,ARG_ADD_BEFORE,ARG_ADD_AFTER,ARG_ADD_PHONEENTRY,
  613.             ARG_ADD_NAME };
  614.  
  615.     WORD ListIndex;
  616.  
  617.     if((ListIndex = ToList(Args[ARG_ADD_FROM])) != -1)
  618.     {
  619.         struct GenericList    *List = GenericListTable[ListIndex];
  620.         BYTE             AddMode;
  621.  
  622.         if(Args[ARG_ADD_BEFORE])
  623.             AddMode = ADD_GLIST_BEFORE;
  624.         else
  625.         {
  626.             if(Args[ARG_ADD_AFTER])
  627.                 AddMode = ADD_GLIST_BEHIND;
  628.             else
  629.                 AddMode = ADD_GLIST_BOTTOM;
  630.         }
  631.  
  632.         if(ListIndex == GLIST_DIAL)
  633.         {
  634.             if(Args[ARG_ADD_PHONEENTRY])
  635.             {
  636.                 if(!IsNumeric(Args[ARG_ADD_PHONEENTRY]))
  637.                 {
  638.                     STRPTR Buffer;
  639.  
  640.                     if(Buffer = CreateMatchBuffer(Args[ARG_ADD_PHONEENTRY]))
  641.                     {
  642.                         struct DialNode    *Node;
  643.                         LONG         i;
  644.  
  645.                         for(i = 0 ; i < NumPhoneEntries ; i++)
  646.                         {
  647.                             if(MatchBuffer(Buffer,Phonebook[i] -> Header -> Name))
  648.                             {
  649.                                 if(Node = (struct DialNode *)CreateGenericListNode(sizeof(struct DialNode),NULL))
  650.                                 {
  651.                                     Node -> Entry = Phonebook[i];
  652.  
  653.                                     AddGenericListNode(List,(struct Node *)Node,AddMode);
  654.                                 }
  655.                                 else
  656.                                 {
  657.                                     Results[0] = RC_ERROR;
  658.                                     Results[1] = ERROR_NO_FREE_STORE;
  659.  
  660.                                     break;
  661.                                 }
  662.                             }
  663.                         }
  664.  
  665.                         DeleteMatchBuffer(Buffer);
  666.                     }
  667.                     else
  668.                     {
  669.                         Results[0] = RC_ERROR;
  670.                         Results[1] = ERROR_NO_FREE_STORE;
  671.                     }
  672.                 }
  673.                 else
  674.                 {
  675.                     LONG Index = Atol(Args[ARG_ADD_PHONEENTRY]);
  676.  
  677.                     if(Index < 0 || Index > NumPhoneEntries)
  678.                     {
  679.                         Results[0] = RC_ERROR;
  680.                         Results[1] = TERMERROR_INDEX_OUT_OF_RANGE;
  681.                     }
  682.                     else
  683.                     {
  684.                         struct DialNode    *Node;
  685.  
  686.                         if(Node = (struct DialNode *)CreateGenericListNode(sizeof(struct DialNode),NULL))
  687.                         {
  688.                             Node -> Entry = Phonebook[Index];
  689.  
  690.                             AddGenericListNode(List,(struct Node *)Node,AddMode);
  691.                         }
  692.                         else
  693.                         {
  694.                             Results[0] = RC_ERROR;
  695.                             Results[1] = ERROR_NO_FREE_STORE;
  696.                         }
  697.                     }
  698.                 }
  699.             }
  700.             else
  701.             {
  702.                 if(Args[ARG_ADD_NAME])
  703.                 {
  704.                     struct Node *Node;
  705.  
  706.                     if(Node = CreateGenericListNode(sizeof(struct DialNode),Args[ARG_ADD_NAME]))
  707.                         AddGenericListNode(List,Node,AddMode);
  708.                     else
  709.                     {
  710.                         Results[0] = RC_ERROR;
  711.                         Results[1] = ERROR_NO_FREE_STORE;
  712.                     }
  713.                 }
  714.             }
  715.         }
  716.         else
  717.         {
  718.             if(Args[ARG_ADD_NAME])
  719.             {
  720.                 struct Node *Node;
  721.  
  722.                 if(Node = CreateGenericListNode(sizeof(struct DialNode),Args[ARG_ADD_NAME]))
  723.                 {
  724.                     if(ListIndex == GLIST_WAIT)
  725.                     {
  726.                         WORD i;
  727.  
  728.                         for(i = 0 ; i < strlen(Node -> ln_Name) ; i++)
  729.                             Node -> ln_Name[i] = ToUpper(Node -> ln_Name[i]);
  730.                     }
  731.  
  732.                     AddGenericListNode(List,Node,AddMode);
  733.                 }
  734.                 else
  735.                 {
  736.                     Results[0] = RC_ERROR;
  737.                     Results[1] = ERROR_NO_FREE_STORE;
  738.                 }
  739.             }
  740.             else
  741.             {
  742.                 Results[0] = RC_ERROR;
  743.                 Results[1] = TERMERROR_WRONG_LIST;
  744.             }
  745.         }
  746.     }
  747.     else
  748.     {
  749.         Results[0] = RC_ERROR;
  750.         Results[1] = TERMERROR_UNKNOWN_LIST;
  751.     }
  752.  
  753.     return(NULL);
  754. }
  755.  
  756. STRPTR __regargs
  757. RexxBaud(struct RexxPkt *Pkt)
  758. {
  759.     enum    {    ARG_BAUD_RATE };
  760.  
  761.     LONG Rate = *(LONG *)Args[ARG_BAUD_RATE],Min = MILLION,Diff,Index;
  762.     WORD i;
  763.  
  764.     for(i = 0 ; i < NumBaudRates ; i++)
  765.     {
  766.         Diff = Rate - BaudRates[i];
  767.  
  768.         if(Diff >= 0 && Diff < Min)
  769.         {
  770.             Min    = Diff;
  771.             Index    = i;
  772.         }
  773.     }
  774.  
  775.     if(BaudRates[Index] != Config -> SerialConfig -> BaudRate)
  776.     {
  777.         Config -> SerialConfig -> BaudRate = BaudRates[Index];
  778.  
  779.         ConfigChanged = TRUE;
  780.  
  781.         UpdateRequired = TRUE;
  782.     }
  783.  
  784.     return(NULL);
  785. }
  786.  
  787. STRPTR __regargs
  788. RexxBeepScreen(struct RexxPkt *Pkt)
  789. {
  790.     DoBeep();
  791.  
  792.     return(NULL);
  793. }
  794.  
  795. STRPTR __regargs
  796. RexxCallMenu(struct RexxPkt *Pkt)
  797. {
  798.     enum    {    ARG_CALLMENU_TITLE };
  799.  
  800.     STRPTR Buffer;
  801.  
  802.     if(Buffer = CreateMatchBuffer(Args[ARG_CALLMENU_TITLE]))
  803.     {
  804.         WORD i;
  805.  
  806.         Results[0] = RC_WARN;
  807.  
  808.             /* Scan the menu list... */
  809.  
  810.         for(i = 0 ; TermMenu[i] . nm_Type != NM_END ; i++)
  811.         {
  812.                 /* Did we get a valid name string? */
  813.  
  814.             if(TermMenu[i] . nm_Label != NM_BARLABEL)
  815.             {
  816.                     /* Does the name match our template? */
  817.  
  818.                 if(MatchBuffer(Buffer,TermMenu[i] . nm_Label))
  819.                 {
  820.                     HandleMenuCode((ULONG)TermMenu[i] . nm_UserData,NULL);
  821.  
  822.                     Results[0] = RC_OK;
  823.  
  824.                     break;
  825.                 }
  826.             }
  827.         }
  828.  
  829.         DeleteMatchBuffer(Buffer);
  830.     }
  831.     else
  832.     {
  833.         Results[0] = RC_ERROR;
  834.         Results[1] = ERROR_NO_FREE_STORE;
  835.     }
  836.  
  837.     return(NULL);
  838. }
  839.  
  840. STRPTR __regargs
  841. RexxCapture(struct RexxPkt *Pkt)
  842. {
  843.     enum    {    ARG_CAPTURE_TO,ARG_CAPTURE_NAME };
  844.  
  845.     if(!Stricmp(Args[ARG_CAPTURE_TO],"PRINTER"))
  846.     {
  847.         if(!PrinterCapture)
  848.             OpenPrinterCapture(FALSE);
  849.     }
  850.     else
  851.     {
  852.         if(!Stricmp(Args[ARG_CAPTURE_TO],"FILE"))
  853.         {
  854.             if(FileCapture)
  855.             {
  856.                 Results[0] = RC_ERROR;
  857.                 Results[1] = ERROR_OBJECT_IN_USE;
  858.             }
  859.             else
  860.             {
  861.                 if(Args[ARG_CAPTURE_NAME])
  862.                 {
  863.                     if(FileCapture = BufferOpen(Args[ARG_CAPTURE_NAME],"a"))
  864.                         strcpy(CaptureName,Args[ARG_CAPTURE_NAME]);
  865.                     else
  866.                     {
  867.                         Results[0] = RC_ERROR;
  868.                         Results[1] = IoErr();
  869.                     }
  870.                 }
  871.                 else
  872.                 {
  873.                     UBYTE             DummyBuffer[MAX_FILENAME_LENGTH],
  874.                                 *DummyChar;
  875.                     struct FileRequester    *FileRequest;
  876.  
  877.                     if(!CaptureName[0])
  878.                     {
  879.                         strcpy(CaptureName,Config -> CaptureConfig -> CapturePath);
  880.  
  881.                         if(!AddPart(CaptureName,LocaleString(MSG_DIALPANEL_CAPTURE_NAME_TXT),MAX_FILENAME_LENGTH))
  882.                             CaptureName[0] = 0;
  883.                     }
  884.  
  885.                     strcpy(DummyBuffer,CaptureName);
  886.  
  887.                     DummyChar = PathPart(DummyBuffer);
  888.  
  889.                     *DummyChar = 0;
  890.  
  891.                     BlockWindows();
  892.  
  893.                     if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_CAPTURE_TO_DISK_TXT),DummyBuffer,FilePart(CaptureName),DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_OPEN_TXT),FALSE))
  894.                     {
  895.                         BYTE Continue;
  896.  
  897.                         if(GetFileSize(DummyBuffer))
  898.                         {
  899.                             Continue = TRUE;
  900.  
  901.                             switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  902.                             {
  903.                                 case 1:
  904.  
  905.                                     FileCapture = BufferOpen(DummyBuffer,"w");
  906.                                     break;
  907.  
  908.                                 case 2:
  909.  
  910.                                     FileCapture = BufferOpen(DummyBuffer,"a");
  911.                                     break;
  912.  
  913.                                 case 0:
  914.  
  915.                                     Results[0] = RC_WARN;
  916.                                     Continue = FALSE;
  917.                                     break;
  918.                             }
  919.                         }
  920.                         else
  921.                         {
  922.                             Continue = TRUE;
  923.  
  924.                             FileCapture = BufferOpen(DummyBuffer,"w");
  925.                         }
  926.  
  927.                         if(Continue)
  928.                         {
  929.                             if(!FileCapture)
  930.                             {
  931.                                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  932.  
  933.                                 Results[0] = RC_ERROR;
  934.                                 Results[1] = IoErr();
  935.                             }
  936.                             else
  937.                             {
  938.                                 strcpy(CaptureName,DummyBuffer);
  939.  
  940.                                 CheckItem(MEN_CAPTURE_TO_FILE,TRUE);
  941.                             }
  942.                         }
  943.  
  944.                         FreeAslRequest(FileRequest);
  945.                     }
  946.  
  947.                     ReleaseWindows();
  948.                 }
  949.             }
  950.         }
  951.         else
  952.         {
  953.             Results[0] = RC_ERROR;
  954.             Results[1] = ERROR_REQUIRED_ARG_MISSING;
  955.         }
  956.     }
  957.  
  958.     ConOutputUpdate();
  959.  
  960.     return(NULL);
  961. }
  962.  
  963. STRPTR __regargs
  964. RexxClear(struct RexxPkt *Pkt)
  965. {
  966.     enum    {    ARG_CLEAR_FROM,ARG_CLEAR_FORCE };
  967.  
  968.     if(!Stricmp(Args[ARG_CLEAR_FROM],"BUFFER"))
  969.     {
  970.         if(Lines)
  971.         {
  972.             if(Args[ARG_CLEAR_FORCE])
  973.             {
  974.                 FreeBuffer();
  975.  
  976.                 TerminateBuffer();
  977.             }
  978.             else
  979.             {
  980.                 BlockWindows();
  981.  
  982.                 if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
  983.                 {
  984.                     FreeBuffer();
  985.  
  986.                     TerminateBuffer();
  987.                 }
  988.                 else
  989.                     Results[0] = RC_WARN;
  990.  
  991.                 ReleaseWindows();
  992.             }
  993.         }
  994.     }
  995.     else
  996.     {
  997.         WORD ListIndex;
  998.  
  999.         if((ListIndex = ToList(Args[ARG_CLEAR_FROM])) != -1)
  1000.             ClearGenericList(GenericListTable[ListIndex]);
  1001.         else
  1002.         {
  1003.             Results[0] = RC_ERROR;
  1004.             Results[1] = TERMERROR_UNKNOWN_LIST;
  1005.         }
  1006.     }
  1007.  
  1008.     return(NULL);
  1009. }
  1010.  
  1011. STRPTR __regargs
  1012. RexxClearScreen(struct RexxPkt *Pkt)
  1013. {
  1014.     if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  1015.         XEmulatorClearConsole(XEM_IO);
  1016.     else
  1017.     {
  1018.         DropMarker();
  1019.  
  1020.         ClearCursor();
  1021.  
  1022.         EraseScreen("2J");
  1023.  
  1024.         SetAbsolutePosition("H");
  1025.  
  1026.         DrawCursor();
  1027.     }
  1028.  
  1029.     return(NULL);
  1030. }
  1031.  
  1032. STRPTR __regargs
  1033. RexxClose(struct RexxPkt *Pkt)
  1034. {
  1035.     enum    {    ARG_CLOSE_FROM };
  1036.  
  1037.     STATIC STRPTR ValidArgs[3] =
  1038.     {
  1039.         "PRINTER",
  1040.         "FILE",
  1041.         "ALL"
  1042.     };
  1043.  
  1044.     WORD i;
  1045.  
  1046.     for(i = 0 ; i < 3 ; i++)
  1047.     {
  1048.         if(!Stricmp(Args[ARG_CLOSE_FROM],ValidArgs[i]))
  1049.         {
  1050.             if(i == 0 || i == 2)
  1051.             {
  1052.                 if(PrinterCapture)
  1053.                     ClosePrinterCapture(TRUE);
  1054.             }
  1055.  
  1056.             if(i == 1 || i == 2)
  1057.             {
  1058.                 if(FileCapture)
  1059.                 {
  1060.                     BufferClose(FileCapture);
  1061.  
  1062.                     CheckItem(MEN_CAPTURE_TO_FILE,FALSE);
  1063.  
  1064.                     FileCapture = NULL;
  1065.  
  1066.                     if(!GetFileSize(CaptureName))
  1067.                         DeleteFile(CaptureName);
  1068.                     else
  1069.                     {
  1070.                         AddProtection(CaptureName,FIBF_EXECUTE);
  1071.  
  1072.                         if(Config -> MiscConfig -> CreateIcons)
  1073.                             AddIcon(CaptureName,FILETYPE_TEXT,TRUE);
  1074.                     }
  1075.  
  1076.                     ConOutputUpdate();
  1077.                 }
  1078.             }
  1079.  
  1080.             return(NULL);
  1081.         }
  1082.     }
  1083.  
  1084.     Results[0] = RC_ERROR;
  1085.     Results[1] = ERROR_TOO_MANY_ARGS;
  1086.  
  1087.     return(NULL);
  1088. }
  1089.  
  1090. STRPTR __regargs
  1091. RexxCloseDevice(struct RexxPkt *Pkt)
  1092. {
  1093.     ClearSerial();
  1094.  
  1095.     DeleteSerial();
  1096.  
  1097.     return(NULL);
  1098. }
  1099.  
  1100. STRPTR __regargs
  1101. RexxCloseRequester(struct RexxPkt *Pkt)
  1102. {
  1103.     if(ThisProcess)
  1104.         Signal(ThisProcess,SIG_BREAK);
  1105.     else
  1106.         Results[0] = RC_WARN;
  1107.  
  1108.     return(NULL);
  1109. }
  1110.  
  1111. STRPTR __regargs
  1112. RexxDeactivate(struct RexxPkt *Pkt)
  1113. {
  1114.     if(Window)
  1115.         DoIconify = TRUE;
  1116.  
  1117.     return(NULL);
  1118. }
  1119.  
  1120. STRPTR __regargs
  1121. RexxDial(struct RexxPkt *Pkt)
  1122. {
  1123.     enum    {    ARG_DIAL_NUM };
  1124.  
  1125.     struct PhoneNode    *DialNode;
  1126.     struct GenericList    *List;
  1127.  
  1128.     if(Args[ARG_DIAL_NUM])
  1129.     {
  1130.         struct List *LocalList;
  1131.  
  1132.         if(LocalList = (struct List *)AllocVec(sizeof(struct List),MEMF_ANY))
  1133.         {
  1134.             LONG Len = strlen(Args[ARG_DIAL_NUM]);
  1135.  
  1136.             NewList(LocalList);
  1137.  
  1138.             if(DialNode = (struct PhoneNode *)AllocVec(sizeof(struct PhoneNode) + Len + 1,MEMF_ANY | MEMF_CLEAR))
  1139.             {
  1140.                 DialNode -> VanillaNode . ln_Name = (STRPTR)(DialNode + 1);
  1141.  
  1142.                 strcpy(DialNode -> VanillaNode . ln_Name,Args[ARG_DIAL_NUM]);
  1143.  
  1144.                 AddTail(LocalList,&DialNode -> VanillaNode);
  1145.  
  1146.                 FreeDialList(TRUE);
  1147.  
  1148.                 DialList = LocalList;
  1149.             }
  1150.             else
  1151.             {
  1152.                 FreeVec(LocalList);
  1153.  
  1154.                 Results[0] = RC_ERROR;
  1155.                 Results[1] = ERROR_NO_FREE_STORE;
  1156.  
  1157.                 return(NULL);
  1158.             }
  1159.         }
  1160.     }
  1161.     else
  1162.     {
  1163.         if(GenericListCount(List = GenericListTable[GLIST_DIAL]))
  1164.         {
  1165.             struct DialNode *Node = (struct DialNode *)FirstGenericListNode(List);
  1166.  
  1167.             if(Node)
  1168.             {
  1169.                 LONG Len;
  1170.  
  1171.                 if(!DialList)
  1172.                 {
  1173.                     if(DialList = (struct List *)AllocVec(sizeof(struct List),MEMF_ANY | MEMF_CLEAR))
  1174.                         NewList(DialList);
  1175.                 }
  1176.  
  1177.                 if(DialList)
  1178.                 {
  1179.                     while(Node)
  1180.                     {
  1181.                         if(Node -> Entry)
  1182.                             Len = 0;
  1183.                         else
  1184.                             Len = strlen(Node -> Node . ln_Name) + 1;
  1185.  
  1186.                         if(DialNode = (struct PhoneNode *)AllocVec(sizeof(struct PhoneNode) + Len,MEMF_ANY | MEMF_CLEAR))
  1187.                         {
  1188.                             if(Node -> Entry)
  1189.                                 DialNode -> Entry = Node -> Entry;
  1190.                             else
  1191.                             {
  1192.                                 DialNode -> VanillaNode . ln_Name = (STRPTR)(DialNode + 1);
  1193.  
  1194.                                 strcpy(DialNode -> VanillaNode . ln_Name,Node -> Node . ln_Name);
  1195.                             }
  1196.  
  1197.                             AddTail(DialList,&DialNode -> VanillaNode);
  1198.                         }
  1199.                         else
  1200.                         {
  1201.                             FreeDialList(FALSE);
  1202.  
  1203.                             Results[0] = RC_ERROR;
  1204.                             Results[1] = ERROR_NO_FREE_STORE;
  1205.  
  1206.                             return(NULL);
  1207.                         }
  1208.  
  1209.                         Node = (struct DialNode *)NextGenericListNode(List);
  1210.                     }
  1211.                 }
  1212.             }
  1213.         }
  1214.     }
  1215.  
  1216.     if(DialList)
  1217.     {
  1218.         if(DialList -> lh_Head -> ln_Succ)
  1219.             DoDial = DIAL_LIST;
  1220.         else
  1221.         {
  1222.             FreeDialList(FALSE);
  1223.  
  1224.             Results[0] = RC_ERROR;
  1225.             Results[1] = TERMERROR_LIST_IS_ALREADY_EMPTY;
  1226.         }
  1227.     }
  1228.     else
  1229.     {
  1230.         Results[0] = RC_ERROR;
  1231.         Results[1] = ERROR_NO_FREE_STORE;
  1232.     }
  1233.  
  1234.     return(NULL);
  1235. }
  1236.  
  1237. STRPTR __regargs
  1238. RexxDelay(struct RexxPkt *Pkt)
  1239. {
  1240.     enum    {    ARG_DELAY_MICROSECONDS,ARG_DELAY_SECONDS,ARG_DELAY_MINUTES,ARG_DELAY_QUIET };
  1241.  
  1242.     LONG    Seconds = 0,
  1243.         Micros;
  1244.     ULONG    Signals;
  1245.     BYTE    Quiet;
  1246.  
  1247.     if(Args[ARG_DELAY_QUIET] || !ReadRequest || !WriteRequest)
  1248.         Quiet = TRUE;
  1249.     else
  1250.         Quiet = FALSE;
  1251.  
  1252.     if(Args[ARG_DELAY_MINUTES])
  1253.         Seconds += 60 * (*(LONG *)Args[ARG_DELAY_MINUTES]);
  1254.  
  1255.     if(Args[ARG_DELAY_SECONDS])
  1256.         Seconds += *(LONG *)Args[ARG_DELAY_SECONDS];
  1257.  
  1258.     if(Args[ARG_DELAY_MICROSECONDS])
  1259.         Micros = *(LONG *)Args[ARG_DELAY_MICROSECONDS];
  1260.     else
  1261.         Micros = 0;
  1262.  
  1263.     if(Seconds || Micros)
  1264.     {
  1265.         StartTime(Seconds,Micros);
  1266.  
  1267.         BlockWindows();
  1268.  
  1269.         if(Quiet)
  1270.             Signals = NULL;
  1271.         else
  1272.             Signals = CheckSignal(SIG_SERIAL);
  1273.  
  1274.         FOREVER
  1275.         {
  1276.             if(Signals & SIG_SERIAL)
  1277.             {
  1278.                 if(!WaitIO(ReadRequest))
  1279.                 {
  1280.                     LONG Length;
  1281.  
  1282.                     BytesIn++;
  1283.  
  1284.                     ConProcess(ReadBuffer,1);
  1285.  
  1286.                     Status = STATUS_READY;
  1287.  
  1288.                     do
  1289.                     {
  1290.                             /* Check how many bytes are still in
  1291.                              * the serial buffer.
  1292.                              */
  1293.  
  1294.                         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  1295.  
  1296.                         DoIO(WriteRequest);
  1297.  
  1298.                         if(Length = WriteRequest -> IOSer . io_Actual)
  1299.                         {
  1300.                             if(Length > Config -> SerialConfig -> SerialBufferSize)
  1301.                                 Length = Config -> SerialConfig -> SerialBufferSize;
  1302.  
  1303.                             ReadRequest -> IOSer . io_Command    = CMD_READ;
  1304.                             ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1305.                             ReadRequest -> IOSer . io_Length    = Length;
  1306.  
  1307.                             if(!DoIO(ReadRequest))
  1308.                             {
  1309.                                 BytesIn += Length;
  1310.  
  1311.                                     /* Send the data to the console. */
  1312.  
  1313.                                 ConProcess(ReadBuffer,Length);
  1314.  
  1315.                                 Status = STATUS_READY;
  1316.                             }
  1317.                         }
  1318.                     }
  1319.                     while(Length);
  1320.                 }
  1321.  
  1322.                 RestartSerial();
  1323.             }
  1324.  
  1325.             if(Signals & SIG_BREAK)
  1326.             {
  1327.                 if(!CheckIO(TimeRequest))
  1328.                     AbortIO(TimeRequest);
  1329.  
  1330.                 WaitIO(TimeRequest);
  1331.  
  1332.                 Results[0] = RC_WARN;
  1333.  
  1334.                 break;
  1335.             }
  1336.  
  1337.             if(Signals & SIG_TIMER)
  1338.             {
  1339.                 WaitIO(TimeRequest);
  1340.  
  1341.                 break;
  1342.             }
  1343.  
  1344.             if(Quiet)
  1345.                 Signals = Wait(SIG_TIMER | SIG_BREAK);
  1346.             else
  1347.                 Signals = Wait(SIG_TIMER | SIG_BREAK | SIG_SERIAL);
  1348.         }
  1349.  
  1350.         ReleaseWindows();
  1351.     }
  1352.  
  1353.     return(NULL);
  1354. }
  1355.  
  1356. STRPTR __regargs
  1357. RexxDuplex(struct RexxPkt *Pkt)
  1358. {
  1359.     enum    {    ARG_DUPLEX_FULL,ARG_DUPLEX_HALF };
  1360.  
  1361.     BYTE Mode;
  1362.  
  1363.     if(Args[ARG_DUPLEX_FULL])
  1364.         Mode = DUPLEX_FULL;
  1365.  
  1366.     if(Args[ARG_DUPLEX_HALF])
  1367.         Mode = DUPLEX_HALF;
  1368.  
  1369.     if(Config -> SerialConfig -> Duplex != Mode)
  1370.     {
  1371.         Config -> SerialConfig -> Duplex = Mode;
  1372.  
  1373.         UpdateRequired = TRUE;
  1374.  
  1375.         ConfigChanged = TRUE;
  1376.     }
  1377.  
  1378.     return(NULL);
  1379. }
  1380.  
  1381. STRPTR __regargs
  1382. RexxFault(struct RexxPkt *Pkt)
  1383. {
  1384.     enum    {    ARG_FAULT_CODE };
  1385.  
  1386.     LONG    Code = *(LONG *)Args[ARG_FAULT_CODE];
  1387.     UBYTE    RexxResultString[256];
  1388.     STRPTR    Result;
  1389.  
  1390.     if(Code >= ERR10_001 && Code <= ERR10_048)
  1391.         Result = LocaleString(MSG_AREXX_SYSERR10_001_TXT + Code - ERR10_001);
  1392.     else
  1393.     {
  1394.         if(Code >= TERMERROR_NO_DATA_TO_PROCESS && Code <= TERMERROR_WRONG_LIST)
  1395.             Result = LocaleString(MSG_AREXX_HOSTERR_000_TXT + Code - TERMERROR_NO_DATA_TO_PROCESS);
  1396.         else
  1397.         {
  1398.             Fault(Code,"",RexxResultString,256);
  1399.  
  1400.             Result = &RexxResultString[2];
  1401.         }
  1402.     }
  1403.  
  1404.     return(CreateResult(Result,Results));
  1405. }
  1406.  
  1407. STRPTR __regargs
  1408. RexxGetClip(struct RexxPkt *Pkt)
  1409. {
  1410.     enum    {    ARG_GETCLIP_UNIT };
  1411.  
  1412.     struct IFFHandle    *Handle;
  1413.     STRPTR             ResultBuffer = NULL;
  1414.  
  1415.     if(Handle = AllocIFF())
  1416.     {
  1417.         if(Args[ARG_GETCLIP_UNIT])
  1418.             Handle -> iff_Stream = (ULONG)OpenClipboard(*(LONG *)Args[ARG_GETCLIP_UNIT]);
  1419.         else
  1420.             Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit);
  1421.  
  1422.         if(Handle -> iff_Stream)
  1423.         {
  1424.             InitIFFasClip(Handle);
  1425.  
  1426.             if(!OpenIFF(Handle,IFFF_READ))
  1427.             {
  1428.                 if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  1429.                 {
  1430.                     if(!ParseIFF(Handle,IFFPARSE_SCAN))
  1431.                     {
  1432.                         struct ContextNode *ContextNode;
  1433.  
  1434.                         ContextNode = CurrentChunk(Handle);
  1435.  
  1436.                         if(ContextNode -> cn_Type == ID_FTXT && ContextNode -> cn_Size > 0)
  1437.                         {
  1438.                             STRPTR Result;
  1439.  
  1440.                             if(Result = (STRPTR)AllocVec(ContextNode -> cn_Size,MEMF_ANY))
  1441.                             {
  1442.                                 if(ReadChunkBytes(Handle,Result,ContextNode -> cn_Size) == ContextNode -> cn_Size)
  1443.                                     ResultBuffer = CreateArgstring(Result,ContextNode -> cn_Size);
  1444.  
  1445.                                 FreeVec(Result);
  1446.                             }
  1447.                             else
  1448.                             {
  1449.                                 Results[0] = RC_ERROR;
  1450.                                 Results[1] = ERROR_NO_FREE_STORE;
  1451.                             }
  1452.                         }
  1453.                         else
  1454.                             Results[0] = RC_WARN;
  1455.                     }
  1456.                     else
  1457.                     {
  1458.                         Results[0] = RC_ERROR;
  1459.                         Results[1] = ERROR_OBJECT_NOT_FOUND;
  1460.                     }
  1461.                 }
  1462.                 else
  1463.                 {
  1464.                     Results[0] = RC_ERROR;
  1465.                     Results[1] = ERROR_OBJECT_NOT_FOUND;
  1466.                 }
  1467.  
  1468.                 CloseIFF(Handle);
  1469.             }
  1470.             else
  1471.             {
  1472.                 Results[0] = RC_ERROR;
  1473.                 Results[1] = ERROR_OBJECT_NOT_FOUND;
  1474.             }
  1475.  
  1476.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  1477.         }
  1478.         else
  1479.         {
  1480.             Results[0] = RC_ERROR;
  1481.             Results[1] = TERMERROR_UNIT_NOT_AVAILABLE;
  1482.         }
  1483.  
  1484.         FreeIFF(Handle);
  1485.     }
  1486.     else
  1487.     {
  1488.         Results[0] = RC_ERROR;
  1489.         Results[1] = ERROR_OBJECT_NOT_FOUND;
  1490.     }
  1491.  
  1492.     return(ResultBuffer);
  1493. }
  1494.  
  1495. STRPTR __regargs
  1496. RexxHangup(struct RexxPkt *Pkt)
  1497. {
  1498.     BYTE OldStatus = Status;
  1499.  
  1500.     if(!WriteRequest)
  1501.     {
  1502.         Results[0] = RC_WARN;
  1503.  
  1504.         return(NULL);
  1505.     }
  1506.  
  1507.     BlockWindows();
  1508.  
  1509.     Status = STATUS_HANGUP;
  1510.  
  1511.         /* Are we to drop the DTR line
  1512.          * before sending the hangup
  1513.          * string?
  1514.          */
  1515.  
  1516.     if(Config -> ModemConfig -> DropDTR)
  1517.     {
  1518.             /* Let's be nice and try to transmit the
  1519.              * `drop the line' command before
  1520.              * trying to close and reopen the driver.
  1521.              */
  1522.  
  1523.         WriteRequest -> IOSer . io_Command    = SIOCMD_SETCTRLLINES;
  1524.         WriteRequest -> IOSer . io_Offset    = SIOB_DTRF;
  1525.         WriteRequest -> IOSer . io_Length    = 0;
  1526.  
  1527.             /* Transmit the command. */
  1528.  
  1529.         if(!DoIO(WriteRequest))
  1530.         {
  1531.                 /* Wait a bit... */
  1532.  
  1533.             WaitTime(1,0);
  1534.  
  1535.                 /* Raise the line again. */
  1536.  
  1537.             WriteRequest -> IOSer . io_Command    = SIOCMD_SETCTRLLINES;
  1538.             WriteRequest -> IOSer . io_Offset    = SIOB_DTRF;
  1539.             WriteRequest -> IOSer . io_Length    = SIOB_DTRF;
  1540.  
  1541.             DoIO(WriteRequest);
  1542.         }
  1543.         else
  1544.         {
  1545.                 /* Do it the standard way: close and reopen
  1546.                  * the serial driver (the serial.device is
  1547.                  * supposed to drop the DTR line when closed).
  1548.                  */
  1549.  
  1550.             if(!DropDTR())
  1551.             {
  1552.                 if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_REOPEN_UNIT_TXT),LocaleString(MSG_TERMMAIN_IGNORE_QUIT_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber))
  1553.                     MainTerminated = TRUE;
  1554.             }
  1555.         }
  1556.     }
  1557.  
  1558.         /* Transmit the hangup command. */
  1559.  
  1560.     LocalRexxSerialCommand(Config -> ModemConfig -> ModemHangup,NULL);
  1561.  
  1562.         /* Reset to old status. */
  1563.  
  1564.     Status = OldStatus;
  1565.  
  1566.         /* We are no longer online. */
  1567.  
  1568.     Online = FALSE;
  1569.  
  1570.         /* Reset time limit. */
  1571.  
  1572.     LimitCount = -1;
  1573.  
  1574.         /* Clear the password. */
  1575.  
  1576.     Password[0]        = 0;
  1577.     UserName[0]        = 0;
  1578.  
  1579.     CurrentBBSName[0]    = 0;
  1580.     CurrentBBSComment[0]    = 0;
  1581.     CurrentBBSNumber[0]    = 0;
  1582.  
  1583.         /* Note the  last action. */
  1584.  
  1585.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_TXT));
  1586.  
  1587.     ReleaseWindows();
  1588.  
  1589.         /* Execute logoff macro. */
  1590.  
  1591.     if(WasOnline)
  1592.         LocalRexxSerialCommand(Config -> CommandConfig -> LogoffMacro,NULL);
  1593.  
  1594.         /* Update the logfile. */
  1595.  
  1596.     StopCall(FALSE);
  1597.  
  1598.         /* Don't execute the logoff macro twice. */
  1599.  
  1600.     WasOnline = FALSE;
  1601.  
  1602.         /* Enable the dialing functions. */
  1603.  
  1604.     SetDialMenu(TRUE);
  1605.  
  1606.     Status = OldStatus;
  1607.  
  1608.     if(Config -> ModemConfig -> RedialAfterHangup)
  1609.     {
  1610.         if(DialList)
  1611.         {
  1612.             if(DialList -> lh_Head -> ln_Succ)
  1613.                 DoDial = DIAL_REDIAL;
  1614.         }
  1615.     }
  1616.  
  1617.     ChosenEntry = NULL;
  1618.  
  1619.     return(NULL);
  1620. }
  1621.  
  1622. STRPTR __regargs
  1623. RexxHelp(struct RexxPkt *Pkt)
  1624. {
  1625.     enum    {    ARG_HELP_COMMAND,ARG_HELP_PROMPT };
  1626.  
  1627.     if(Args[ARG_HELP_PROMPT])
  1628.         GuideSetup();
  1629.     else
  1630.     {
  1631.         WORD i;
  1632.  
  1633.         for(i = 0 ; i < CommandTableSize ; i++)
  1634.         {
  1635.             if(!Stricmp(Args[ARG_HELP_COMMAND],CommandTable[i] . Name))
  1636.             {
  1637.                 if(CommandTable[i] . Arguments)
  1638.                     return(CreateResult(CommandTable[i] . Arguments,Results));
  1639.                 else
  1640.                     return(CreateResult(",",Results));
  1641.             }
  1642.         }
  1643.  
  1644.         Results[0] = RC_ERROR;
  1645.         Results[1] = ERROR_OBJECT_NOT_FOUND;
  1646.     }
  1647.  
  1648.     return(NULL);
  1649. }
  1650.  
  1651. STRPTR __regargs
  1652. RexxOpen(struct RexxPkt *Pkt)
  1653. {
  1654.     enum    {    ARG_OPEN_NAME,ARG_OPEN_TO };
  1655.  
  1656.     WORD Index = ToConfig(Args[ARG_OPEN_TO]);
  1657.  
  1658.     if(Index == -1 || Index > DATATYPE_PHONEBOOK)
  1659.     {
  1660.         Results[0] = RC_ERROR;
  1661.         Results[1] = ERROR_OBJECT_NOT_FOUND;
  1662.     }
  1663.     else
  1664.     {
  1665.         UBYTE    DummyBuffer[MAX_FILENAME_LENGTH];
  1666.         STRPTR    FileName;
  1667.  
  1668.         if(Args[ARG_OPEN_NAME])
  1669.             FileName = Args[ARG_OPEN_NAME];
  1670.         else
  1671.         {
  1672.             STRPTR             Title;
  1673.             struct FileRequester    *FileRequest;
  1674.  
  1675.             FileName = NULL;
  1676.  
  1677.             switch(Index)
  1678.             {
  1679.                 case DATATYPE_TRANSLATIONS:
  1680.  
  1681.                     Title = LocaleString(MSG_PHONEPANEL_SELECT_TRANSLATION_TXT);
  1682.                     break;
  1683.  
  1684.                 case DATATYPE_FUNCTIONKEYS:
  1685.  
  1686.                     Title = LocaleString(MSG_PHONEPANEL_SELECT_KEYBOARD_MACROS_TXT);
  1687.                     break;
  1688.  
  1689.                 case DATATYPE_CURSORKEYS:
  1690.  
  1691.                     Title = LocaleString(MSG_PHONEPANEL_SELECT_CURSOR_KEYS_TXT);
  1692.                     break;
  1693.  
  1694.                 case DATATYPE_FASTMACROS:
  1695.  
  1696.                     Title = LocaleString(MSG_PHONEPANEL_SELECT_FAST_MACROS_TXT);
  1697.                     break;
  1698.  
  1699.                 case DATATYPE_HOTKEYS:
  1700.  
  1701.                     Title = LocaleString(MSG_HOTKEYPANEL_LOAD_HOTKEYS_TXT);
  1702.                     break;
  1703.  
  1704.                 case DATATYPE_SPEECH:
  1705.  
  1706.                     Title = LocaleString(MSG_SPEECHPANEL_LOAD_SPEECH_SETTINGS_TXT);
  1707.                     break;
  1708.  
  1709.                 case DATATYPE_SOUND:
  1710.  
  1711.                     Title = LocaleString(MSG_SOUNDPANEL_LOAD_SOUNDS_TXT);
  1712.                     break;
  1713.  
  1714.                 case DATATYPE_BUFFER:
  1715.  
  1716.                     Title = LocaleString(MSG_TERMMAIN_LOAD_BUFFER_TXT);
  1717.                     break;
  1718.  
  1719.                 case DATATYPE_CONFIGURATION:
  1720.  
  1721.                     Title = LocaleString(MSG_TERMMAIN_OPEN_PREFERENCES_TXT);
  1722.                     break;
  1723.  
  1724.                 case DATATYPE_PHONEBOOK:
  1725.  
  1726.                     Title = LocaleString(MSG_PHONEPANEL_LOAD_PHONEBOOK_TXT);
  1727.                     break;
  1728.             }
  1729.  
  1730.             BlockWindows();
  1731.  
  1732.             if(FileRequest = GetFile(Title,"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,"Ok",TRUE))
  1733.             {
  1734.                 FileName = DummyBuffer;
  1735.  
  1736.                 FreeAslRequest(FileRequest);
  1737.             }
  1738.             else
  1739.                 Results[0] = RC_WARN;
  1740.  
  1741.             ReleaseWindows();
  1742.         }
  1743.  
  1744.         if(FileName)
  1745.         {
  1746.             if(!GetFileSize(FileName))
  1747.             {
  1748.                 Results[0] = RC_ERROR;
  1749.                 Results[1] = ERROR_OBJECT_NOT_FOUND;
  1750.  
  1751.                 return(NULL);
  1752.             }
  1753.  
  1754.             BlockWindows();
  1755.  
  1756.             switch(Index)
  1757.             {
  1758.                 case DATATYPE_TRANSLATIONS:
  1759.                 {
  1760.                     struct TranslationEntry    **Send,
  1761.                                 **Receive = NULL;
  1762.                     BYTE            Success = FALSE;
  1763.  
  1764.                     if(Send = AllocTranslationTable())
  1765.                     {
  1766.                         if(Receive = AllocTranslationTable())
  1767.                         {
  1768.                             if(!(Success = LoadTranslationTables(FileName,Send,Receive)))
  1769.                             {
  1770.                                 Results[0] = RC_ERROR;
  1771.                                 Results[1] = IoErr();
  1772.                             }
  1773.                         }
  1774.                         else
  1775.                         {
  1776.                             Results[0] = RC_ERROR;
  1777.                             Results[1] = ERROR_NO_FREE_STORE;
  1778.                         }
  1779.                     }
  1780.                     else
  1781.                     {
  1782.                         Results[0] = RC_ERROR;
  1783.                         Results[1] = ERROR_NO_FREE_STORE;
  1784.                     }
  1785.  
  1786.                     if(!Success)
  1787.                     {
  1788.                         if(Send)
  1789.                             FreeTranslationTable(Send);
  1790.  
  1791.                         if(Receive)
  1792.                             FreeTranslationTable(Receive);
  1793.                     }
  1794.                     else
  1795.                     {
  1796.                         strcpy(Config -> FileConfig -> TranslationFileName,FileName);
  1797.  
  1798.                         strcpy(LastTranslation,FileName);
  1799.  
  1800.                         FreeTranslationTable(SendTable);
  1801.                         FreeTranslationTable(ReceiveTable);
  1802.  
  1803.                         SendTable    = Send;
  1804.                         ReceiveTable    = Receive;
  1805.                     }
  1806.                 }
  1807.  
  1808.                 break;
  1809.  
  1810.                 case DATATYPE_FUNCTIONKEYS:
  1811.                 {
  1812.                     if(!LoadMacros(FileName,MacroKeys))
  1813.                     {
  1814.                         Results[0] = RC_ERROR;
  1815.                         Results[1] = IoErr();
  1816.                     }
  1817.                     else
  1818.                     {
  1819.                         MacroChanged = FALSE;
  1820.  
  1821.                         strcpy(Config -> FileConfig -> MacroFileName,FileName);
  1822.  
  1823.                         strcpy(LastMacros,FileName);
  1824.                     }
  1825.                 }
  1826.  
  1827.                 break;
  1828.  
  1829.                 case DATATYPE_CURSORKEYS:
  1830.                 {
  1831.                     if(!ReadIFFData(FileName,CursorKeys,sizeof(struct CursorKeys),ID_KEYS))
  1832.                     {
  1833.                         Results[0] = RC_ERROR;
  1834.                         Results[1] = IoErr();
  1835.                     }
  1836.                     else
  1837.                     {
  1838.                         CursorKeysChanged = FALSE;
  1839.  
  1840.                         strcpy(Config -> FileConfig -> CursorFileName,FileName);
  1841.  
  1842.                         strcpy(LastCursorKeys,FileName);
  1843.                     }
  1844.                 }
  1845.  
  1846.                 break;
  1847.  
  1848.                 case DATATYPE_FASTMACROS:
  1849.                 {
  1850.                     if(!LoadFastMacros(FileName))
  1851.                     {
  1852.                         Results[0] = RC_ERROR;
  1853.                         Results[1] = IoErr();
  1854.                     }
  1855.                     else
  1856.                     {
  1857.                         strcpy(Config -> FileConfig -> FastMacroFileName,FileName);
  1858.  
  1859.                         strcpy(LastFastMacros,FileName);
  1860.  
  1861.                         FastMacrosChanged = FALSE;
  1862.                     }
  1863.  
  1864.                     RefreshFastWindow(TRUE);
  1865.                 }
  1866.  
  1867.                 break;
  1868.  
  1869.                 case DATATYPE_HOTKEYS:
  1870.                 {
  1871.                     if(!LoadHotkeys(FileName,&Hotkeys))
  1872.                     {
  1873.                         Results[0] = RC_ERROR;
  1874.                         Results[1] = IoErr();
  1875.                     }
  1876.                     else
  1877.                     {
  1878.                         strcpy(LastKeys,FileName);
  1879.  
  1880.                         HotkeysChanged = FALSE;
  1881.  
  1882.                         SetupCx();
  1883.                     }
  1884.                 }
  1885.  
  1886.                 break;
  1887.  
  1888.                 case DATATYPE_SPEECH:
  1889.                 {
  1890.                     if(!ReadIFFData(FileName,&SpeechConfig,sizeof(struct SpeechConfig),ID_SPEK))
  1891.                     {
  1892.                         Results[0] = RC_ERROR;
  1893.                         Results[1] = IoErr();
  1894.                     }
  1895.                     else
  1896.                     {
  1897.                         strcpy(LastSpeech,FileName);
  1898.  
  1899.                         SpeechSetup();
  1900.  
  1901.                         SpeechChanged = FALSE;
  1902.                     }
  1903.                 }
  1904.  
  1905.                 break;
  1906.  
  1907.                 case DATATYPE_SOUND:
  1908.                 {
  1909.                     if(!ReadIFFData(FileName,&SoundConfig,sizeof(struct SoundConfig),ID_SOUN))
  1910.                     {
  1911.                         Results[0] = RC_ERROR;
  1912.                         Results[1] = IoErr();
  1913.                     }
  1914.                     else
  1915.                     {
  1916.                         strcpy(LastSound,FileName);
  1917.  
  1918.                         SoundInit();
  1919.  
  1920.                         SoundChanged = FALSE;
  1921.                     }
  1922.                 }
  1923.  
  1924.                 break;
  1925.  
  1926.                 case DATATYPE_BUFFER:
  1927.                 {
  1928.                     BPTR SomeFile;
  1929.  
  1930.                     if(SomeFile = Open(FileName,MODE_OLDFILE))
  1931.                     {
  1932.                         LONG Len;
  1933.  
  1934.                         LineRead(NULL,NULL,NULL);
  1935.  
  1936.                         while((Len = LineRead(SomeFile,FileName,80)) > 0)
  1937.                             StoreBuffer(FileName,Len);
  1938.  
  1939.                         Close(SomeFile);
  1940.  
  1941.                         BufferChanged = TRUE;
  1942.                     }
  1943.                     else
  1944.                     {
  1945.                         Results[0] = RC_ERROR;
  1946.                         Results[1] = IoErr();
  1947.                     }
  1948.                 }
  1949.  
  1950.                 break;
  1951.  
  1952.                 case DATATYPE_CONFIGURATION:
  1953.                 {
  1954.                     if(ReadConfig(FileName,PrivateConfig))
  1955.                     {
  1956.                         SwapConfig(PrivateConfig,Config);
  1957.  
  1958.                         strcpy(FileName,LastConfig);
  1959.  
  1960.                         ConfigSetup();
  1961.  
  1962.                         ConfigChanged = FALSE;
  1963.                     }
  1964.                     else
  1965.                     {
  1966.                         Results[0] = RC_ERROR;
  1967.                         Results[1] = IoErr();
  1968.                     }
  1969.                 }
  1970.  
  1971.                 break;
  1972.  
  1973.                 case DATATYPE_PHONEBOOK:
  1974.                 {
  1975.                     if(ChosenEntry)
  1976.                     {
  1977.                         Results[0] = RC_ERROR;
  1978.                         Results[1] = ERROR_OBJECT_IN_USE;
  1979.                     }
  1980.                     else
  1981.                     {
  1982.                         if(!LoadPhonebook(FileName))
  1983.                         {
  1984.                             Results[0] = RC_ERROR;
  1985.                             Results[1] = IoErr();
  1986.                         }
  1987.                         else
  1988.                         {
  1989.                             strcpy(LastPhone,FileName);
  1990.  
  1991.                             PhonebookChanged = FALSE;
  1992.  
  1993.                             RebuildMenu = TRUE;
  1994.                         }
  1995.                     }
  1996.                 }
  1997.  
  1998.                 break;
  1999.             }
  2000.  
  2001.             ReleaseWindows();
  2002.         }
  2003.         else
  2004.             Results[0] = RC_WARN;
  2005.     }
  2006.  
  2007.     return(NULL);
  2008. }
  2009.  
  2010. STRPTR __regargs
  2011. RexxOpenDevice(struct RexxPkt *Pkt)
  2012. {
  2013.     enum    {    ARG_OPENDEVICE_NAME,ARG_OPENDEVICE_UNIT };
  2014.  
  2015.     if(ReadRequest)
  2016.     {
  2017.         Results[0] = RC_ERROR;
  2018.         Results[1] = TERMERROR_DEVICE_DRIVER_STILL_OPEN;
  2019.     }
  2020.     else
  2021.     {
  2022.         if(Args[ARG_OPENDEVICE_NAME])
  2023.         {
  2024.             strcpy(Config -> SerialConfig -> SerialDevice,Args[ARG_OPENDEVICE_NAME]);
  2025.  
  2026.             ConfigChanged = TRUE;
  2027.         }
  2028.  
  2029.         if(Args[ARG_OPENDEVICE_UNIT])
  2030.         {
  2031.             Config -> SerialConfig -> UnitNumber = *(LONG *)Args[ARG_OPENDEVICE_UNIT];
  2032.  
  2033.             ConfigChanged = TRUE;
  2034.         }
  2035.  
  2036.         BlockWindows();
  2037.  
  2038.         ReopenSerial();
  2039.  
  2040.         ReleaseWindows();
  2041.     }
  2042.  
  2043.     return(NULL);
  2044. }
  2045.  
  2046. STRPTR __regargs
  2047. RexxOpenRequester(struct RexxPkt *Pkt)
  2048. {
  2049.     enum    {    ARG_OPENREQUESTER_REQUESTER };
  2050.  
  2051.     WORD Index;
  2052.  
  2053.     if((Index = ToRequester(Args[ARG_OPENREQUESTER_REQUESTER])) == -1)
  2054.     {
  2055.         Results[0] = RC_ERROR;
  2056.         Results[1] = ERROR_OBJECT_NOT_FOUND;
  2057.     }
  2058.     else
  2059.     {
  2060.         ULONG    Code;
  2061.         WORD    i;
  2062.  
  2063.         switch(Index)
  2064.         {
  2065.             case REQUESTER_SERIAL:
  2066.  
  2067.                 Code = MEN_SERIAL;
  2068.                 break;
  2069.  
  2070.             case REQUESTER_MODEM:
  2071.  
  2072.                 Code = MEN_MODEM;
  2073.                 break;
  2074.  
  2075.             case REQUESTER_SCREEN:
  2076.  
  2077.                 Code = MEN_SCREEN;
  2078.                 break;
  2079.  
  2080.             case REQUESTER_TERMINAL:
  2081.  
  2082.                 Code = MEN_TERMINAL;
  2083.                 break;
  2084.  
  2085.             case REQUESTER_EMULATION:
  2086.  
  2087.                 Code = MEN_SET_EMULATION;
  2088.                 break;
  2089.  
  2090.             case REQUESTER_CLIPBOARD:
  2091.  
  2092.                 Code = MEN_CLIPBOARD;
  2093.                 break;
  2094.  
  2095.             case REQUESTER_CAPTURE:
  2096.  
  2097.                 Code = MEN_CAPTURE;
  2098.                 break;
  2099.  
  2100.             case REQUESTER_COMMANDS:
  2101.  
  2102.                 Code = MEN_COMMANDS;
  2103.                 break;
  2104.  
  2105.             case REQUESTER_MISC:
  2106.  
  2107.                 Code = MEN_MISC;
  2108.                 break;
  2109.  
  2110.             case REQUESTER_PATH:
  2111.  
  2112.                 Code = MEN_PATH;
  2113.                 break;
  2114.  
  2115.             case REQUESTER_TRANSFER:
  2116.  
  2117.                 Code = MEN_TRANSFER;
  2118.                 break;
  2119.  
  2120.             case REQUESTER_TRANSLATIONS:
  2121.  
  2122.                 Code = MEN_TRANSLATION;
  2123.                 break;
  2124.  
  2125.             case REQUESTER_FUNCTIONKEYS:
  2126.  
  2127.                 Code = MEN_MACROS;
  2128.                 break;
  2129.  
  2130.             case REQUESTER_CURSORKEYS:
  2131.  
  2132.                 Code = MEN_CURSORKEYS;
  2133.                 break;
  2134.  
  2135.             case REQUESTER_FASTMACROS:
  2136.  
  2137.                 Code = MEN_FAST_MACROS;
  2138.                 break;
  2139.  
  2140.             case REQUESTER_HOTKEYS:
  2141.  
  2142.                 Code = MEN_HOTKEYS;
  2143.                 break;
  2144.  
  2145.             case REQUESTER_SPEECH:
  2146.  
  2147.                 Code = MEN_SPEECH;
  2148.                 break;
  2149.  
  2150.             case REQUESTER_SOUND:
  2151.  
  2152.                 Code = MEN_SOUND;
  2153.                 break;
  2154.  
  2155.  
  2156.             case REQUESTER_PHONE:
  2157.  
  2158.                 Code = MEN_PHONEBOOK;
  2159.                 break;
  2160.         }
  2161.  
  2162.             /* Scan the menu list... */
  2163.  
  2164.         for(i = 0 ; TermMenu[i] . nm_Type != NM_END ; i++)
  2165.         {
  2166.                 /* Did we get a valid name string? */
  2167.  
  2168.             if(TermMenu[i] . nm_Label != NM_BARLABEL)
  2169.             {
  2170.                 if((ULONG)TermMenu[i] . nm_UserData == Code)
  2171.                 {
  2172.                     HandleMenuCode((ULONG)TermMenu[i] . nm_UserData,NULL);
  2173.  
  2174.                     break;
  2175.                 }
  2176.             }
  2177.         }
  2178.     }
  2179.  
  2180.     return(NULL);
  2181. }
  2182.  
  2183. STRPTR __regargs
  2184. RexxParity(struct RexxPkt *Pkt)
  2185. {
  2186.     enum    {    ARG_PARITY_EVEN,ARG_PARITY_ODD,ARG_PARITY_NONE,ARG_PARITY_MARK,ARG_PARITY_SPACE };
  2187.  
  2188.     BYTE Mode;
  2189.  
  2190.     if(Args[ARG_PARITY_EVEN])
  2191.         Mode = PARITY_EVEN;
  2192.  
  2193.     if(Args[ARG_PARITY_ODD])
  2194.         Mode = PARITY_ODD;
  2195.  
  2196.     if(Args[ARG_PARITY_NONE])
  2197.         Mode = PARITY_NONE;
  2198.  
  2199.     if(Args[ARG_PARITY_MARK])
  2200.         Mode = PARITY_MARK;
  2201.  
  2202.     if(Args[ARG_PARITY_SPACE])
  2203.         Mode = PARITY_SPACE;
  2204.  
  2205.     if(Config -> SerialConfig -> Parity != Mode)
  2206.     {
  2207.         Config -> SerialConfig -> Parity = Mode;
  2208.  
  2209.         UpdateRequired = TRUE;
  2210.  
  2211.         ConfigChanged = TRUE;
  2212.     }
  2213.  
  2214.     return(NULL);
  2215. }
  2216.  
  2217. STRPTR __regargs
  2218. RexxPasteClip(struct RexxPkt *Pkt)
  2219. {
  2220.     enum    {    ARG_PASTECLIP_UNIT };
  2221.  
  2222.     LONG Unit;
  2223.  
  2224.     if(Args[ARG_PASTECLIP_UNIT])
  2225.         Unit = *(LONG *)Args[ARG_PASTECLIP_UNIT];
  2226.     else
  2227.         Unit = Config -> ClipConfig -> ClipboardUnit;
  2228.  
  2229.     if(!OpenClip(Unit))
  2230.         ClipInput = TRUE;
  2231.     else
  2232.         ClipInput = FALSE;
  2233.  
  2234.     return(NULL);
  2235. }
  2236.  
  2237. STRPTR __regargs
  2238. RexxPrint(struct RexxPkt *Pkt)
  2239. {
  2240.     enum    {    ARG_PRINT_FROM,ARG_PRINT_TO,ARG_PRINT_SERIAL,ARG_PRINT_MODEM,ARG_PRINT_SCREEN,
  2241.             ARG_PRINT_TERMINAL,ARG_PRINT_USER,ARG_PRINT_COMMENT,ARG_PRINT_SIZE,
  2242.             ARG_PRINT_DATE,ARG_PRINT_BITS };
  2243.  
  2244.     WORD    Index,Mode = -1;
  2245.     ULONG    Flags = NULL;
  2246.  
  2247.     if(Args[ARG_PRINT_SERIAL])
  2248.         Flags |= PRINT_SERIAL;
  2249.  
  2250.     if(Args[ARG_PRINT_MODEM])
  2251.         Flags |= PRINT_MODEM;
  2252.  
  2253.     if(Args[ARG_PRINT_SCREEN])
  2254.         Flags |= PRINT_SCREEN;
  2255.  
  2256.     if(Args[ARG_PRINT_TERMINAL])
  2257.         Flags |= PRINT_TERMINAL;
  2258.  
  2259.     if(Args[ARG_PRINT_USER])
  2260.         Flags |= PRINT_USERNAME;
  2261.  
  2262.     if(Args[ARG_PRINT_COMMENT])
  2263.         Flags |= PRINT_COMMENT;
  2264.  
  2265.     if(Args[ARG_PRINT_SIZE])
  2266.         Flags |= PRINT_SIZE;
  2267.  
  2268.     if(Args[ARG_PRINT_DATE])
  2269.         Flags |= PRINT_DATE;
  2270.  
  2271.     if(Args[ARG_PRINT_BITS])
  2272.         Flags |= PRINT_BITS;
  2273.  
  2274.     if((Index = ToList(Args[ARG_PRINT_FROM])) == -1)
  2275.     {
  2276.         if(!Stricmp(Args[ARG_PRINT_FROM],"SCREENTEXT"))
  2277.         {
  2278.             if(!RasterEnabled)
  2279.             {
  2280.                 Results[0] = RC_ERROR;
  2281.                 Results[1] = TERMERROR_NO_DATA_TO_PROCESS;
  2282.  
  2283.                 return(NULL);
  2284.             }
  2285.             else
  2286.                 Mode = 0;
  2287.         }
  2288.  
  2289.         if(!Stricmp(Args[ARG_PRINT_FROM],"CLIPBOARD"))
  2290.             Mode = 1;
  2291.  
  2292.         if(!Stricmp(Args[ARG_PRINT_FROM],"BUFFER"))
  2293.             Mode = 2;
  2294.     }
  2295.  
  2296.     if(Index == -1 && Mode == -1)
  2297.     {
  2298.         Results[0] = RC_ERROR;
  2299.         Results[1] = TERMERROR_UNKNOWN_LIST;
  2300.     }
  2301.     else
  2302.     {
  2303.         BYTE    Continue = TRUE;
  2304.         LONG    Error = 0;
  2305.         BPTR    File;
  2306.         STRPTR    Name;
  2307.  
  2308.         if(Args[ARG_PRINT_TO])
  2309.             Name = Args[ARG_PRINT_TO];
  2310.         else
  2311.             Name = "PRT:";
  2312.  
  2313.         if(File = Open(Name,MODE_NEWFILE))
  2314.         {
  2315.             struct Window        *ReqWindow;
  2316.             struct EasyStruct     Easy;
  2317.  
  2318.             Easy . es_StructSize    = sizeof(struct EasyStruct);
  2319.             Easy . es_Flags        = NULL;
  2320.             Easy . es_Title        = (UBYTE *)LocaleString(MSG_TERMAUX_TERM_REQUEST_TXT);
  2321.             Easy . es_GadgetFormat    = (UBYTE *)LocaleString(MSG_PRINT_STOP_TXT);
  2322.             Easy . es_TextFormat    = (UBYTE *)LocaleString(MSG_GLOBAL_PRINTING_TXT);
  2323.  
  2324.             BlockWindows();
  2325.  
  2326.             if(ReqWindow = BuildEasyRequest(Window,&Easy,NULL))
  2327.             {
  2328.                 switch(Index)
  2329.                 {
  2330.                     case GLIST_DIAL:
  2331.                     {
  2332.                         struct GenericList *List = GenericListTable[Index];
  2333.  
  2334.                         ObtainSemaphore(&List -> ListSemaphore);
  2335.  
  2336.                         if(List -> ListHeader . mlh_Head -> mln_Succ)
  2337.                         {
  2338.                             struct DialNode *TempNode;
  2339.  
  2340.                             for(TempNode = (struct DialNode *)List -> ListHeader . mlh_Head ; Continue && TempNode -> Node . ln_Succ ; TempNode = (struct DialNode *)TempNode -> Node . ln_Succ)
  2341.                             {
  2342.                                 if(TempNode -> Entry)
  2343.                                     Continue = PrintEntry(File,ReqWindow,TRUE,&Error,TempNode -> Entry,Flags);
  2344.                                 else
  2345.                                     Continue = PrintText(File,ReqWindow,&Error,"\n\"???\" (%s)",TempNode -> Node . ln_Name);
  2346.                             }
  2347.                         }
  2348.  
  2349.                         ReleaseSemaphore(&List -> ListSemaphore);
  2350.                     }
  2351.  
  2352.                     break;
  2353.  
  2354.                     case GLIST_UPLOAD:
  2355.                     case GLIST_DOWNLOAD:
  2356.                     {
  2357.                         struct GenericList *List = GenericListTable[Index];
  2358.  
  2359.                         ObtainSemaphore(&List -> ListSemaphore);
  2360.  
  2361.                         if(List -> ListHeader . mlh_Head -> mln_Succ)
  2362.                         {
  2363.                             struct Node *TempNode;
  2364.  
  2365.                             for(TempNode = (struct Node *)List -> ListHeader . mlh_Head ; Continue && TempNode -> ln_Succ ; TempNode = TempNode -> ln_Succ)
  2366.                                 Continue = PrintFileInformation(File,ReqWindow,&Error,TempNode -> ln_Name,Flags);
  2367.                         }
  2368.  
  2369.                         ReleaseSemaphore(&List -> ListSemaphore);
  2370.                     }
  2371.  
  2372.                     break;
  2373.  
  2374.                     case GLIST_WAIT:
  2375.                     {
  2376.                         struct GenericList *List = GenericListTable[Index];
  2377.  
  2378.                         ObtainSemaphore(&List -> ListSemaphore);
  2379.  
  2380.                         if(List -> ListHeader . mlh_Head -> mln_Succ)
  2381.                         {
  2382.                             struct Node *TempNode;
  2383.  
  2384.                             for(TempNode = (struct Node *)List -> ListHeader . mlh_Head ; Continue && TempNode -> ln_Succ ; TempNode = TempNode -> ln_Succ)
  2385.                                 Continue = PrintText(File,ReqWindow,&Error,"%s\n",TempNode -> ln_Name);
  2386.                         }
  2387.  
  2388.                         ReleaseSemaphore(&List -> ListSemaphore);
  2389.                     }
  2390.  
  2391.                     break;
  2392.  
  2393.                     default:
  2394.                     {
  2395.                         switch(Mode)
  2396.                         {
  2397.                             case 0:
  2398.  
  2399.                                 Continue = PrintScreen(File,ReqWindow,&Error);
  2400.                                 break;
  2401.  
  2402.                             case 1:
  2403.  
  2404.                                 Continue = PrintClip(File,ReqWindow,&Error);
  2405.                                 break;
  2406.  
  2407.                             case 2:
  2408.  
  2409.                                 Continue = PrintBuffer(File,ReqWindow,&Error);
  2410.                                 break;
  2411.                         }
  2412.  
  2413.                         break;
  2414.                     }
  2415.  
  2416.                     break;
  2417.                 }
  2418.  
  2419.                 FreeSysRequest(ReqWindow);
  2420.             }
  2421.  
  2422.             ReleaseWindows();
  2423.  
  2424.             Close(File);
  2425.         }
  2426.         else
  2427.             Error = IoErr();
  2428.  
  2429.         if(Error)
  2430.         {
  2431.             Results[0] = RC_ERROR;
  2432.             Results[1] = Error;
  2433.         }
  2434.         else
  2435.         {
  2436.             if(!Continue)
  2437.                 Results[0] = RC_WARN;
  2438.         }
  2439.     }
  2440.  
  2441.     return(NULL);
  2442. }
  2443.  
  2444. STRPTR __regargs
  2445. RexxProtocol(struct RexxPkt *Pkt)
  2446. {
  2447.     enum    {    ARG_PROTOCOL_NONE,ARG_PROTOCOL_RTSCTS,ARG_PROTOCOL_RTSCTSDTR };
  2448.  
  2449.     BYTE Mode;
  2450.  
  2451.     if(Args[ARG_PROTOCOL_NONE])
  2452.         Mode = HANDSHAKING_NONE;
  2453.  
  2454.     if(Args[ARG_PROTOCOL_RTSCTS])
  2455.         Mode = HANDSHAKING_RTSCTS;
  2456.  
  2457.     if(Args[ARG_PROTOCOL_RTSCTSDTR])
  2458.         Mode = HANDSHAKING_RTSCTS_DSR;
  2459.  
  2460.     if(Config -> SerialConfig -> HandshakingProtocol != Mode)
  2461.     {
  2462.         Config -> SerialConfig -> HandshakingProtocol = Mode;
  2463.  
  2464.         UpdateRequired = TRUE;
  2465.  
  2466.         ConfigChanged = TRUE;
  2467.     }
  2468.  
  2469.     return(NULL);
  2470. }
  2471.  
  2472. STRPTR __regargs
  2473. RexxPutClip(struct RexxPkt *Pkt)
  2474. {
  2475.     enum    {    ARG_PUTCLIP_UNIT,ARG_PUTCLIP_TEXT };
  2476.  
  2477.     struct IFFHandle    *Handle;
  2478.     LONG             Unit;
  2479.     BYTE             Success = FALSE;
  2480.  
  2481.     if(Args[ARG_PUTCLIP_UNIT])
  2482.         Unit = *(LONG *)Args[ARG_PUTCLIP_UNIT];
  2483.     else
  2484.         Unit = Config -> ClipConfig -> ClipboardUnit;
  2485.  
  2486.     if(Handle = AllocIFF())
  2487.     {
  2488.         if(Handle -> iff_Stream = (ULONG)OpenClipboard(Unit))
  2489.         {
  2490.             InitIFFasClip(Handle);
  2491.  
  2492.             if(!OpenIFF(Handle,IFFF_WRITE))
  2493.             {
  2494.                 if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  2495.                 {
  2496.                     if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
  2497.                     {
  2498.                         LONG Len = strlen(Args[ARG_PUTCLIP_TEXT]);
  2499.  
  2500.                         if(WriteChunkBytes(Handle,Args[ARG_PUTCLIP_TEXT],Len) == Len)
  2501.                         {
  2502.                             if(!PopChunk(Handle))
  2503.                                 Success = TRUE;
  2504.                         }
  2505.                     }
  2506.                 }
  2507.  
  2508.                 if(PopChunk(Handle))
  2509.                     Success = FALSE;
  2510.  
  2511.                 CloseIFF(Handle);
  2512.             }
  2513.             else
  2514.             {
  2515.                 Results[0] = RC_ERROR;
  2516.                 Results[1] = ERROR_NO_FREE_STORE;
  2517.             }
  2518.  
  2519.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  2520.         }
  2521.         else
  2522.         {
  2523.             Results[0] = RC_ERROR;
  2524.             Results[1] = TERMERROR_UNIT_NOT_AVAILABLE;
  2525.         }
  2526.  
  2527.         FreeIFF(Handle);
  2528.     }
  2529.     else
  2530.     {
  2531.         Results[0] = RC_ERROR;
  2532.         Results[1] = ERROR_NO_FREE_STORE;
  2533.     }
  2534.  
  2535.     if(!Success && !Results[0])
  2536.     {
  2537.         Results[0] = RC_ERROR;
  2538.         Results[1] = TERMERROR_CLIPBOARD_ERROR;
  2539.     }
  2540.  
  2541.     return(NULL);
  2542. }
  2543.  
  2544. STRPTR __regargs
  2545. RexxQuit(struct RexxPkt *Pkt)
  2546. {
  2547.     enum    {    ARG_QUIT_FORCE };
  2548.  
  2549.     if(Args[ARG_QUIT_FORCE])
  2550.         MainTerminated = TRUE;
  2551.     else
  2552.         HandleMenuCode(MEN_QUIT,NULL);
  2553.  
  2554.     return(NULL);
  2555. }
  2556.  
  2557. STRPTR __regargs
  2558. RexxRead(struct RexxPkt *Pkt)
  2559. {
  2560.     enum    {    ARG_READ_NUM,ARG_READ_CR,ARG_READ_NOECHO,ARG_READ_PROMPT };
  2561.  
  2562.     LONG Len,BytesRead = 0;
  2563.  
  2564.     if(!ReadRequest || !WriteRequest)
  2565.     {
  2566.         Results[0] = RC_WARN;
  2567.  
  2568.         return(NULL);
  2569.     }
  2570.  
  2571.     if(Args[ARG_READ_NUM])
  2572.     {
  2573.         Len = *(LONG *)Args[ARG_READ_NUM] + 1;
  2574.  
  2575.         if(Len < 1)
  2576.         {
  2577.             Results[0] = RC_ERROR;
  2578.             Results[1] = ERROR_BAD_NUMBER;
  2579.  
  2580.             return(NULL);
  2581.         }
  2582.  
  2583.         if(Len > MAX_RESULT_LEN + 1)
  2584.             Len = MAX_RESULT_LEN + 1;
  2585.     }
  2586.     else
  2587.         Len = MAX_RESULT_LEN + 1;
  2588.  
  2589.     if(Args[ARG_READ_PROMPT])
  2590.         LocalRexxSerialCommand(Args[ARG_READ_PROMPT],NULL);
  2591.  
  2592.     BlockWindows();
  2593.  
  2594.     Status = STATUS_READY;
  2595.  
  2596.     if(Args[ARG_READ_NUM])
  2597.     {
  2598.         STRPTR Buffer;
  2599.  
  2600.         if(Buffer = (STRPTR)AllocVec(Len,MEMF_ANY))
  2601.         {
  2602.             ULONG    Signals,SignalMask = SIG_SERIAL | SIG_TIMER | SIG_BREAK;
  2603.             STRPTR    Result;
  2604.  
  2605.             ClearSerial();
  2606.  
  2607.             ReadRequest -> IOSer . io_Command    = CMD_READ;
  2608.             ReadRequest -> IOSer . io_Data        = Buffer;
  2609.             ReadRequest -> IOSer . io_Length    = Len - 1;
  2610.  
  2611.             ClrSignal(SignalMask);
  2612.  
  2613.             if(RexxTimeoutVal)
  2614.                 StartTime(RexxTimeoutVal,0);
  2615.  
  2616.             SendIO(ReadRequest);
  2617.  
  2618.             FOREVER
  2619.             {
  2620.                 Signals = Wait(SignalMask);
  2621.  
  2622.                 if(Signals & SIG_SERIAL)
  2623.                 {
  2624.                     if(RexxTimeoutVal)
  2625.                     {
  2626.                         if(!CheckIO(TimeRequest))
  2627.                             AbortIO(TimeRequest);
  2628.  
  2629.                         WaitIO(TimeRequest);
  2630.                     }
  2631.  
  2632.                         /* Did the request terminate gracefully? */
  2633.  
  2634.                     if(!WaitIO(ReadRequest))
  2635.                     {
  2636.                         BytesIn += ReadRequest -> IOSer . io_Actual;
  2637.  
  2638.                         BytesRead = ReadRequest -> IOSer . io_Actual;
  2639.                     }
  2640.                     else
  2641.                         Results[0] = RC_ERROR;
  2642.  
  2643.                     break;
  2644.                 }
  2645.  
  2646.                 if(Signals & SIG_BREAK)
  2647.                 {
  2648.                     if(!CheckIO(ReadRequest))
  2649.                         AbortIO(ReadRequest);
  2650.  
  2651.                     WaitIO(ReadRequest);
  2652.  
  2653.                     if(RexxTimeoutVal)
  2654.                     {
  2655.                         if(!CheckIO(TimeRequest))
  2656.                             AbortIO(TimeRequest);
  2657.  
  2658.                         WaitIO(TimeRequest);
  2659.                     }
  2660.  
  2661.                     Results[0] = RC_WARN;
  2662.  
  2663.                     break;
  2664.                 }
  2665.  
  2666.                 if(Signals & SIG_TIMER)
  2667.                 {
  2668.                     if(!CheckIO(ReadRequest))
  2669.                         AbortIO(ReadRequest);
  2670.  
  2671.                     WaitIO(ReadRequest);
  2672.  
  2673.                     WaitIO(TimeRequest);
  2674.  
  2675.                     if(ReadRequest -> IOSer . io_Actual)
  2676.                     {
  2677.                         BytesIn += ReadRequest -> IOSer . io_Actual;
  2678.  
  2679.                         BytesRead = ReadRequest -> IOSer . io_Actual;
  2680.                     }
  2681.                     else
  2682.                     {
  2683.                         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  2684.  
  2685.                         DoIO(WriteRequest);
  2686.  
  2687.                         if(WriteRequest -> IOSer . io_Actual)
  2688.                         {
  2689.                                 /* Don't read more than actually wanted. */
  2690.  
  2691.                             ReadRequest -> IOSer . io_Command    = CMD_READ;
  2692.                             ReadRequest -> IOSer . io_Data        = Buffer;
  2693.                             ReadRequest -> IOSer . io_Length    = MIN(Len - 1,WriteRequest -> IOSer . io_Actual);
  2694.  
  2695.                             if(!DoIO(ReadRequest))
  2696.                             {
  2697.                                 BytesIn += ReadRequest -> IOSer . io_Actual;
  2698.  
  2699.                                 BytesRead = ReadRequest -> IOSer . io_Actual;
  2700.                             }
  2701.                         }
  2702.                     }
  2703.  
  2704.                     break;
  2705.                 }
  2706.             }
  2707.  
  2708.             if(BytesRead)
  2709.             {
  2710.                 Buffer[BytesRead] = 0;
  2711.  
  2712.                 Result = CreateResult(Buffer,Results);
  2713.             }
  2714.             else
  2715.             {
  2716.                 Results[0] = RC_WARN;
  2717.  
  2718.                 Result = NULL;
  2719.             }
  2720.  
  2721.             FreeVec(Buffer);
  2722.  
  2723.             RestartSerial();
  2724.  
  2725.             ReleaseWindows();
  2726.  
  2727.             return(Result);
  2728.         }
  2729.         else
  2730.         {
  2731.             Results[0] = RC_ERROR;
  2732.             Results[1] = ERROR_NO_FREE_STORE;
  2733.         }
  2734.  
  2735.         RestartSerial();
  2736.     }
  2737.     else
  2738.     {
  2739.         ULONG     Signals,SignalMask = SIG_SERIAL | SIG_TIMER | SIG_BREAK;
  2740.         UBYTE    *Char = ReadBuffer;
  2741.         BYTE     Echo,Done = FALSE;
  2742.         LONG     Index = 0;
  2743.  
  2744.         if(Args[ARG_READ_NOECHO])
  2745.             Echo = FALSE;
  2746.         else
  2747.             Echo = TRUE;
  2748.  
  2749.         if(RexxTimeoutVal)
  2750.             StartTime(RexxTimeoutVal,0);
  2751.  
  2752.         if(CheckIO(ReadRequest))
  2753.             Signals = SIG_SERIAL;
  2754.         else
  2755.             Signals = NULL;
  2756.  
  2757.         do
  2758.         {
  2759.             if(Signals & SIG_SERIAL)
  2760.             {
  2761.                 if(!WaitIO(ReadRequest))
  2762.                 {
  2763.                     BytesIn++;
  2764.  
  2765.                     switch(*Char)
  2766.                     {
  2767.                         case '\n':
  2768.                         case '\r':
  2769.  
  2770.                             Done = TRUE;
  2771.  
  2772.                             if(Echo)
  2773.                                 SerWrite(ReadBuffer,1);
  2774.  
  2775.                             break;
  2776.  
  2777.                         case '\b':
  2778.  
  2779.                             if(Index > 0)
  2780.                             {
  2781.                                 Index--;
  2782.  
  2783.                                 if(Echo)
  2784.                                     SerWrite(ReadBuffer,1);
  2785.                             }
  2786.  
  2787.                             break;
  2788.  
  2789.                         case '\30':
  2790.  
  2791.                             if(Echo)
  2792.                             {
  2793.                                 while(Index > 0)
  2794.                                 {
  2795.                                     Index--;
  2796.  
  2797.                                     SerWrite("\b",1);
  2798.                                 }
  2799.                             }
  2800.                             else
  2801.                                 Index = 0;
  2802.  
  2803.                         default:
  2804.  
  2805.                             if(Index < 255 && ((*Char >= ' ' && *Char < 127) || *Char >= 160 || Config -> TerminalConfig -> FontMode == FONT_IBM))
  2806.                             {
  2807.                                 SharedBuffer[Index++] = *Char;
  2808.  
  2809.                                 if(Echo)
  2810.                                     SerWrite(ReadBuffer,1);
  2811.                             }
  2812.  
  2813.                             break;
  2814.                     }
  2815.                 }
  2816.  
  2817.                 RestartSerial();
  2818.             }
  2819.  
  2820.             if(Signals & (SIG_BREAK | SIG_TIMER))
  2821.             {
  2822.                 Results[0] = RC_WARN;
  2823.  
  2824.                 break;
  2825.             }
  2826.  
  2827.             if(!Done)
  2828.                 Signals = Wait(SignalMask);
  2829.         }
  2830.         while(!Done);
  2831.  
  2832.         if(RexxTimeoutVal)
  2833.         {
  2834.             if(!CheckIO(TimeRequest))
  2835.                 AbortIO(TimeRequest);
  2836.  
  2837.             WaitIO(TimeRequest);
  2838.         }
  2839.  
  2840.         if(Index)
  2841.         {
  2842.             SharedBuffer[Index] = 0;
  2843.  
  2844.             ReleaseWindows();
  2845.  
  2846.             return(CreateResult(SharedBuffer,Results));
  2847.         }
  2848.         else
  2849.             Results[0] = RC_WARN;
  2850.     }
  2851.  
  2852.     ReleaseWindows();
  2853.  
  2854.     return(NULL);
  2855. }
  2856.  
  2857. STRPTR __regargs
  2858. RexxReceiveFile(struct RexxPkt *Pkt)
  2859. {
  2860.     enum    {    ARG_RECEIVEFILE_MODE,ARG_RECEIVEFILE_NAME };
  2861.  
  2862.     WORD Mode = TRANSFER_BINARY;
  2863.  
  2864.     if(Args[ARG_RECEIVEFILE_MODE])
  2865.         Mode = ToMode(Args[ARG_RECEIVEFILE_MODE]);
  2866.  
  2867.     if(Mode == -1)
  2868.     {
  2869.         Results[0] = RC_ERROR;
  2870.         Results[1] = ERROR_ACTION_NOT_KNOWN;
  2871.     }
  2872.     else
  2873.     {
  2874.         BlockWindows();
  2875.  
  2876.         switch(Mode)
  2877.         {
  2878.             case TRANSFER_ASCII:
  2879.  
  2880.                 if(ASCIISetup())
  2881.                 {
  2882.                     StartXprReceive(TRANSFER_ASCII,NULL,FALSE);
  2883.  
  2884.                     ASCIIShutdown();
  2885.  
  2886.                     LocalRexxSerialCommand(Config -> CommandConfig -> DownloadMacro,NULL);
  2887.                 }
  2888.                 else
  2889.                 {
  2890.                     Results[0] = RC_ERROR;
  2891.                     Results[1] = ERROR_NO_FREE_STORE;
  2892.                 }
  2893.  
  2894.                 break;
  2895.  
  2896.             case TRANSFER_TEXT:
  2897.  
  2898.                 BinaryTransfer = FALSE;
  2899.  
  2900.                 StartXprReceive(TRANSFER_TEXT,NULL,FALSE);
  2901.  
  2902.                 BinaryTransfer = TRUE;
  2903.  
  2904.                 LocalRexxSerialCommand(Config -> CommandConfig -> DownloadMacro,NULL);
  2905.  
  2906.                 break;
  2907.  
  2908.             case TRANSFER_BINARY:
  2909.  
  2910.                 BinaryTransfer = TRUE;
  2911.  
  2912.                 StartXprReceive(TRANSFER_BINARY,NULL,FALSE);
  2913.  
  2914.                 LocalRexxSerialCommand(Config -> CommandConfig -> DownloadMacro,NULL);
  2915.  
  2916.                 break;
  2917.         }
  2918.  
  2919.         if(TransferFailed)
  2920.             Results[0] = RC_ERROR;
  2921.  
  2922.         if(TransferAborted)
  2923.             Results[0] = RC_WARN;
  2924.  
  2925.         ReleaseWindows();
  2926.     }
  2927.  
  2928.     return(NULL);
  2929. }
  2930.  
  2931. STRPTR __regargs
  2932. RexxRedial(struct RexxPkt *Pkt)
  2933. {
  2934.     if(DialList)
  2935.     {
  2936.         if(DialList -> lh_Head -> ln_Succ)
  2937.             DoDial = DIAL_REDIAL;
  2938.         else
  2939.             Results[0] = RC_WARN;
  2940.     }
  2941.     else
  2942.         Results[0] = RC_WARN;
  2943.  
  2944.     return(NULL);
  2945. }
  2946.  
  2947. STRPTR __regargs
  2948. RexxRemove(struct RexxPkt *Pkt)
  2949. {
  2950.     enum    {    ARG_REMOVE_FROM,ARG_REMOVE_NAME };
  2951.  
  2952.     WORD Index;
  2953.  
  2954.     if((Index = ToList(Args[ARG_REMOVE_FROM])) == -1)
  2955.     {
  2956.         Results[0] = RC_ERROR;
  2957.         Results[1] = TERMERROR_UNKNOWN_LIST;
  2958.     }
  2959.     else
  2960.     {
  2961.         if(Args[ARG_REMOVE_NAME] && Index == GLIST_DIAL)
  2962.         {
  2963.             Results[0] = RC_ERROR;
  2964.             Results[1] = TERMERROR_DATA_TYPES_INCOMPATIBLE;
  2965.         }
  2966.         else
  2967.         {
  2968.             struct GenericList *List;
  2969.  
  2970.             List = GenericListTable[Index];
  2971.  
  2972.             if(Args[ARG_REMOVE_NAME])
  2973.             {
  2974.                 STRPTR Buffer;
  2975.  
  2976.                 if(Buffer = CreateMatchBuffer(Args[ARG_REMOVE_NAME]))
  2977.                 {
  2978.                     struct Node *Node,*NextNode;
  2979.  
  2980.                     ObtainSemaphore(&List -> ListSemaphore);
  2981.  
  2982.                     Node = (struct Node *)List -> ListHeader . mlh_Head;
  2983.  
  2984.                     while(NextNode = Node -> ln_Succ)
  2985.                     {
  2986.                         if(MatchBuffer(Buffer,Node -> ln_Name))
  2987.                         {
  2988.                             Forbid();
  2989.  
  2990.                             ReleaseSemaphore(&List -> ListSemaphore);
  2991.  
  2992.                             DeleteGenericListNode(List,Node);
  2993.  
  2994.                             ObtainSemaphore(&List -> ListSemaphore);
  2995.  
  2996.                             Permit();
  2997.                         }
  2998.  
  2999.                         Node = NextNode;
  3000.                     }
  3001.  
  3002.                     ReleaseSemaphore(&List -> ListSemaphore);
  3003.  
  3004.                     DeleteMatchBuffer(Buffer);
  3005.                 }
  3006.                 else
  3007.                 {
  3008.                     Results[0] = RC_ERROR;
  3009.                     Results[1] = ERROR_NO_FREE_STORE;
  3010.                 }
  3011.             }
  3012.             else
  3013.                 DeleteGenericListNode(List,NULL);
  3014.  
  3015.             if(!GenericListCount(List))
  3016.                 Results[0] = RC_WARN;
  3017.         }
  3018.     }
  3019.  
  3020.     return(NULL);
  3021. }
  3022.  
  3023. STRPTR __regargs
  3024. RexxRequestFile(struct RexxPkt *Pkt)
  3025. {
  3026.     enum    {    ARG_REQUESTFILE_TITLE,ARG_REQUESTFILE_PATH,ARG_REQUESTFILE_FILE,
  3027.             ARG_REQUESTFILE_PATTERN,ARG_REQUESTFILE_MULTI,ARG_REQUESTFILE_NAME };
  3028.  
  3029.     if(Args[ARG_REQUESTFILE_MULTI] && !Args[ARG_REQUESTFILE_NAME])
  3030.     {
  3031.         Results[0] = RC_ERROR;
  3032.         Results[1] = TERMERROR_RESULT_VARIABLE_REQUIRED;
  3033.     }
  3034.     else
  3035.     {
  3036.         struct FileRequester    *FileRequester;
  3037.         UBYTE             DummyBuffer[MAX_FILENAME_LENGTH],
  3038.                     *DummyChar;
  3039.         STRPTR             FileName,
  3040.                      PathName;
  3041.  
  3042.         if(Args[ARG_REQUESTFILE_PATH])
  3043.         {
  3044.             PathName = Args[ARG_REQUESTFILE_PATH];
  3045.  
  3046.             if(Args[ARG_REQUESTFILE_FILE])
  3047.                 FileName = Args[ARG_REQUESTFILE_FILE];
  3048.             else
  3049.                 FileName = "";
  3050.         }
  3051.         else
  3052.         {
  3053.             PathName = "";
  3054.  
  3055.             if(Args[ARG_REQUESTFILE_FILE])
  3056.             {
  3057.                 strcpy(DummyBuffer,Args[ARG_REQUESTFILE_FILE]);
  3058.  
  3059.                 DummyChar = PathPart(DummyBuffer);
  3060.  
  3061.                 *DummyChar = 0;
  3062.  
  3063.                 PathName = DummyBuffer;
  3064.                 FileName = FilePart(Args[ARG_REQUESTFILE_FILE]);
  3065.             }
  3066.             else
  3067.                 FileName = "";
  3068.         }
  3069.  
  3070.         BlockWindows();
  3071.  
  3072.         if(FileRequester = GetFile(Args[ARG_REQUESTFILE_TITLE],PathName,FileName,DummyBuffer,Args[ARG_REQUESTFILE_PATTERN],FALSE,Args[ARG_REQUESTFILE_MULTI] != NULL,FALSE,"Ok",TRUE))
  3073.         {
  3074.             if(Args[ARG_REQUESTFILE_NAME])
  3075.             {
  3076.                 if(Args[ARG_REQUESTFILE_MULTI])
  3077.                 {
  3078.                     UBYTE         DummyBuffer[MAX_FILENAME_LENGTH];
  3079.                     struct WBArg    *ArgList = FileRequester -> rf_ArgList;
  3080.                     LONG         i,Counted = 0;
  3081.  
  3082.                     for(i = 0 ; i < FileRequester -> rf_NumArgs ; i++)
  3083.                     {
  3084.                         if(ArgList[i] . wa_Name)
  3085.                         {
  3086.                             if(ArgList[i] . wa_Lock)
  3087.                             {
  3088.                                 if(!NameFromLock(ArgList[i] . wa_Lock,DummyBuffer,MAX_FILENAME_LENGTH))
  3089.                                 {
  3090.                                     Results[0] = RC_ERROR;
  3091.                                     Results[1] = IoErr();
  3092.  
  3093.                                     break;
  3094.                                 }
  3095.                             }
  3096.                             else
  3097.                                 strcpy(DummyBuffer,FileRequester -> rf_Dir);
  3098.  
  3099.                             if(AddPart(DummyBuffer,ArgList[i] . wa_Name,MAX_FILENAME_LENGTH))
  3100.                             {
  3101.                                 if(CreateVarArgs(DummyBuffer,Pkt,"%s.%ld",Args[ARG_REQUESTFILE_NAME],i))
  3102.                                     Counted++;
  3103.                                 else
  3104.                                     break;
  3105.                             }
  3106.                             else
  3107.                             {
  3108.                                 Results[0] = RC_ERROR;
  3109.                                 Results[1] = IoErr();
  3110.  
  3111.                                 break;
  3112.                             }
  3113.                         }
  3114.                     }
  3115.  
  3116.                     if(Counted)
  3117.                     {
  3118.                         SPrintf(DummyBuffer,"%ld",Counted);
  3119.  
  3120.                         CreateVarArgs(DummyBuffer,Pkt,"%s.COUNT",Args[ARG_REQUESTFILE_NAME]);
  3121.                     }
  3122.  
  3123.                     FreeAslRequest(FileRequester);
  3124.                 }
  3125.                 else
  3126.                 {
  3127.                     FreeAslRequest(FileRequester);
  3128.  
  3129.                     ReleaseWindows();
  3130.  
  3131.                     return(CreateVar(DummyBuffer,Pkt,Args[ARG_REQUESTFILE_NAME]));
  3132.                 }
  3133.             }
  3134.             else
  3135.             {
  3136.                 FreeAslRequest(FileRequester);
  3137.  
  3138.                 ReleaseWindows();
  3139.  
  3140.                 return(CreateResult(DummyBuffer,Results));
  3141.             }
  3142.         }
  3143.         else
  3144.             Results[0] = RC_WARN;
  3145.  
  3146.         ReleaseWindows();
  3147.     }
  3148.  
  3149.     return(NULL);
  3150. }
  3151.  
  3152. STRPTR __regargs
  3153. RexxRequestNotify(struct RexxPkt *Pkt)
  3154. {
  3155.     enum    {    ARG_REQUESTNOTIFY_TITLE,ARG_REQUESTNOTIFY_PROMPT };
  3156.  
  3157.     struct EasyStruct    Easy;
  3158.     ULONG            IDCMP = NULL;
  3159.  
  3160.     Easy . es_StructSize    = sizeof(struct EasyStruct);
  3161.     Easy . es_Flags        = NULL;
  3162.     Easy . es_TextFormat    = Args[ARG_REQUESTNOTIFY_PROMPT];
  3163.     Easy . es_GadgetFormat    = LocaleString(MSG_GLOBAL_CONTINUE_TXT);
  3164.  
  3165.     if(Args[ARG_REQUESTNOTIFY_TITLE])
  3166.         Easy . es_Title    = Args[ARG_REQUESTNOTIFY_TITLE];
  3167.     else
  3168.         Easy . es_Title    = LocaleString(MSG_TERMAUX_TERM_REQUEST_TXT);
  3169.  
  3170.     BlockWindows();
  3171.  
  3172.     EasyRequestArgs(Window,&Easy,&IDCMP,NULL);
  3173.  
  3174.     ReleaseWindows();
  3175.  
  3176.     return(NULL);
  3177. }
  3178.  
  3179. STRPTR __regargs
  3180. RexxRequestNumber(struct RexxPkt *Pkt)
  3181. {
  3182.     enum    {    ARG_REQUESTNUMBER_DEFAULT,ARG_REQUESTNUMBER_PROMPT };
  3183.  
  3184.     UBYTE DummyBuffer[256];
  3185.  
  3186.     if(Args[ARG_REQUESTNUMBER_DEFAULT])
  3187.         SPrintf(DummyBuffer,"%ld",*(LONG *)Args[ARG_REQUESTNUMBER_DEFAULT]);
  3188.     else
  3189.         DummyBuffer[0] = 0;
  3190.  
  3191.     BlockWindows();
  3192.  
  3193.     if(GetString(FALSE,FALSE,255,Args[ARG_REQUESTNUMBER_PROMPT],DummyBuffer))
  3194.     {
  3195.         STRPTR Index = DummyBuffer;
  3196.  
  3197.         while(*Index == ' ' || *Index == '\t')
  3198.             Index++;
  3199.  
  3200.         if(*Index)
  3201.         {
  3202.             LONG Value;
  3203.  
  3204.             if(StrToLong(DummyBuffer,&Value) == -1)
  3205.             {
  3206.                 Results[0] = RC_ERROR;
  3207.                 Results[1] = ERROR_BAD_NUMBER;
  3208.             }
  3209.             else
  3210.             {
  3211.                 ReleaseWindows();
  3212.  
  3213.                 SPrintf(DummyBuffer,"%ld",Value);
  3214.  
  3215.                 return(CreateResult(DummyBuffer,Results));
  3216.             }
  3217.         }
  3218.         else
  3219.             Results[0] = RC_WARN;
  3220.     }
  3221.     else
  3222.         Results[0] = RC_WARN;
  3223.  
  3224.     ReleaseWindows();
  3225.  
  3226.     return(NULL);
  3227. }
  3228.  
  3229. STRPTR __regargs
  3230. RexxRequestResponse(struct RexxPkt *Pkt)
  3231. {
  3232.     enum    {    ARG_REQUESTRESPONSE_TITLE,ARG_REQUESTRESPONSE_OPTIONS,
  3233.             ARG_REQUESTRESPONSE_PROMPT };
  3234.  
  3235.     struct EasyStruct    Easy;
  3236.     ULONG            IDCMP = NULL;
  3237.     WORD            Result;
  3238.  
  3239.     Easy . es_StructSize    = sizeof(struct EasyStruct);
  3240.     Easy . es_Flags        = NULL;
  3241.     Easy . es_TextFormat    = Args[ARG_REQUESTRESPONSE_PROMPT];
  3242.  
  3243.     if(Args[ARG_REQUESTRESPONSE_OPTIONS])
  3244.         Easy . es_GadgetFormat = Args[ARG_REQUESTRESPONSE_OPTIONS];
  3245.     else
  3246.         Easy . es_GadgetFormat = LocaleString(MSG_GLOBAL_YES_NO_TXT);
  3247.  
  3248.     if(Args[ARG_REQUESTRESPONSE_TITLE])
  3249.         Easy . es_Title    = Args[ARG_REQUESTRESPONSE_TITLE];
  3250.     else
  3251.         Easy . es_Title    = LocaleString(MSG_TERMAUX_TERM_REQUEST_TXT);
  3252.  
  3253.     BlockWindows();
  3254.  
  3255.     Result = EasyRequestArgs(Window,&Easy,&IDCMP,NULL);
  3256.  
  3257.     ReleaseWindows();
  3258.  
  3259.     if(Result)
  3260.     {
  3261.         UBYTE DummyBuffer[20];
  3262.  
  3263.         SPrintf(DummyBuffer,"%ld",Result);
  3264.  
  3265.         return(CreateResult(DummyBuffer,Results));
  3266.     }
  3267.     else
  3268.     {
  3269.         Results[0] = RC_WARN;
  3270.  
  3271.         return(NULL);
  3272.     }
  3273. }
  3274.  
  3275. STRPTR __regargs
  3276. RexxRequestString(struct RexxPkt *Pkt)
  3277. {
  3278.     enum    {    ARG_REQUESTSTRING_SECRET,ARG_REQUESTSTRING_DEFAULT,ARG_REQUESTSTRING_PROMPT };
  3279.  
  3280.     UBYTE DummyBuffer[256];
  3281.  
  3282.     if(Args[ARG_REQUESTSTRING_DEFAULT])
  3283.         strcpy(DummyBuffer,Args[ARG_REQUESTSTRING_DEFAULT]);
  3284.     else
  3285.         DummyBuffer[0] = 0;
  3286.  
  3287.     BlockWindows();
  3288.  
  3289.     if(GetString(FALSE,Args[ARG_REQUESTSTRING_SECRET] != NULL,255,Args[ARG_REQUESTSTRING_PROMPT],DummyBuffer))
  3290.     {
  3291.         ReleaseWindows();
  3292.  
  3293.         return(CreateResult(DummyBuffer,Results));
  3294.     }
  3295.     else
  3296.         Results[0] = RC_WARN;
  3297.  
  3298.     ReleaseWindows();
  3299.  
  3300.     return(NULL);
  3301. }
  3302.  
  3303. STRPTR __regargs
  3304. RexxResetScreen(struct RexxPkt *Pkt)
  3305. {
  3306.     if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3307.         XEmulatorResetConsole(XEM_IO);
  3308.     else
  3309.     {
  3310.         FreeMarker();
  3311.  
  3312.         ClearCursor();
  3313.  
  3314.         DoCancel();
  3315.  
  3316.         Reset();
  3317.  
  3318.         DrawCursor();
  3319.     }
  3320.  
  3321.     return(NULL);
  3322. }
  3323.  
  3324. STRPTR __regargs
  3325. RexxResetStyles(struct RexxPkt *Pkt)
  3326. {
  3327.     if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3328.         XEmulatorResetTextStyles(XEM_IO);
  3329.     else
  3330.     {
  3331.         DropMarker();
  3332.  
  3333.         ClearCursor();
  3334.  
  3335.         SetAttributes("0m");
  3336.  
  3337.         Config -> EmulationConfig -> FontScale = SCALE_NORMAL;
  3338.  
  3339.         FgPen = GetPenIndex(SafeTextPen);
  3340.         BgPen = 0;
  3341.  
  3342.         if(ReadAPen(RPort) != MappedPens[0][FgPen])
  3343.             SetAPen(RPort,MappedPens[0][FgPen]);
  3344.  
  3345.         if(ReadBPen(RPort) != MappedPens[0][BgPen])
  3346.             SetBPen(RPort,MappedPens[0][BgPen]);
  3347.  
  3348.         SetWrMsk(RPort,DepthMask);
  3349.  
  3350.         ConFontScaleUpdate();
  3351.  
  3352.         DrawCursor();
  3353.     }
  3354.  
  3355.     return(NULL);
  3356. }
  3357.  
  3358. STRPTR __regargs
  3359. RexxResetText(struct RexxPkt *Pkt)
  3360. {
  3361.     if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3362.         XEmulatorResetCharset(XEM_IO);
  3363.     else
  3364.     {
  3365.         DropMarker();
  3366.  
  3367.         CurrentFont = TextFont;
  3368.  
  3369.         SetFont(RPort,CurrentFont);
  3370.  
  3371.         ConOutputUpdate();
  3372.     }
  3373.  
  3374.     return(NULL);
  3375. }
  3376.  
  3377. STRPTR __regargs
  3378. RexxSaveAs(struct RexxPkt *Pkt)
  3379. {
  3380.     enum    {    ARG_SAVEAS_NAME,ARG_SAVEAS_FROM };
  3381.  
  3382.     WORD Index = ToConfig(Args[ARG_SAVEAS_FROM]);
  3383.  
  3384.     if(Index == -1)
  3385.     {
  3386.         Results[0] = RC_ERROR;
  3387.         Results[1] = ERROR_OBJECT_NOT_FOUND;
  3388.     }
  3389.     else
  3390.     {
  3391.         UBYTE    DummyBuffer[MAX_FILENAME_LENGTH];
  3392.         STRPTR    FileName;
  3393.  
  3394.         if(Args[ARG_SAVEAS_NAME])
  3395.             FileName = Args[ARG_SAVEAS_NAME];
  3396.         else
  3397.         {
  3398.             STRPTR             Title;
  3399.             struct FileRequester    *FileRequest;
  3400.  
  3401.             FileName = NULL;
  3402.  
  3403.             switch(Index)
  3404.             {
  3405.                 case DATATYPE_TRANSLATIONS:
  3406.  
  3407.                     Title = LocaleString(MSG_TRANSLATIONPANEL_SAVE_TRANSLATION_TABLES_TXT);
  3408.                     break;
  3409.  
  3410.                 case DATATYPE_FUNCTIONKEYS:
  3411.  
  3412.                     Title = LocaleString(MSG_MACROPANEL_SAVE_MACRO_KEYS_TXT);
  3413.                     break;
  3414.  
  3415.                 case DATATYPE_CURSORKEYS:
  3416.  
  3417.                     Title = LocaleString(MSG_CURSORPANEL_SAVE_CURSOR_KEYS_TXT);
  3418.                     break;
  3419.  
  3420.                 case DATATYPE_FASTMACROS:
  3421.  
  3422.                     Title = LocaleString(MSG_FASTMACROPANEL_SAVE_FAST_MACRO_SETTINGS_TXT);
  3423.                     break;
  3424.  
  3425.                 case DATATYPE_HOTKEYS:
  3426.  
  3427.                     Title = LocaleString(MSG_HOTKEYPANEL_SAVE_HOTKEYS_TXT);
  3428.                     break;
  3429.  
  3430.                 case DATATYPE_SPEECH:
  3431.  
  3432.                     Title = LocaleString(MSG_SPEECHPANEL_SAVE_SPEECH_SETTINGS_TXT);
  3433.                     break;
  3434.  
  3435.                 case DATATYPE_SOUND:
  3436.  
  3437.                     Title = LocaleString(MSG_SOUNDPANEL_SAVE_SOUNDS_TXT);
  3438.                     break;
  3439.  
  3440.                 case DATATYPE_BUFFER:
  3441.  
  3442.                     Title = LocaleString(MSG_TERMMAIN_SAVE_BUFFER_TXT);
  3443.                     break;
  3444.  
  3445.                 case DATATYPE_CONFIGURATION:
  3446.  
  3447.                     Title = LocaleString(MSG_TERMMAIN_SAVE_PREFERENCES_AS_TXT);
  3448.                     break;
  3449.  
  3450.                 case DATATYPE_PHONEBOOK:
  3451.  
  3452.                     Title = LocaleString(MSG_PHONEPANEL_SAVE_PHONEBOOK_TXT);
  3453.                     break;
  3454.  
  3455.                 case DATATYPE_SCREENTEXT:
  3456.  
  3457.                     Title = LocaleString(MSG_TERMMAIN_SAVE_SCREEN_ASCII_TXT);
  3458.                     break;
  3459.  
  3460.                 case DATATYPE_SCREENIMAGE:
  3461.  
  3462.                     Title = LocaleString(MSG_TERMMAIN_SAVE_SCREEN_IFF_TXT);
  3463.                     break;
  3464.             }
  3465.  
  3466.             BlockWindows();
  3467.  
  3468.             if(FileRequest = GetFile(Title,"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,NULL,TRUE))
  3469.             {
  3470.                 FileName = DummyBuffer;
  3471.  
  3472.                 FreeAslRequest(FileRequest);
  3473.             }
  3474.  
  3475.             ReleaseWindows();
  3476.         }
  3477.  
  3478.         if(FileName)
  3479.         {
  3480.             switch(Index)
  3481.             {
  3482.                 case DATATYPE_TRANSLATIONS:
  3483.                 {
  3484.                     if(SendTable && ReceiveTable)
  3485.                     {
  3486.                         if(!SaveTranslationTables(FileName,SendTable,ReceiveTable))
  3487.                         {
  3488.                             Results[0] = RC_ERROR;
  3489.                             Results[1] = IoErr();
  3490.                         }
  3491.                         else
  3492.                         {
  3493.                             strcpy(LastTranslation,FileName);
  3494.  
  3495.                             TranslationChanged = FALSE;
  3496.                         }
  3497.                     }
  3498.                     else
  3499.                         Results[0] = RC_WARN;
  3500.                 }
  3501.  
  3502.                 break;
  3503.  
  3504.                 case DATATYPE_FUNCTIONKEYS:
  3505.                 {
  3506.                     if(!WriteIFFData(FileName,MacroKeys,sizeof(struct MacroKeys),ID_KEYS))
  3507.                     {
  3508.                         Results[0] = RC_ERROR;
  3509.                         Results[1] = IoErr();
  3510.                     }
  3511.                     else
  3512.                     {
  3513.                         strcpy(LastMacros,FileName);
  3514.  
  3515.                         MacroChanged = FALSE;
  3516.                     }
  3517.                 }
  3518.  
  3519.                 break;
  3520.  
  3521.                 case DATATYPE_CURSORKEYS:
  3522.                 {
  3523.                     if(!WriteIFFData(FileName,CursorKeys,sizeof(struct CursorKeys),ID_KEYS))
  3524.                     {
  3525.                         Results[0] = RC_ERROR;
  3526.                         Results[1] = IoErr();
  3527.                     }
  3528.                     else
  3529.                     {
  3530.                         strcpy(LastCursorKeys,FileName);
  3531.  
  3532.                         CursorKeysChanged = FALSE;
  3533.                     }
  3534.                 }
  3535.  
  3536.                 break;
  3537.  
  3538.                 case DATATYPE_FASTMACROS:
  3539.                 {
  3540.                     if(!SaveFastMacros(FileName))
  3541.                     {
  3542.                         Results[0] = RC_ERROR;
  3543.                         Results[1] = IoErr();
  3544.                     }
  3545.                     else
  3546.                     {
  3547.                         strcpy(LastFastMacros,FileName);
  3548.  
  3549.                         FastMacrosChanged = FALSE;
  3550.                     }
  3551.                 }
  3552.  
  3553.                 break;
  3554.  
  3555.                 case DATATYPE_HOTKEYS:
  3556.                 {
  3557.                     if(!WriteIFFData(FileName,&Hotkeys,sizeof(struct Hotkeys),ID_HOTK))
  3558.                     {
  3559.                         Results[0] = RC_ERROR;
  3560.                         Results[1] = IoErr();
  3561.                     }
  3562.                     else
  3563.                     {
  3564.                         strcpy(LastKeys,FileName);
  3565.  
  3566.                         HotkeysChanged = FALSE;
  3567.                     }
  3568.                 }
  3569.  
  3570.                 break;
  3571.  
  3572.                 case DATATYPE_SPEECH:
  3573.                 {
  3574.                     if(!WriteIFFData(FileName,&SpeechConfig,sizeof(struct SpeechConfig),ID_SPEK))
  3575.                     {
  3576.                         Results[0] = RC_ERROR;
  3577.                         Results[1] = IoErr();
  3578.                     }
  3579.                     else
  3580.                     {
  3581.                         strcpy(LastSpeech,FileName);
  3582.  
  3583.                         SpeechChanged = FALSE;
  3584.                     }
  3585.                 }
  3586.  
  3587.                 break;
  3588.  
  3589.                 case DATATYPE_SOUND:
  3590.                 {
  3591.                     if(!WriteIFFData(FileName,&SoundConfig,sizeof(struct SoundConfig),ID_SOUN))
  3592.                     {
  3593.                         Results[0] = RC_ERROR;
  3594.                         Results[1] = IoErr();
  3595.                     }
  3596.                     else
  3597.                     {
  3598.                         strcpy(LastSound,FileName);
  3599.  
  3600.                         SoundChanged = FALSE;
  3601.                     }
  3602.                 }
  3603.  
  3604.                 break;
  3605.  
  3606.                 case DATATYPE_BUFFER:
  3607.                 {
  3608.                     if(BufferLines && Lines)
  3609.                     {
  3610.                         BPTR SomeFile;
  3611.  
  3612.                         if(GetFileSize(FileName))
  3613.                         {
  3614.                             if(SomeFile = Open(FileName,MODE_READWRITE))
  3615.                             {
  3616.                                 if(Seek(SomeFile,0,OFFSET_END) == -1)
  3617.                                 {
  3618.                                     Close(SomeFile);
  3619.  
  3620.                                     SomeFile = NULL;
  3621.  
  3622.                                     SetIoErr(ERROR_SEEK_ERROR);
  3623.                                 }
  3624.                             }
  3625.                         }
  3626.                         else
  3627.                             SomeFile = Open(FileName,MODE_NEWFILE);
  3628.  
  3629.                         if(SomeFile)
  3630.                         {
  3631.                             LONG i,Len;
  3632.  
  3633.                                 /* Obtain the semaphore required
  3634.                                  * to gain access to the line buffer
  3635.                                  */
  3636.  
  3637.                             ObtainSemaphore(BufferSemaphore);
  3638.  
  3639.                             for(i = 0 ; i < Lines ; i++)
  3640.                             {
  3641.                                 Len = BufferLines[i][-1];
  3642.  
  3643.                                 if(Len)
  3644.                                 {
  3645.                                     if(FWrite(SomeFile,BufferLines[i],Len,1) != 1)
  3646.                                     {
  3647.                                         Results[0] = RC_ERROR;
  3648.                                         Results[1] = IoErr();
  3649.  
  3650.                                         break;
  3651.                                     }
  3652.                                 }
  3653.  
  3654.                                 if(FPrintf(SomeFile,"\n") < 1)
  3655.                                 {
  3656.                                     Results[0] = RC_ERROR;
  3657.                                     Results[1] = IoErr();
  3658.  
  3659.                                     break;
  3660.                                 }
  3661.                             }
  3662.  
  3663.                             ReleaseSemaphore(BufferSemaphore);
  3664.  
  3665.                             Close(SomeFile);
  3666.  
  3667.                             AddProtection(FileName,FIBF_EXECUTE);
  3668.  
  3669.                             if(Config -> MiscConfig -> CreateIcons)
  3670.                                 AddIcon(FileName,FILETYPE_TEXT,TRUE);
  3671.  
  3672.                             BufferChanged = FALSE;
  3673.                         }
  3674.                         else
  3675.                         {
  3676.                             Results[0] = RC_ERROR;
  3677.                             Results[1] = IoErr();
  3678.                         }
  3679.                     }
  3680.                     else
  3681.                     {
  3682.                         Results[0] = RC_ERROR;
  3683.                         Results[1] = TERMERROR_NO_DATA_TO_PROCESS;
  3684.                     }
  3685.                 }
  3686.  
  3687.                 break;
  3688.  
  3689.                 case DATATYPE_CONFIGURATION:
  3690.                 {
  3691.                     if(!WriteConfig(FileName,Config))
  3692.                     {
  3693.                         Results[0] = RC_ERROR;
  3694.                         Results[1] = IoErr();
  3695.                     }
  3696.                     else
  3697.                     {
  3698.                         strcpy(LastConfig,FileName);
  3699.  
  3700.                         ConfigChanged = FALSE;
  3701.                     }
  3702.                 }
  3703.  
  3704.                 break;
  3705.  
  3706.                 case DATATYPE_PHONEBOOK:
  3707.                 {
  3708.                     if(!SavePhonebook(FileName))
  3709.                     {
  3710.                         Results[0] = RC_ERROR;
  3711.                         Results[1] = IoErr();
  3712.                     }
  3713.                     else
  3714.                     {
  3715.                         strcpy(LastPhone,FileName);
  3716.  
  3717.                         PhonebookChanged = FALSE;
  3718.                     }
  3719.                 }
  3720.  
  3721.                 break;
  3722.  
  3723.                 case DATATYPE_SCREENTEXT:
  3724.                 {
  3725.                     if(RasterEnabled)
  3726.                     {
  3727.                         BPTR SomeFile;
  3728.  
  3729.                         if(GetFileSize(FileName))
  3730.                         {
  3731.                             if(SomeFile = Open(FileName,MODE_READWRITE))
  3732.                             {
  3733.                                 if(Seek(SomeFile,0,OFFSET_END) == -1)
  3734.                                 {
  3735.                                     Close(SomeFile);
  3736.  
  3737.                                     SomeFile = NULL;
  3738.  
  3739.                                     SetIoErr(ERROR_SEEK_ERROR);
  3740.                                 }
  3741.                             }
  3742.                         }
  3743.                         else
  3744.                             SomeFile = Open(FileName,MODE_NEWFILE);
  3745.  
  3746.                         if(SomeFile)
  3747.                         {
  3748.                             LONG     i,j;
  3749.                             UBYTE    *Buffer;
  3750.  
  3751.                             for(i = 0 ; i < RasterHeight ; i++)
  3752.                             {
  3753.                                 Buffer = &Raster[i * RasterWidth];
  3754.  
  3755.                                 j = LastColumn;
  3756.  
  3757.                                 while(j >= 0 && Buffer[j] == ' ')
  3758.                                     j--;
  3759.  
  3760.                                 if(j >= 0)
  3761.                                 {
  3762.                                     if(!FWrite(SomeFile,Buffer,j + 1,1))
  3763.                                     {
  3764.                                         Results[0] = RC_ERROR;
  3765.                                         Results[1] = IoErr();
  3766.  
  3767.                                         break;
  3768.                                     }
  3769.                                 }
  3770.  
  3771.                                 if(!FWrite(SomeFile,"\n",1,1))
  3772.                                 {
  3773.                                     Results[0] = RC_ERROR;
  3774.                                     Results[1] = IoErr();
  3775.  
  3776.                                     break;
  3777.                                 }
  3778.                             }
  3779.  
  3780.                             Close(SomeFile);
  3781.  
  3782.                             AddProtection(FileName,FIBF_EXECUTE);
  3783.  
  3784.                             if(Config -> MiscConfig -> CreateIcons)
  3785.                                 AddIcon(FileName,FILETYPE_TEXT,TRUE);
  3786.                         }
  3787.                         else
  3788.                         {
  3789.                             Results[0] = RC_ERROR;
  3790.                             Results[1] = IoErr();
  3791.                         }
  3792.                     }
  3793.                     else
  3794.                     {
  3795.                         Results[0] = RC_ERROR;
  3796.                         Results[1] = TERMERROR_NO_DATA_TO_PROCESS;
  3797.                     }
  3798.                 }
  3799.  
  3800.                 break;
  3801.  
  3802.                 case DATATYPE_SCREENIMAGE:
  3803.                 {
  3804.                     if(!SaveWindow(FileName,Window))
  3805.                     {
  3806.                         Results[0] = RC_ERROR;
  3807.                         Results[1] = IoErr();
  3808.                     }
  3809.                 }
  3810.  
  3811.                 break;
  3812.             }
  3813.         }
  3814.         else
  3815.             Results[0] = RC_WARN;
  3816.     }
  3817.  
  3818.     return(NULL);
  3819. }
  3820.  
  3821. STRPTR __regargs
  3822. RexxSave(struct RexxPkt *Pkt)
  3823. {
  3824.     enum    {    ARG_SAVE_FROM };
  3825.  
  3826.     Args[1] = Args[ARG_SAVE_FROM];
  3827.     Args[0] = NULL;
  3828.  
  3829.     return(RexxSaveAs(Pkt));
  3830. }
  3831.  
  3832. STRPTR __regargs
  3833. RexxSelect(struct RexxPkt *Pkt)
  3834. {
  3835.     enum    {    ARG_SELECT_NAME,ARG_SELECT_FROM,ARG_SELECT_NEXT,ARG_SELECT_PREVIOUS,
  3836.             ARG_SELECT_TOP,ARG_SELECT_BOTTOM };
  3837.  
  3838.     WORD Index;
  3839.  
  3840.     if((Index = ToList(Args[ARG_SELECT_FROM])) == -1)
  3841.     {
  3842.         Results[0] = RC_ERROR;
  3843.         Results[1] = TERMERROR_UNKNOWN_LIST;
  3844.     }
  3845.     else
  3846.     {
  3847.         if(Args[ARG_SELECT_NAME] && Index == GLIST_DIAL)
  3848.         {
  3849.             Results[0] = RC_ERROR;
  3850.             Results[1] = TERMERROR_DATA_TYPES_INCOMPATIBLE;
  3851.         }
  3852.         else
  3853.         {
  3854.             struct GenericList *List;
  3855.  
  3856.             List = GenericListTable[Index];
  3857.  
  3858.             if(Args[ARG_SELECT_NAME])
  3859.             {
  3860.                 STRPTR Buffer;
  3861.  
  3862.                 if(Buffer = CreateMatchBuffer(Args[ARG_SELECT_NAME]))
  3863.                 {
  3864.                     struct Node *Node,*NextNode;
  3865.  
  3866.                     ObtainSemaphore(&List -> ListSemaphore);
  3867.  
  3868.                     Node = (struct Node *)List -> ListHeader . mlh_Head;
  3869.  
  3870.                     while(NextNode = Node -> ln_Succ)
  3871.                     {
  3872.                         if(MatchBuffer(Buffer,Node -> ln_Name))
  3873.                         {
  3874.                             List -> ListNode = Node;
  3875.  
  3876.                             Node = NULL;
  3877.  
  3878.                             break;
  3879.                         }
  3880.  
  3881.                         Node = NextNode;
  3882.                     }
  3883.  
  3884.                     if(Node)
  3885.                         Results[0] = RC_WARN;
  3886.  
  3887.                     ReleaseSemaphore(&List -> ListSemaphore);
  3888.  
  3889.                     DeleteMatchBuffer(Buffer);
  3890.                 }
  3891.                 else
  3892.                 {
  3893.                     Results[0] = RC_ERROR;
  3894.                     Results[1] = ERROR_NO_FREE_STORE;
  3895.                 }
  3896.             }
  3897.             else
  3898.             {
  3899.                 if(Args[ARG_SELECT_NEXT])
  3900.                 {
  3901.                     if(!NextGenericListNode(List))
  3902.                     {
  3903.                         Results[0] = RC_WARN;
  3904.  
  3905.                         return(NULL);
  3906.                     }
  3907.                 }
  3908.  
  3909.                 if(Args[ARG_SELECT_PREVIOUS])
  3910.                 {
  3911.                     if(!PrevGenericListNode(List))
  3912.                     {
  3913.                         Results[0] = RC_WARN;
  3914.  
  3915.                         return(NULL);
  3916.                     }
  3917.                 }
  3918.  
  3919.                 if(Args[ARG_SELECT_TOP])
  3920.                 {
  3921.                     if(!FirstGenericListNode(List))
  3922.                     {
  3923.                         Results[0] = RC_WARN;
  3924.  
  3925.                         return(NULL);
  3926.                     }
  3927.                 }
  3928.  
  3929.                 if(Args[ARG_SELECT_BOTTOM])
  3930.                 {
  3931.                     if(!LastGenericListNode(List))
  3932.                     {
  3933.                         Results[0] = RC_WARN;
  3934.  
  3935.                         return(NULL);
  3936.                     }
  3937.                 }
  3938.             }
  3939.  
  3940.             ObtainSemaphore(&List -> ListSemaphore);
  3941.  
  3942.             if(List -> ListNode)
  3943.             {
  3944.                 if(Index != GLIST_DIAL)
  3945.                 {
  3946.                     struct Node    *Node = (struct Node *)List -> ListNode;
  3947.                     STRPTR         Result;
  3948.  
  3949.                     Result = CreateResult(Node -> ln_Name,Results);
  3950.  
  3951.                     ReleaseSemaphore(&List -> ListSemaphore);
  3952.  
  3953.                     return(Result);
  3954.                 }
  3955.             }
  3956.             else
  3957.                 Results[0] = RC_WARN;
  3958.  
  3959.             ReleaseSemaphore(&List -> ListSemaphore);
  3960.         }
  3961.     }
  3962.  
  3963.     return(NULL);
  3964. }
  3965.  
  3966. STRPTR __regargs
  3967. RexxSend(struct RexxPkt *Pkt)
  3968. {
  3969.     enum    {    ARG_SEND_NOECHO,ARG_SEND_LOCAL,ARG_SEND_BYTE,ARG_SEND_TEXT };
  3970.  
  3971.     if(Args[ARG_SEND_LOCAL])
  3972.     {
  3973.         if(!Args[ARG_SEND_NOECHO])
  3974.         {
  3975.             if(Args[ARG_SEND_TEXT])
  3976.                 ConsoleCommand(Args[ARG_SEND_TEXT]);
  3977.             else
  3978.             {
  3979.                 UBYTE Byte = *(LONG *)Args[ARG_SEND_BYTE];
  3980.  
  3981.                 ConProcess(&Byte,1);
  3982.             }
  3983.         }
  3984.     }
  3985.     else
  3986.     {
  3987.         if(Args[ARG_SEND_NOECHO])
  3988.             Quiet = TRUE;
  3989.  
  3990.         if(Args[ARG_SEND_TEXT])
  3991.             LocalRexxSerialCommand(Args[ARG_SEND_TEXT],Pkt);
  3992.         else
  3993.         {
  3994.             UBYTE Byte = *(LONG *)Args[ARG_SEND_BYTE];
  3995.  
  3996.             SerWrite(&Byte,1);
  3997.         }
  3998.  
  3999.         Quiet = FALSE;
  4000.     }
  4001.  
  4002.     return(NULL);
  4003. }
  4004.  
  4005. STRPTR __regargs
  4006. RexxSendBreak(struct RexxPkt *Pkt)
  4007. {
  4008.     if(WriteRequest)
  4009.     {
  4010.         BYTE OldStatus = Status;
  4011.  
  4012.         Status = STATUS_BREAKING;
  4013.  
  4014.         WriteRequest -> IOSer . io_Command = SDCMD_BREAK;
  4015.  
  4016.         BlockWindows();
  4017.  
  4018.         DoIO(WriteRequest);
  4019.  
  4020.         ReleaseWindows();
  4021.  
  4022.         Status = OldStatus;
  4023.     }
  4024.     else
  4025.         Results[0] = RC_WARN;
  4026.  
  4027.     return(NULL);
  4028. }
  4029.  
  4030. STRPTR __regargs
  4031. RexxSendFile(struct RexxPkt *Pkt)
  4032. {
  4033.     enum    {    ARG_SENDFILE_MODE,ARG_SENDFILE_NAMES };
  4034.  
  4035.     WORD Mode = TRANSFER_BINARY;
  4036.  
  4037.     if(Args[ARG_SENDFILE_MODE])
  4038.         Mode = ToMode(Args[ARG_SENDFILE_MODE]);
  4039.  
  4040.     if(Mode == -1)
  4041.     {
  4042.         Results[0] = RC_ERROR;
  4043.         Results[1] = ERROR_ACTION_NOT_KNOWN;
  4044.     }
  4045.     else
  4046.     {
  4047.         struct FileTransferInfo    *Info;
  4048.         LONG             FilesFound = 0;
  4049.  
  4050.         if(Info = AllocFileTransferInfo())
  4051.         {
  4052.             struct GenericList *List = GenericListTable[GLIST_UPLOAD];
  4053.  
  4054.             if(Args[ARG_SENDFILE_NAMES])
  4055.             {
  4056.                 struct FileInfoBlock *FileInfo;
  4057.  
  4058.                 if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  4059.                 {
  4060.                     STRPTR    *Names = (STRPTR *)Args[ARG_SENDFILE_NAMES];
  4061.                     BPTR     FileLock,NewDir,OldDir;
  4062.  
  4063.                     NewDir = NULL;
  4064.  
  4065.                     switch(Mode)
  4066.                     {
  4067.                         case TRANSFER_BINARY:
  4068.  
  4069.                             if(Config -> PathConfig -> BinaryUploadPath[0])
  4070.                                 NewDir = Lock(Config -> PathConfig -> BinaryUploadPath,ACCESS_READ);
  4071.  
  4072.                             break;
  4073.  
  4074.                         case TRANSFER_TEXT:
  4075.  
  4076.                             if(Config -> PathConfig -> TextUploadPath[0])
  4077.                                 NewDir = Lock(Config -> PathConfig -> TextUploadPath,ACCESS_READ);
  4078.  
  4079.                             break;
  4080.  
  4081.                         case TRANSFER_ASCII:
  4082.  
  4083.                             if(Config -> PathConfig -> ASCIIUploadPath[0])
  4084.                                 NewDir = Lock(Config -> PathConfig -> ASCIIUploadPath,ACCESS_READ);
  4085.  
  4086.                             break;
  4087.                     }
  4088.  
  4089.                     if(NewDir)
  4090.                         OldDir = CurrentDir(NewDir);
  4091.                     else
  4092.                         OldDir = NULL;
  4093.  
  4094.                     while(*Names && Results[0] == RC_OK)
  4095.                     {
  4096.                         if(FileLock = Lock(*Names,ACCESS_READ))
  4097.                         {
  4098.                             if(Examine(FileLock,FileInfo))
  4099.                             {
  4100.                                 if(FileInfo -> fib_DirEntryType < 0)
  4101.                                 {
  4102.                                     if(NameFromLock(FileLock,SharedBuffer,512))
  4103.                                     {
  4104.                                         if(AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  4105.                                             FilesFound++;
  4106.                                         else
  4107.                                         {
  4108.                                             Results[0] = RC_ERROR;
  4109.                                             Results[1] = ERROR_NO_FREE_STORE;
  4110.                                         }
  4111.                                     }
  4112.                                     else
  4113.                                     {
  4114.                                         Results[0] = RC_ERROR;
  4115.                                         Results[1] = IoErr();
  4116.                                     }
  4117.                                 }
  4118.                                 else
  4119.                                 {
  4120.                                     Results[0] = RC_ERROR;
  4121.                                     Results[1] = ERROR_OBJECT_WRONG_TYPE;
  4122.                                 }
  4123.                             }
  4124.                             else
  4125.                             {
  4126.                                 Results[0] = RC_ERROR;
  4127.                                 Results[1] = IoErr();
  4128.                             }
  4129.  
  4130.                             UnLock(FileLock);
  4131.                         }
  4132.                         else
  4133.                         {
  4134.                             Results[0] = RC_ERROR;
  4135.                             Results[1] = IoErr();
  4136.                         }
  4137.  
  4138.                         Names++;
  4139.                     }
  4140.  
  4141.                     if(OldDir)
  4142.                         CurrentDir(NewDir);
  4143.  
  4144.                     if(NewDir)
  4145.                         UnLock(NewDir);
  4146.  
  4147.                     FreeDosObject(DOS_FIB,FileInfo);
  4148.                 }
  4149.                 else
  4150.                 {
  4151.                     Results[0] = RC_ERROR;
  4152.                     Results[1] = ERROR_NO_FREE_STORE;
  4153.                 }
  4154.             }
  4155.  
  4156.             ObtainSemaphore(&List -> ListSemaphore);
  4157.  
  4158.             if(List -> ListHeader . mlh_Head -> mln_Succ)
  4159.             {
  4160.                 struct Node        *Node = (struct Node *)List -> ListHeader . mlh_Head;
  4161.                 struct FileInfoBlock    *FileInfo;
  4162.                 BPTR             NewDir,OldDir;
  4163.  
  4164.                 NewDir = NULL;
  4165.  
  4166.                 switch(Mode)
  4167.                 {
  4168.                     case TRANSFER_BINARY:
  4169.  
  4170.                         if(Config -> PathConfig -> BinaryUploadPath[0])
  4171.                             NewDir = Lock(Config -> PathConfig -> BinaryUploadPath,ACCESS_READ);
  4172.  
  4173.                         break;
  4174.  
  4175.                     case TRANSFER_TEXT:
  4176.  
  4177.                         if(Config -> PathConfig -> TextUploadPath[0])
  4178.                             NewDir = Lock(Config -> PathConfig -> TextUploadPath,ACCESS_READ);
  4179.  
  4180.                         break;
  4181.  
  4182.                     case TRANSFER_ASCII:
  4183.  
  4184.                         if(Config -> PathConfig -> ASCIIUploadPath[0])
  4185.                             NewDir = Lock(Config -> PathConfig -> ASCIIUploadPath,ACCESS_READ);
  4186.  
  4187.                         break;
  4188.                 }
  4189.  
  4190.                 if(NewDir)
  4191.                     OldDir = CurrentDir(NewDir);
  4192.                 else
  4193.                     OldDir = NULL;
  4194.  
  4195.                 if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  4196.                 {
  4197.                     BPTR FileLock;
  4198.  
  4199.                     while(Node -> ln_Succ && Results[0] == RC_OK)
  4200.                     {
  4201.                         if(FileLock = Lock(Node -> ln_Name,ACCESS_READ))
  4202.                         {
  4203.                             if(Examine(FileLock,FileInfo))
  4204.                             {
  4205.                                 if(FileInfo -> fib_DirEntryType < 0)
  4206.                                 {
  4207.                                     if(NameFromLock(FileLock,SharedBuffer,512))
  4208.                                     {
  4209.                                         if(AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  4210.                                             FilesFound++;
  4211.                                         else
  4212.                                         {
  4213.                                             Results[0] = RC_ERROR;
  4214.                                             Results[1] = ERROR_NO_FREE_STORE;
  4215.                                         }
  4216.                                     }
  4217.                                     else
  4218.                                     {
  4219.                                         Results[0] = RC_ERROR;
  4220.                                         Results[1] = IoErr();
  4221.                                     }
  4222.                                 }
  4223.                                 else
  4224.                                 {
  4225.                                     Results[0] = RC_ERROR;
  4226.                                     Results[1] = ERROR_OBJECT_WRONG_TYPE;
  4227.                                 }
  4228.                             }
  4229.                             else
  4230.                             {
  4231.                                 Results[0] = RC_ERROR;
  4232.                                 Results[1] = IoErr();
  4233.                             }
  4234.  
  4235.                             UnLock(FileLock);
  4236.                         }
  4237.                         else
  4238.                         {
  4239.                             Results[0] = RC_ERROR;
  4240.                             Results[1] = IoErr();
  4241.                         }
  4242.  
  4243.                         Node = Node -> ln_Succ;
  4244.                     }
  4245.  
  4246.                     if(OldDir)
  4247.                         CurrentDir(NewDir);
  4248.  
  4249.                     if(NewDir)
  4250.                         UnLock(NewDir);
  4251.  
  4252.                     FreeDosObject(DOS_FIB,FileInfo);
  4253.                 }
  4254.                 else
  4255.                 {
  4256.                     Results[0] = RC_ERROR;
  4257.                     Results[1] = ERROR_NO_FREE_STORE;
  4258.                 }
  4259.             }
  4260.  
  4261.             ReleaseSemaphore(&List -> ListSemaphore);
  4262.  
  4263.             if(Results[0] == RC_OK)
  4264.             {
  4265.                 BlockWindows();
  4266.  
  4267.                 if(FilesFound)
  4268.                 {
  4269.                     SortFileTransferInfo(Info);
  4270.  
  4271.                     FileTransferInfo = Info;
  4272.                 }
  4273.  
  4274.                 switch(Mode)
  4275.                 {
  4276.                     case TRANSFER_ASCII:
  4277.  
  4278.                         if(ASCIISetup())
  4279.                         {
  4280.                             if(FilesFound)
  4281.                                 StartXprSendFromList(TRANSFER_ASCII,FALSE);
  4282.                             else
  4283.                                 StartXprSend(TRANSFER_ASCII,FALSE);
  4284.  
  4285.                             ASCIIShutdown();
  4286.  
  4287.                             LocalRexxSerialCommand(Config -> CommandConfig -> UploadMacro,NULL);
  4288.                         }
  4289.                         else
  4290.                         {
  4291.                             Results[0] = RC_ERROR;
  4292.                             Results[1] = ERROR_NO_FREE_STORE;
  4293.                         }
  4294.  
  4295.                         break;
  4296.  
  4297.                     case TRANSFER_TEXT:
  4298.  
  4299.                         BinaryTransfer = FALSE;
  4300.  
  4301.                         if(FilesFound)
  4302.                             StartXprSendFromList(TRANSFER_TEXT,FALSE);
  4303.                         else
  4304.                             StartXprSend(TRANSFER_TEXT,FALSE);
  4305.  
  4306.                         BinaryTransfer = TRUE;
  4307.  
  4308.                         LocalRexxSerialCommand(Config -> CommandConfig -> UploadMacro,NULL);
  4309.  
  4310.                         break;
  4311.  
  4312.                     case TRANSFER_BINARY:
  4313.  
  4314.                         BinaryTransfer = TRUE;
  4315.  
  4316.                         if(FilesFound)
  4317.                             StartXprSendFromList(TRANSFER_BINARY,FALSE);
  4318.                         else
  4319.                             StartXprSend(TRANSFER_BINARY,FALSE);
  4320.  
  4321.                         LocalRexxSerialCommand(Config -> CommandConfig -> UploadMacro,NULL);
  4322.  
  4323.                         break;
  4324.                 }
  4325.  
  4326.                 if(TransferFailed)
  4327.                     Results[0] = RC_ERROR;
  4328.  
  4329.                 if(TransferAborted)
  4330.                     Results[0] = RC_WARN;
  4331.  
  4332.                 ReleaseWindows();
  4333.             }
  4334.             else
  4335.                 FreeFileTransferInfo(Info);
  4336.         }
  4337.         else
  4338.         {
  4339.             Results[0] = RC_ERROR;
  4340.             Results[1] = ERROR_NO_FREE_STORE;
  4341.         }
  4342.     }
  4343.  
  4344.     return(NULL);
  4345. }
  4346.  
  4347. STRPTR __regargs
  4348. RexxSpeak(struct RexxPkt *Pkt)
  4349. {
  4350.     enum    {    ARG_SPEAK_TEXT };
  4351.  
  4352.     if(SpeechConfig . Enabled && English)
  4353.         Say(Args[ARG_SPEAK_TEXT]);
  4354.     else
  4355.         Results[0] = RC_WARN;
  4356.  
  4357.     return(NULL);
  4358. }
  4359.  
  4360. STRPTR __regargs
  4361. RexxStopBits(struct RexxPkt *Pkt)
  4362. {
  4363.     enum    {    ARG_STOPBITS_0,ARG_STOPBITS_1 };
  4364.  
  4365.     BYTE Bits;
  4366.  
  4367.     if(Args[ARG_STOPBITS_0])
  4368.         Bits = 0;
  4369.  
  4370.     if(Args[ARG_STOPBITS_1])
  4371.         Bits = 1;
  4372.  
  4373.     if(Config -> SerialConfig -> StopBits != Bits)
  4374.     {
  4375.         Config -> SerialConfig -> StopBits = Bits;
  4376.  
  4377.         UpdateRequired = TRUE;
  4378.  
  4379.         ConfigChanged = TRUE;
  4380.     }
  4381.  
  4382.     return(NULL);
  4383. }
  4384.  
  4385. STRPTR __regargs
  4386. RexxTextBuffer(struct RexxPkt *Pkt)
  4387. {
  4388.     enum    {    ARG_TEXTBUFFER_LOCK,ARG_TEXTBUFFER_UNLOCK };
  4389.  
  4390.     if(Args[ARG_TEXTBUFFER_LOCK])
  4391.         BufferFrozen = TRUE;
  4392.  
  4393.     if(Args[ARG_TEXTBUFFER_UNLOCK])
  4394.         BufferFrozen = FALSE;
  4395.  
  4396.     CheckItem(MEN_FREEZE_BUFFER,BufferFrozen);
  4397.  
  4398.     return(NULL);
  4399. }
  4400.  
  4401. STRPTR __regargs
  4402. RexxTimeout(struct RexxPkt *Pkt)
  4403. {
  4404.     enum    {    ARG_TIMEOUT_SECONDS,ARG_TIMEOUT_OFF };
  4405.  
  4406.     if(Args[ARG_TIMEOUT_OFF])
  4407.         RexxTimeoutVal = 0;
  4408.     else
  4409.         RexxTimeoutVal = *(LONG *)Args[ARG_TIMEOUT_SECONDS];
  4410.  
  4411.     return(NULL);
  4412.  
  4413. }
  4414.  
  4415. STRPTR __regargs
  4416. RexxWait(struct RexxPkt *Pkt)
  4417. {
  4418.     enum    {    ARG_WAIT_NOECHO,ARG_WAIT_TEXT };
  4419.  
  4420.     ULONG         Signals;
  4421.     STRPTR         Result = NULL;
  4422.     BYTE         Echo;
  4423.     struct WaitNode    *WaitNode,
  4424.              Node;
  4425.     UBYTE         DummyBuffer[256];
  4426.  
  4427.     if(!ReadRequest || !WriteRequest)
  4428.     {
  4429.         Results[0] = RC_WARN;
  4430.  
  4431.         return(NULL);
  4432.     }
  4433.  
  4434.     if(Args[ARG_WAIT_NOECHO])
  4435.         Echo = FALSE;
  4436.     else
  4437.         Echo = TRUE;
  4438.  
  4439.     if(Args[ARG_WAIT_TEXT])
  4440.     {
  4441.         WORD i;
  4442.  
  4443.         memcpy(DummyBuffer,Args[ARG_WAIT_TEXT],255);
  4444.  
  4445.         DummyBuffer[255] = 0;
  4446.  
  4447.         for(i = 0 ; i < strlen(DummyBuffer) ; i++)
  4448.             DummyBuffer[i] = ToUpper(DummyBuffer[i]);
  4449.  
  4450.         memset(&Node,0,sizeof(struct WaitNode));
  4451.  
  4452.         Node . Node . ln_Name    = DummyBuffer;
  4453.         Node . Count        = 0;
  4454.  
  4455.         WaitNode = &Node;
  4456.     }
  4457.     else
  4458.     {
  4459.         if(!GenericListCount(GenericListTable[GLIST_WAIT]))
  4460.         {
  4461.             Results[0] = RC_ERROR;
  4462.             Results[1] = TERMERROR_LIST_IS_ALREADY_EMPTY;
  4463.  
  4464.             return(NULL);
  4465.         }
  4466.         else
  4467.         {
  4468.             WaitNode = (struct WaitNode *)GenericListTable[GLIST_WAIT] -> ListHeader . mlh_Head;
  4469.  
  4470.             while(WaitNode -> Node . ln_Succ)
  4471.             {
  4472.                 WaitNode -> Count = 0;
  4473.  
  4474.                 WaitNode = (struct WaitNode *)WaitNode -> Node . ln_Succ;
  4475.             }
  4476.  
  4477.             WaitNode = NULL;
  4478.         }
  4479.     }
  4480.  
  4481.     if(RexxTimeoutVal)
  4482.         StartTime(RexxTimeoutVal,0);
  4483.  
  4484.     WaitCount = 0;
  4485.  
  4486.     BlockWindows();
  4487.  
  4488.     if(Marking)
  4489.         DropMarker();
  4490.  
  4491.     ClearCursor();
  4492.  
  4493.     if(CheckIO(ReadRequest))
  4494.         Signals = SIG_SERIAL;
  4495.     else
  4496.         Signals = NULL;
  4497.  
  4498.     do
  4499.     {
  4500.         if(Signals & SIG_SERIAL)
  4501.         {
  4502.             if(!WaitIO(ReadRequest))
  4503.             {
  4504.                 LONG Length;
  4505.  
  4506.                 BytesIn++;
  4507.  
  4508.                 if(Echo)
  4509.                 {
  4510.                     ConProcess(ReadBuffer,1);
  4511.  
  4512.                     Status = STATUS_READY;
  4513.                 }
  4514.  
  4515.                 if(!Result)
  4516.                     Result = ScanNodeFilter(ReadBuffer,1,WaitNode);
  4517.  
  4518.                 do
  4519.                 {
  4520.                         /* Check how many bytes are still in
  4521.                          * the serial buffer.
  4522.                          */
  4523.  
  4524.                     WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  4525.  
  4526.                     DoIO(WriteRequest);
  4527.  
  4528.                     if(Length = WriteRequest -> IOSer . io_Actual)
  4529.                     {
  4530.                         if(Length > Config -> SerialConfig -> SerialBufferSize)
  4531.                             Length = Config -> SerialConfig -> SerialBufferSize;
  4532.  
  4533.                         ReadRequest -> IOSer . io_Command    = CMD_READ;
  4534.                         ReadRequest -> IOSer . io_Data        = ReadBuffer;
  4535.                         ReadRequest -> IOSer . io_Length    = Length;
  4536.  
  4537.                         if(!DoIO(ReadRequest))
  4538.                         {
  4539.                             BytesIn += Length;
  4540.  
  4541.                                 /* Send the data to the console. */
  4542.  
  4543.                             if(Echo)
  4544.                             {
  4545.                                 ConProcess(ReadBuffer,Length);
  4546.  
  4547.                                 Status = STATUS_READY;
  4548.                             }
  4549.                         }
  4550.  
  4551.                         if(!Result)
  4552.                             Result = ScanNodeFilter(ReadBuffer,Length,WaitNode);
  4553.                     }
  4554.                 }
  4555.                 while(Length);
  4556.             }
  4557.  
  4558.             RestartSerial();
  4559.         }
  4560.  
  4561.         if(Signals & (SIG_BREAK | SIG_TIMER))
  4562.         {
  4563.             if(!Result)
  4564.                 Results[0] = RC_WARN;
  4565.  
  4566.             break;
  4567.         }
  4568.  
  4569.         if(!Result)
  4570.             Signals = Wait(SIG_SERIAL | SIG_TIMER | SIG_BREAK);
  4571.     }
  4572.     while(!Result);
  4573.  
  4574.     DrawCursor();
  4575.  
  4576.     ReleaseWindows();
  4577.  
  4578.     if(RexxTimeoutVal)
  4579.     {
  4580.         if(!CheckIO(TimeRequest))
  4581.             AbortIO(TimeRequest);
  4582.  
  4583.         WaitIO(TimeRequest);
  4584.     }
  4585.  
  4586.     if(Result)
  4587.         return(CreateResult(Result,Results));
  4588.     else
  4589.         return(NULL);
  4590. }
  4591.  
  4592. STRPTR __regargs
  4593. RexxWindow(struct RexxPkt *Pkt)
  4594. {
  4595.     enum    {    ARG_WINDOW_NAMES,ARG_WINDOW_OPEN,ARG_WINDOW_CLOSE,ARG_WINDOW_ACTIVATE,
  4596.             ARG_WINDOW_MIN,ARG_WINDOW_MAX,ARG_WINDOW_FRONT,ARG_WINDOW_BACK,
  4597.             ARG_WINDOW_TOP,ARG_WINDOW_BOTTOM,ARG_WINDOW_UP,ARG_WINDOW_DOWN };
  4598.  
  4599.     STRPTR    *Names = (STRPTR *)Args[ARG_WINDOW_NAMES];
  4600.     WORD     Index;
  4601.  
  4602.     while(*Names)
  4603.     {
  4604.         if((Index = ToWindow(*Names++)) != -1)
  4605.         {
  4606.             if(Args[ARG_WINDOW_OPEN])
  4607.             {
  4608.                 switch(Index)
  4609.                 {
  4610.                     case WINDOW_BUFFER:
  4611.  
  4612.                         if(!BufferProcess)
  4613.                             LaunchBuffer();
  4614.  
  4615.                         break;
  4616.  
  4617.                     case WINDOW_REVIEW:
  4618.  
  4619.                         if(!ReviewWindow)
  4620.                             CreateReview();
  4621.  
  4622.                         break;
  4623.  
  4624.                     case WINDOW_PACKET:
  4625.  
  4626.                         if(!PacketWindow)
  4627.                             CreatePacketWindow();
  4628.  
  4629.                         break;
  4630.  
  4631.                     case WINDOW_FASTMACROS:
  4632.  
  4633.                         if(!FastWindow)
  4634.                             OpenFastWindow();
  4635.  
  4636.                         break;
  4637.  
  4638.                     case WINDOW_STATUS:
  4639.  
  4640.                         if(!InfoWindow)
  4641.                             OpenInfoWindow();
  4642.  
  4643.                         break;
  4644.  
  4645.                     case WINDOW_MAIN:
  4646.  
  4647.                         if(!IconTerminated)
  4648.                             IconTerminated = TRUE;
  4649.  
  4650.                         break;
  4651.                 }
  4652.             }
  4653.  
  4654.             if(Args[ARG_WINDOW_CLOSE])
  4655.             {
  4656.                 switch(Index)
  4657.                 {
  4658.                     case WINDOW_BUFFER:
  4659.  
  4660.                         if(BufferProcess)
  4661.                         {
  4662.                             Forbid();
  4663.  
  4664.                             Signal(BufferProcess,SIG_KILL);
  4665.  
  4666.                             ClrSignal(SIG_HANDSHAKE);
  4667.  
  4668.                             Wait(SIG_HANDSHAKE);
  4669.  
  4670.                             Permit();
  4671.                         }
  4672.  
  4673.                         break;
  4674.  
  4675.                     case WINDOW_REVIEW:
  4676.  
  4677.                         if(ReviewWindow)
  4678.                             DeleteReview();
  4679.  
  4680.                         break;
  4681.  
  4682.                     case WINDOW_PACKET:
  4683.  
  4684.                         if(PacketWindow)
  4685.                             DeletePacketWindow(FALSE);
  4686.  
  4687.                         break;
  4688.  
  4689.                     case WINDOW_FASTMACROS:
  4690.  
  4691.                         if(FastWindow)
  4692.                             CloseFastWindow();
  4693.  
  4694.                         break;
  4695.  
  4696.                     case WINDOW_STATUS:
  4697.  
  4698.                         if(InfoWindow)
  4699.                             CloseInfoWindow();
  4700.  
  4701.                         break;
  4702.  
  4703.                     case WINDOW_MAIN:
  4704.  
  4705.                         if(Window)
  4706.                             DoIconify = TRUE;
  4707.  
  4708.                         break;
  4709.                 }
  4710.             }
  4711.  
  4712.             if(Args[ARG_WINDOW_ACTIVATE])
  4713.             {
  4714.                 switch(Index)
  4715.                 {
  4716.                     case WINDOW_BUFFER:
  4717.  
  4718.                         if(BufferProcess)
  4719.                             LaunchBuffer();
  4720.  
  4721.                         break;
  4722.  
  4723.                     case WINDOW_REVIEW:
  4724.  
  4725.                         if(ReviewWindow)
  4726.                             BumpWindow(ReviewWindow);
  4727.  
  4728.                         break;
  4729.  
  4730.                     case WINDOW_PACKET:
  4731.  
  4732.                         if(PacketWindow)
  4733.                             BumpWindow(PacketWindow);
  4734.  
  4735.                         break;
  4736.  
  4737.                     case WINDOW_FASTMACROS:
  4738.  
  4739.                         if(FastWindow)
  4740.                             BumpWindow(FastWindow);
  4741.  
  4742.                         break;
  4743.  
  4744.                     case WINDOW_STATUS:
  4745.  
  4746.                         if(InfoWindow)
  4747.                             BumpWindow(InfoWindow);
  4748.  
  4749.                         break;
  4750.  
  4751.                     case WINDOW_MAIN:
  4752.  
  4753.                         if(Window)
  4754.                             BumpWindow(Window);
  4755.  
  4756.                         break;
  4757.                 }
  4758.             }
  4759.  
  4760.             if(Args[ARG_WINDOW_MIN])
  4761.             {
  4762.                 struct Window *SomeWindow = NULL;
  4763.  
  4764.                 switch(Index)
  4765.                 {
  4766.                     case WINDOW_REVIEW:
  4767.  
  4768.                         SomeWindow = ReviewWindow;
  4769.                         break;
  4770.  
  4771.                     case WINDOW_PACKET:
  4772.  
  4773.                         SomeWindow = PacketWindow;
  4774.                         break;
  4775.  
  4776.                     case WINDOW_FASTMACROS:
  4777.  
  4778.                         SomeWindow = FastWindow;
  4779.                         break;
  4780.  
  4781.                     case WINDOW_STATUS:
  4782.  
  4783.                         SomeWindow = InfoWindow;
  4784.                         break;
  4785.                 }
  4786.  
  4787.                 if(SomeWindow)
  4788.                     ChangeWindowBox(SomeWindow,SomeWindow -> LeftEdge,SomeWindow -> TopEdge,SomeWindow -> MinWidth,SomeWindow -> MinHeight);
  4789.             }
  4790.  
  4791.             if(Args[ARG_WINDOW_MAX])
  4792.             {
  4793.                 struct Window *SomeWindow = NULL;
  4794.  
  4795.                 switch(Index)
  4796.                 {
  4797.                     case WINDOW_REVIEW:
  4798.  
  4799.                         SomeWindow = ReviewWindow;
  4800.                         break;
  4801.  
  4802.                     case WINDOW_PACKET:
  4803.  
  4804.                         SomeWindow = PacketWindow;
  4805.                         break;
  4806.  
  4807.                     case WINDOW_FASTMACROS:
  4808.  
  4809.                         SomeWindow = FastWindow;
  4810.                         break;
  4811.  
  4812.                     case WINDOW_STATUS:
  4813.  
  4814.                         SomeWindow = InfoWindow;
  4815.                         break;
  4816.                 }
  4817.  
  4818.                 if(SomeWindow)
  4819.                     ChangeWindowBox(SomeWindow,0,0,SomeWindow -> MaxWidth,SomeWindow -> MaxHeight);
  4820.             }
  4821.  
  4822.             if(Args[ARG_WINDOW_FRONT])
  4823.             {
  4824.                 switch(Index)
  4825.                 {
  4826.                     case WINDOW_BUFFER:
  4827.  
  4828.                         if(BufferProcess)
  4829.                             LaunchBuffer();
  4830.  
  4831.                         break;
  4832.  
  4833.                     case WINDOW_REVIEW:
  4834.  
  4835.                         if(ReviewWindow)
  4836.                             WindowToFront(ReviewWindow);
  4837.  
  4838.                         break;
  4839.  
  4840.                     case WINDOW_PACKET:
  4841.  
  4842.                         if(PacketWindow)
  4843.                             WindowToFront(PacketWindow);
  4844.  
  4845.                         break;
  4846.  
  4847.                     case WINDOW_FASTMACROS:
  4848.  
  4849.                         if(FastWindow)
  4850.                             WindowToFront(FastWindow);
  4851.  
  4852.                         break;
  4853.  
  4854.                     case WINDOW_STATUS:
  4855.  
  4856.                         if(InfoWindow)
  4857.                             WindowToFront(InfoWindow);
  4858.  
  4859.                         break;
  4860.  
  4861.                     case WINDOW_MAIN:
  4862.  
  4863.                         if(Window)
  4864.                             WindowToFront(Window);
  4865.  
  4866.                         break;
  4867.                 }
  4868.             }
  4869.  
  4870.             if(Args[ARG_WINDOW_BACK])
  4871.             {
  4872.                 switch(Index)
  4873.                 {
  4874.                     case WINDOW_REVIEW:
  4875.  
  4876.                         if(ReviewWindow)
  4877.                             WindowToBack(ReviewWindow);
  4878.  
  4879.                         break;
  4880.  
  4881.                     case WINDOW_PACKET:
  4882.  
  4883.                         if(PacketWindow)
  4884.                             WindowToBack(PacketWindow);
  4885.  
  4886.                         break;
  4887.  
  4888.                     case WINDOW_FASTMACROS:
  4889.  
  4890.                         if(FastWindow)
  4891.                             WindowToBack(FastWindow);
  4892.  
  4893.                         break;
  4894.  
  4895.                     case WINDOW_STATUS:
  4896.  
  4897.                         if(InfoWindow)
  4898.                             WindowToBack(InfoWindow);
  4899.  
  4900.                         break;
  4901.  
  4902.                     case WINDOW_MAIN:
  4903.  
  4904.                         if(Window)
  4905.                             WindowToBack(Window);
  4906.  
  4907.                         break;
  4908.                 }
  4909.             }
  4910.  
  4911.             if(Index == WINDOW_REVIEW && ReviewWindow)
  4912.             {
  4913.                 if(Args[ARG_WINDOW_TOP])
  4914.                     MoveReview(REVIEW_MOVE_TOP);
  4915.  
  4916.                 if(Args[ARG_WINDOW_BOTTOM])
  4917.                     MoveReview(REVIEW_MOVE_BOTTOM);
  4918.  
  4919.                 if(Args[ARG_WINDOW_UP])
  4920.                     MoveReview(REVIEW_MOVE_UP);
  4921.  
  4922.                 if(Args[ARG_WINDOW_DOWN])
  4923.                     MoveReview(REVIEW_MOVE_DOWN);
  4924.             }
  4925.         }
  4926.     }
  4927.  
  4928.     return(NULL);
  4929. }
  4930.  
  4931. STRPTR __regargs
  4932. RexxRX(struct RexxPkt *Pkt)
  4933. {
  4934.     enum    {    ARG_RX_CONSOLE,ARG_RX_ASYNC,ARG_RX_COMMAND };
  4935.  
  4936.     struct MsgPort    *RexxPort;
  4937.     BYTE         Eaten = FALSE;
  4938.  
  4939.     if(RexxPort = FindPort(RXSDIR))
  4940.     {
  4941.         struct MsgPort __aligned     SinglePort;
  4942.         struct RexxMsg            *HostMessage;
  4943.  
  4944.         InitSinglePort(&SinglePort);
  4945.  
  4946.         if(HostMessage = CreateRexxMsg(&SinglePort,"term",RexxPortName))
  4947.         {
  4948.             if(HostMessage -> rm_Args[0] = CreateArgstring(Args[ARG_RX_COMMAND],strlen(Args[ARG_RX_COMMAND])))
  4949.             {
  4950.                 HostMessage -> rm_Action = RXCOMM;
  4951.  
  4952.                 if(!GoodStream(NULL))
  4953.                     HostMessage -> rm_Action |= RXFF_NOIO;
  4954.  
  4955.                 if(Args[ARG_RX_ASYNC])
  4956.                 {
  4957.                     RexxPktCleanup(Pkt,NULL);
  4958.  
  4959.                     Eaten = TRUE;
  4960.                 }
  4961.  
  4962.                 Forbid();
  4963.  
  4964.                 PutMsg(RexxPort,HostMessage);
  4965.  
  4966.                 ClrSignal(SIGF_SINGLE);
  4967.  
  4968.                 WaitPort(&SinglePort);
  4969.  
  4970.                 Permit();
  4971.  
  4972.                 GetMsg(&SinglePort);
  4973.  
  4974.                 if(!Eaten)
  4975.                 {
  4976.                     Results[0] = HostMessage -> rm_Result1;
  4977.                     Results[1] = HostMessage -> rm_Result2;
  4978.                 }
  4979.             }
  4980.             else
  4981.             {
  4982.                 Results[0] = RC_ERROR;
  4983.                 Results[1] = ERR10_003;
  4984.             }
  4985.  
  4986.             DeleteRexxMsg(HostMessage);
  4987.         }
  4988.         else
  4989.         {
  4990.             Results[0] = RC_ERROR;
  4991.             Results[1] = ERR10_003;
  4992.         }
  4993.     }
  4994.     else
  4995.     {
  4996.         Results[0] = RC_ERROR;
  4997.         Results[1] = ERR10_013;
  4998.     }
  4999.  
  5000.     if(!Eaten)
  5001.         RexxPktCleanup(Pkt,NULL);
  5002.  
  5003.     return(NULL);
  5004. }
  5005.  
  5006. STRPTR __regargs
  5007. RexxExecTool(struct RexxPkt *Pkt)
  5008. {
  5009.     enum    {    ARG_EXECTOOL_CONSOLE,ARG_EXECTOOL_ASYNC,ARG_EXECTOOL_PORT,ARG_EXECTOOL_COMMAND };
  5010.  
  5011.     LONG     Error;
  5012.     UBYTE     CommandName[256],
  5013.          CommandArgs[256],
  5014.         *Index = Args[ARG_EXECTOOL_COMMAND];
  5015.     WORD     i;
  5016.     BYTE     Eaten = FALSE;
  5017.  
  5018.     while(*Index == ' ' || *Index == '\t')
  5019.         Index++;
  5020.  
  5021.     for(i = 0 ; Index[i] != ' ' && Index[i] != '\t' ; i++)
  5022.         CommandName[i] = Index[i];
  5023.  
  5024.     CommandName[i] = 0;
  5025.  
  5026.     Index += i;
  5027.  
  5028.     while(*Index == ' ' || *Index == '\t')
  5029.         Index++;
  5030.  
  5031.     if(Args[ARG_EXECTOOL_PORT])
  5032.         SPrintf(CommandArgs,"%s %s\n",Index,RexxPortName);
  5033.     else
  5034.         SPrintf(CommandArgs,"%s\n",Index);
  5035.  
  5036.     if(Args[ARG_EXECTOOL_ASYNC])
  5037.     {
  5038.         RexxPktCleanup(Pkt,NULL);
  5039.  
  5040.         Eaten = TRUE;
  5041.     }
  5042.  
  5043.     Error = SystemTags(CommandName,
  5044.         NP_Arguments,CommandArgs,
  5045.     TAG_DONE);
  5046.  
  5047.     if(!Eaten)
  5048.     {
  5049.         if(Error)
  5050.         {
  5051.             Results[0] = RC_ERROR;
  5052.             Results[1] = Error;
  5053.         }
  5054.  
  5055.         RexxPktCleanup(Pkt,NULL);
  5056.     }
  5057.  
  5058.     return(NULL);
  5059. }
  5060.