home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d8xx / d832 / term.lha / Term / term-3.1-Source.lha / termARexxCommands.c < prev    next >
C/C++ Source or Header  |  1993-02-18  |  86KB  |  4,871 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])
  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])
  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.                 SetSignal(0,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.                 SerWrite(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)))
  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.                 FreeBuffer();
  974.             else
  975.             {
  976.                 BlockWindows();
  977.  
  978.                 if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
  979.                     FreeBuffer();
  980.                 else
  981.                     Results[0] = RC_WARN;
  982.  
  983.                 ReleaseWindows();
  984.             }
  985.         }
  986.     }
  987.     else
  988.     {
  989.         WORD ListIndex;
  990.  
  991.         if((ListIndex = ToList(Args[ARG_CLEAR_FROM])) != -1)
  992.             ClearGenericList(GenericListTable[ListIndex]);
  993.         else
  994.         {
  995.             Results[0] = RC_ERROR;
  996.             Results[1] = TERMERROR_UNKNOWN_LIST;
  997.         }
  998.     }
  999.  
  1000.     return(NULL);
  1001. }
  1002.  
  1003. STRPTR __regargs
  1004. RexxClearScreen(struct RexxPkt *Pkt)
  1005. {
  1006.     if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  1007.         XEmulatorClearConsole(XEM_IO);
  1008.     else
  1009.     {
  1010.         DropMarker();
  1011.  
  1012.         ClearCursor();
  1013.  
  1014.         EraseScreen("2J");
  1015.  
  1016.         SetAbsolutePosition("H");
  1017.  
  1018.         DrawCursor();
  1019.     }
  1020.  
  1021.     return(NULL);
  1022. }
  1023.  
  1024. STRPTR __regargs
  1025. RexxClose(struct RexxPkt *Pkt)
  1026. {
  1027.     enum    {    ARG_CLOSE_FROM };
  1028.  
  1029.     STATIC STRPTR ValidArgs[3] =
  1030.     {
  1031.         "PRINTER",
  1032.         "FILE",
  1033.         "ALL"
  1034.     };
  1035.  
  1036.     WORD i;
  1037.  
  1038.     for(i = 0 ; i < 3 ; i++)
  1039.     {
  1040.         if(!Stricmp(Args[ARG_CLOSE_FROM],ValidArgs[i]))
  1041.         {
  1042.             if(i == 0 || i == 2)
  1043.             {
  1044.                 if(PrinterCapture)
  1045.                     ClosePrinterCapture(TRUE);
  1046.             }
  1047.  
  1048.             if(i == 1 || i == 2)
  1049.             {
  1050.                 if(FileCapture)
  1051.                 {
  1052.                     BufferClose(FileCapture);
  1053.  
  1054.                     CheckItem(MEN_CAPTURE_TO_FILE,FALSE);
  1055.  
  1056.                     FileCapture = NULL;
  1057.  
  1058.                     if(!GetFileSize(CaptureName))
  1059.                         DeleteFile(CaptureName);
  1060.                     else
  1061.                         SetProtection(CaptureName,FIBF_EXECUTE);
  1062.  
  1063.                     ConOutputUpdate();
  1064.                 }
  1065.             }
  1066.  
  1067.             return(NULL);
  1068.         }
  1069.     }
  1070.  
  1071.     Results[0] = RC_ERROR;
  1072.     Results[1] = ERROR_TOO_MANY_ARGS;
  1073.  
  1074.     return(NULL);
  1075. }
  1076.  
  1077. STRPTR __regargs
  1078. RexxCloseDevice(struct RexxPkt *Pkt)
  1079. {
  1080.     ClearSerial();
  1081.  
  1082.     DeleteSerial();
  1083.  
  1084.     return(NULL);
  1085. }
  1086.  
  1087. STRPTR __regargs
  1088. RexxCloseRequester(struct RexxPkt *Pkt)
  1089. {
  1090.     if(ThisProcess)
  1091.         Signal(ThisProcess,SIG_BREAK);
  1092.     else
  1093.         Results[0] = RC_WARN;
  1094.  
  1095.     return(NULL);
  1096. }
  1097.  
  1098. STRPTR __regargs
  1099. RexxDeactivate(struct RexxPkt *Pkt)
  1100. {
  1101.     if(Window)
  1102.         DoIconify = TRUE;
  1103.  
  1104.     return(NULL);
  1105. }
  1106.  
  1107. STRPTR __regargs
  1108. RexxDial(struct RexxPkt *Pkt)
  1109. {
  1110.     enum    {    ARG_DIAL_NUM };
  1111.  
  1112.     struct PhoneNode    *DialNode;
  1113.     struct GenericList    *List;
  1114.  
  1115.     if(Args[ARG_DIAL_NUM])
  1116.     {
  1117.         struct List *LocalList;
  1118.  
  1119.         if(LocalList = (struct List *)AllocVec(sizeof(struct List),MEMF_ANY))
  1120.         {
  1121.             LONG Len = strlen(Args[ARG_DIAL_NUM]);
  1122.  
  1123.             NewList(LocalList);
  1124.  
  1125.             if(DialNode = (struct PhoneNode *)AllocVec(sizeof(struct PhoneNode) + Len + 1,MEMF_ANY | MEMF_CLEAR))
  1126.             {
  1127.                 DialNode -> VanillaNode . ln_Name = (STRPTR)(DialNode + 1);
  1128.  
  1129.                 strcpy(DialNode -> VanillaNode . ln_Name,Args[ARG_DIAL_NUM]);
  1130.  
  1131.                 AddTail(LocalList,&DialNode -> VanillaNode);
  1132.  
  1133.                 FreeDialList(TRUE);
  1134.  
  1135.                 DialList = LocalList;
  1136.             }
  1137.             else
  1138.             {
  1139.                 FreeVec(LocalList);
  1140.  
  1141.                 Results[0] = RC_ERROR;
  1142.                 Results[1] = ERROR_NO_FREE_STORE;
  1143.  
  1144.                 return(NULL);
  1145.             }
  1146.         }
  1147.     }
  1148.     else
  1149.     {
  1150.         if(GenericListCount(List = GenericListTable[GLIST_DIAL]))
  1151.         {
  1152.             struct DialNode *Node = (struct DialNode *)FirstGenericListNode(List);
  1153.  
  1154.             if(Node)
  1155.             {
  1156.                 LONG Len;
  1157.  
  1158.                 if(!DialList)
  1159.                 {
  1160.                     if(DialList = (struct List *)AllocVec(sizeof(struct List),MEMF_ANY | MEMF_CLEAR))
  1161.                         NewList(DialList);
  1162.                 }
  1163.  
  1164.                 if(DialList)
  1165.                 {
  1166.                     while(Node)
  1167.                     {
  1168.                         if(Node -> Entry)
  1169.                             Len = 0;
  1170.                         else
  1171.                             Len = strlen(Node -> Node . ln_Name) + 1;
  1172.  
  1173.                         if(DialNode = (struct PhoneNode *)AllocVec(sizeof(struct PhoneNode) + Len,MEMF_ANY | MEMF_CLEAR))
  1174.                         {
  1175.                             if(Node -> Entry)
  1176.                                 DialNode -> Entry = Node -> Entry;
  1177.                             else
  1178.                             {
  1179.                                 DialNode -> VanillaNode . ln_Name = (STRPTR)(DialNode + 1);
  1180.  
  1181.                                 strcpy(DialNode -> VanillaNode . ln_Name,Node -> Node . ln_Name);
  1182.                             }
  1183.  
  1184.                             AddTail(DialList,&DialNode -> VanillaNode);
  1185.                         }
  1186.                         else
  1187.                         {
  1188.                             FreeDialList(FALSE);
  1189.  
  1190.                             Results[0] = RC_ERROR;
  1191.                             Results[1] = ERROR_NO_FREE_STORE;
  1192.  
  1193.                             return(NULL);
  1194.                         }
  1195.  
  1196.                         Node = (struct DialNode *)NextGenericListNode(List);
  1197.                     }
  1198.                 }
  1199.             }
  1200.         }
  1201.     }
  1202.  
  1203.     if(DialList)
  1204.     {
  1205.         if(DialList -> lh_Head -> ln_Succ)
  1206.             DoDial = DIAL_LIST;
  1207.         else
  1208.         {
  1209.             FreeDialList(FALSE);
  1210.  
  1211.             Results[0] = RC_ERROR;
  1212.             Results[1] = TERMERROR_LIST_IS_ALREADY_EMPTY;
  1213.         }
  1214.     }
  1215.     else
  1216.     {
  1217.         Results[0] = RC_ERROR;
  1218.         Results[1] = ERROR_NO_FREE_STORE;
  1219.     }
  1220.  
  1221.     return(NULL);
  1222. }
  1223.  
  1224. STRPTR __regargs
  1225. RexxDelay(struct RexxPkt *Pkt)
  1226. {
  1227.     enum    {    ARG_DELAY_MICROSECONDS,ARG_DELAY_SECONDS,ARG_DELAY_MINUTES };
  1228.  
  1229.     LONG    Seconds = 0,
  1230.         Micros;
  1231.     ULONG    Signals;
  1232.  
  1233.     if(Args[ARG_DELAY_MINUTES])
  1234.         Seconds += 60 * (*(LONG *)Args[ARG_DELAY_MINUTES]);
  1235.  
  1236.     if(Args[ARG_DELAY_SECONDS])
  1237.         Seconds += *(LONG *)Args[ARG_DELAY_SECONDS];
  1238.  
  1239.     if(Args[ARG_DELAY_MICROSECONDS])
  1240.         Micros = *(LONG *)Args[ARG_DELAY_MICROSECONDS];
  1241.     else
  1242.         Micros = 0;
  1243.  
  1244.     if(Seconds || Micros)
  1245.     {
  1246.         TimeRequest -> tr_node . io_Command    = TR_ADDREQUEST;
  1247.         TimeRequest -> tr_time . tv_secs    = Seconds;
  1248.         TimeRequest -> tr_time . tv_micro    = Micros;
  1249.  
  1250.         BeginIO(TimeRequest);
  1251.  
  1252.         BlockWindows();
  1253.  
  1254.         FOREVER
  1255.         {
  1256.             Signals = Wait(SIG_TIMER | SIG_BREAK);
  1257.  
  1258.             if(Signals & SIG_BREAK)
  1259.             {
  1260.                 if(!CheckIO(TimeRequest))
  1261.                     AbortIO(TimeRequest);
  1262.  
  1263.                 WaitIO(TimeRequest);
  1264.  
  1265.                 Results[0] = RC_WARN;
  1266.  
  1267.                 break;
  1268.             }
  1269.  
  1270.             if(Signals & SIG_TIMER)
  1271.             {
  1272.                 WaitIO(TimeRequest);
  1273.  
  1274.                 break;
  1275.             }
  1276.         }
  1277.  
  1278.         ReleaseWindows();
  1279.     }
  1280.  
  1281.     return(NULL);
  1282. }
  1283.  
  1284. STRPTR __regargs
  1285. RexxDuplex(struct RexxPkt *Pkt)
  1286. {
  1287.     enum    {    ARG_DUPLEX_FULL,ARG_DUPLEX_HALF };
  1288.  
  1289.     BYTE Mode;
  1290.  
  1291.     if(Args[ARG_DUPLEX_FULL])
  1292.         Mode = DUPLEX_FULL;
  1293.  
  1294.     if(Args[ARG_DUPLEX_HALF])
  1295.         Mode = DUPLEX_HALF;
  1296.  
  1297.     if(Config -> SerialConfig -> Duplex != Mode)
  1298.     {
  1299.         Config -> SerialConfig -> Duplex = Mode;
  1300.  
  1301.         UpdateRequired = TRUE;
  1302.  
  1303.         ConfigChanged = TRUE;
  1304.     }
  1305.  
  1306.     return(NULL);
  1307. }
  1308.  
  1309. STRPTR __regargs
  1310. RexxFault(struct RexxPkt *Pkt)
  1311. {
  1312.     enum    {    ARG_FAULT_CODE };
  1313.  
  1314.     LONG    Code = *(LONG *)Args[ARG_FAULT_CODE];
  1315.     UBYTE    RexxResultString[256];
  1316.     STRPTR    Result;
  1317.  
  1318.     if(Code >= ERR10_001 && Code <= ERR10_048)
  1319.         Result = LocaleString(MSG_AREXX_SYSERR10_001_TXT + Code - ERR10_001);
  1320.     else
  1321.     {
  1322.         if(Code >= TERMERROR_NO_DATA_TO_PROCESS && Code <= TERMERROR_WRONG_LIST)
  1323.             Result = LocaleString(MSG_AREXX_HOSTERR_000_TXT + Code - TERMERROR_NO_DATA_TO_PROCESS);
  1324.         else
  1325.         {
  1326.             Fault(Code,"",RexxResultString,256);
  1327.  
  1328.             Result = &RexxResultString[2];
  1329.         }
  1330.     }
  1331.  
  1332.     return(CreateResult(Result,Results));
  1333. }
  1334.  
  1335. STRPTR __regargs
  1336. RexxGetClip(struct RexxPkt *Pkt)
  1337. {
  1338.     enum    {    ARG_GETCLIP_UNIT };
  1339.  
  1340.     struct IFFHandle    *Handle;
  1341.     STRPTR             ResultBuffer = NULL;
  1342.  
  1343.     if(Handle = AllocIFF())
  1344.     {
  1345.         if(Args[ARG_GETCLIP_UNIT])
  1346.             Handle -> iff_Stream = (ULONG)OpenClipboard(*(LONG *)Args[ARG_GETCLIP_UNIT]);
  1347.         else
  1348.             Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit);
  1349.  
  1350.         if(Handle -> iff_Stream)
  1351.         {
  1352.             InitIFFasClip(Handle);
  1353.  
  1354.             if(!OpenIFF(Handle,IFFF_READ))
  1355.             {
  1356.                 if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  1357.                 {
  1358.                     if(!ParseIFF(Handle,IFFPARSE_SCAN))
  1359.                     {
  1360.                         struct ContextNode *ContextNode;
  1361.  
  1362.                         ContextNode = CurrentChunk(Handle);
  1363.  
  1364.                         if(ContextNode -> cn_Type == ID_FTXT && ContextNode -> cn_Size > 0)
  1365.                         {
  1366.                             STRPTR Result;
  1367.  
  1368.                             if(Result = (STRPTR)AllocVec(ContextNode -> cn_Size,MEMF_ANY))
  1369.                             {
  1370.                                 if(ReadChunkBytes(Handle,Result,ContextNode -> cn_Size) == ContextNode -> cn_Size)
  1371.                                     ResultBuffer = CreateArgstring(Result,ContextNode -> cn_Size);
  1372.  
  1373.                                 FreeVec(Result);
  1374.                             }
  1375.                             else
  1376.                             {
  1377.                                 Results[0] = RC_ERROR;
  1378.                                 Results[1] = ERROR_NO_FREE_STORE;
  1379.                             }
  1380.                         }
  1381.                         else
  1382.                             Results[0] = RC_WARN;
  1383.                     }
  1384.                     else
  1385.                     {
  1386.                         Results[0] = RC_ERROR;
  1387.                         Results[1] = ERROR_OBJECT_NOT_FOUND;
  1388.                     }
  1389.                 }
  1390.                 else
  1391.                 {
  1392.                     Results[0] = RC_ERROR;
  1393.                     Results[1] = ERROR_OBJECT_NOT_FOUND;
  1394.                 }
  1395.  
  1396.                 CloseIFF(Handle);
  1397.             }
  1398.             else
  1399.             {
  1400.                 Results[0] = RC_ERROR;
  1401.                 Results[1] = ERROR_OBJECT_NOT_FOUND;
  1402.             }
  1403.  
  1404.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  1405.         }
  1406.         else
  1407.         {
  1408.             Results[0] = RC_ERROR;
  1409.             Results[1] = TERMERROR_UNIT_NOT_AVAILABLE;
  1410.         }
  1411.  
  1412.         FreeIFF(Handle);
  1413.     }
  1414.     else
  1415.     {
  1416.         Results[0] = RC_ERROR;
  1417.         Results[1] = ERROR_OBJECT_NOT_FOUND;
  1418.     }
  1419.  
  1420.     return(ResultBuffer);
  1421. }
  1422.  
  1423. STRPTR __regargs
  1424. RexxHangup(struct RexxPkt *Pkt)
  1425. {
  1426.     BYTE OldStatus = Status;
  1427.  
  1428.     BlockWindows();
  1429.  
  1430.     Status = STATUS_HANGUP;
  1431.  
  1432.         /* Are we to drop the DTR line
  1433.          * before sending the hangup
  1434.          * string?
  1435.          */
  1436.  
  1437.     if(Config -> ModemConfig -> DropDTR)
  1438.     {
  1439.             /* Let's be nice and try to transmit the
  1440.              * `drop the line' command before
  1441.              * trying to close and reopen the driver.
  1442.              */
  1443.  
  1444.         WriteRequest -> IOSer . io_Command    = SIOCMD_SETCTRLLINES;
  1445.         WriteRequest -> IOSer . io_Offset    = SIOB_DTRF;
  1446.         WriteRequest -> IOSer . io_Length    = 0;
  1447.  
  1448.         /* Transmit the command. */
  1449.  
  1450.         if(!DoIO(WriteRequest))
  1451.         {
  1452.                 /* Wait a bit... */
  1453.  
  1454.             WaitTime(1,0);
  1455.  
  1456.                 /* Raise the line again. */
  1457.  
  1458.             WriteRequest -> IOSer . io_Command    = SIOCMD_SETCTRLLINES;
  1459.             WriteRequest -> IOSer . io_Offset    = SIOB_DTRF;
  1460.             WriteRequest -> IOSer . io_Length    = SIOB_DTRF;
  1461.  
  1462.             DoIO(WriteRequest);
  1463.         }
  1464.         else
  1465.         {
  1466.                 /* Do it the standard way: close and reopen
  1467.                  * the serial driver (the serial.device is
  1468.                  * supposed to drop the DTR line when closed).
  1469.                  */
  1470.  
  1471.             if(!DropDTR())
  1472.             {
  1473.                 if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_REOPEN_UNIT_TXT),LocaleString(MSG_TERMMAIN_IGNORE_QUIT_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber))
  1474.                     MainTerminated = TRUE;
  1475.             }
  1476.         }
  1477.     }
  1478.  
  1479.         /* Transmit the hangup command. */
  1480.  
  1481.     LocalRexxSerialCommand(Config -> ModemConfig -> ModemHangup,NULL);
  1482.  
  1483.         /* Reset to old status. */
  1484.  
  1485.     Status = OldStatus;
  1486.  
  1487.         /* We are no longer online. */
  1488.  
  1489.     Online = FALSE;
  1490.  
  1491.         /* Clear the password. */
  1492.  
  1493.     Password[0]        = 0;
  1494.     UserName[0]        = 0;
  1495.  
  1496.     CurrentBBSName[0]    = 0;
  1497.     CurrentBBSComment[0]    = 0;
  1498.     CurrentBBSNumber[0]    = 0;
  1499.  
  1500.         /* Note the  last action. */
  1501.  
  1502.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_TXT));
  1503.  
  1504.     ReleaseWindows();
  1505.  
  1506.         /* Execute logoff macro. */
  1507.  
  1508.     if(WasOnline)
  1509.         LocalRexxSerialCommand(Config -> CommandConfig -> LogoffMacro,NULL);
  1510.  
  1511.         /* Update the logfile. */
  1512.  
  1513.     StopCall(FALSE);
  1514.  
  1515.         /* Don't execute the logoff macro twice. */
  1516.  
  1517.     WasOnline = FALSE;
  1518.  
  1519.         /* Enable the dialing functions. */
  1520.  
  1521.     SetDialMenu(TRUE);
  1522.  
  1523.     Status = OldStatus;
  1524.  
  1525.     if(Config -> ModemConfig -> RedialAfterHangup)
  1526.     {
  1527.         if(DialList)
  1528.         {
  1529.             if(DialList -> lh_Head -> ln_Succ)
  1530.                 DoDial = DIAL_REDIAL;
  1531.         }
  1532.     }
  1533.  
  1534.     ChosenEntry = NULL;
  1535.  
  1536.     return(NULL);
  1537. }
  1538.  
  1539. STRPTR __regargs
  1540. RexxHelp(struct RexxPkt *Pkt)
  1541. {
  1542.     enum    {    ARG_HELP_COMMAND,ARG_HELP_PROMPT };
  1543.  
  1544.     if(Args[ARG_HELP_PROMPT])
  1545.         GuideSetup();
  1546.     else
  1547.     {
  1548.         WORD i;
  1549.  
  1550.         for(i = 0 ; i < CommandTableSize ; i++)
  1551.         {
  1552.             if(!Stricmp(Args[ARG_HELP_COMMAND],CommandTable[i] . Name))
  1553.             {
  1554.                 if(CommandTable[i] . Arguments)
  1555.                     return(CreateResult(CommandTable[i] . Arguments,Results));
  1556.                 else
  1557.                     return(CreateResult(",",Results));
  1558.             }
  1559.         }
  1560.  
  1561.         Results[0] = RC_ERROR;
  1562.         Results[1] = ERROR_OBJECT_NOT_FOUND;
  1563.     }
  1564.  
  1565.     return(NULL);
  1566. }
  1567.  
  1568. STRPTR __regargs
  1569. RexxOpen(struct RexxPkt *Pkt)
  1570. {
  1571.     enum    {    ARG_OPEN_NAME,ARG_OPEN_TO };
  1572.  
  1573.     WORD Index = ToConfig(Args[ARG_OPEN_TO]);
  1574.  
  1575.     if(Index == -1 || Index > DATATYPE_PHONEBOOK)
  1576.     {
  1577.         Results[0] = RC_ERROR;
  1578.         Results[1] = ERROR_OBJECT_NOT_FOUND;
  1579.     }
  1580.     else
  1581.     {
  1582.         UBYTE    DummyBuffer[MAX_FILENAME_LENGTH];
  1583.         STRPTR    FileName;
  1584.  
  1585.         if(Args[ARG_OPEN_NAME])
  1586.             FileName = Args[ARG_OPEN_NAME];
  1587.         else
  1588.         {
  1589.             STRPTR             Title;
  1590.             struct FileRequester    *FileRequest;
  1591.  
  1592.             FileName = NULL;
  1593.  
  1594.             switch(Index)
  1595.             {
  1596.                 case DATATYPE_TRANSLATIONS:
  1597.  
  1598.                     Title = LocaleString(MSG_PHONEPANEL_SELECT_TRANSLATION_TXT);
  1599.                     break;
  1600.  
  1601.                 case DATATYPE_FUNCTIONKEYS:
  1602.  
  1603.                     Title = LocaleString(MSG_PHONEPANEL_SELECT_KEYBOARD_MACROS_TXT);
  1604.                     break;
  1605.  
  1606.                 case DATATYPE_CURSORKEYS:
  1607.  
  1608.                     Title = LocaleString(MSG_PHONEPANEL_SELECT_CURSOR_KEYS_TXT);
  1609.                     break;
  1610.  
  1611.                 case DATATYPE_FASTMACROS:
  1612.  
  1613.                     Title = LocaleString(MSG_PHONEPANEL_SELECT_FAST_MACROS_TXT);
  1614.                     break;
  1615.  
  1616.                 case DATATYPE_HOTKEYS:
  1617.  
  1618.                     Title = LocaleString(MSG_HOTKEYPANEL_LOAD_HOTKEYS_TXT);
  1619.                     break;
  1620.  
  1621.                 case DATATYPE_SPEECH:
  1622.  
  1623.                     Title = LocaleString(MSG_SPEECHPANEL_LOAD_SPEECH_SETTINGS_TXT);
  1624.                     break;
  1625.  
  1626.                 case DATATYPE_BUFFER:
  1627.  
  1628.                     Title = LocaleString(MSG_TERMMAIN_LOAD_BUFFER_TXT);
  1629.                     break;
  1630.  
  1631.                 case DATATYPE_CONFIGURATION:
  1632.  
  1633.                     Title = LocaleString(MSG_TERMMAIN_OPEN_PREFERENCES_TXT);
  1634.                     break;
  1635.  
  1636.                 case DATATYPE_PHONEBOOK:
  1637.  
  1638.                     Title = LocaleString(MSG_PHONEPANEL_LOAD_PHONEBOOK_TXT);
  1639.                     break;
  1640.             }
  1641.  
  1642.             BlockWindows();
  1643.  
  1644.             if(FileRequest = GetFile(Title,"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,"Ok"))
  1645.             {
  1646.                 FileName = DummyBuffer;
  1647.  
  1648.                 FreeAslRequest(FileRequest);
  1649.             }
  1650.             else
  1651.                 Results[0] = RC_WARN;
  1652.  
  1653.             ReleaseWindows();
  1654.         }
  1655.  
  1656.         if(FileName)
  1657.         {
  1658.             if(!GetFileSize(FileName))
  1659.             {
  1660.                 Results[0] = RC_ERROR;
  1661.                 Results[1] = ERROR_OBJECT_NOT_FOUND;
  1662.  
  1663.                 return(NULL);
  1664.             }
  1665.  
  1666.             BlockWindows();
  1667.  
  1668.             switch(Index)
  1669.             {
  1670.                 case DATATYPE_TRANSLATIONS:
  1671.                 {
  1672.                     struct TranslationEntry    **Send,
  1673.                                 **Receive = NULL;
  1674.                     BYTE            Success = FALSE;
  1675.  
  1676.                     if(Send = AllocTranslationTable())
  1677.                     {
  1678.                         if(Receive = AllocTranslationTable())
  1679.                         {
  1680.                             if(!(Success = LoadTranslationTables(FileName,Send,Receive)))
  1681.                             {
  1682.                                 Results[0] = RC_ERROR;
  1683.                                 Results[1] = IoErr();
  1684.                             }
  1685.                         }
  1686.                         else
  1687.                         {
  1688.                             Results[0] = RC_ERROR;
  1689.                             Results[1] = ERROR_NO_FREE_STORE;
  1690.                         }
  1691.                     }
  1692.                     else
  1693.                     {
  1694.                         Results[0] = RC_ERROR;
  1695.                         Results[1] = ERROR_NO_FREE_STORE;
  1696.                     }
  1697.  
  1698.                     if(!Success)
  1699.                     {
  1700.                         if(Send)
  1701.                             FreeTranslationTable(Send);
  1702.  
  1703.                         if(Receive)
  1704.                             FreeTranslationTable(Receive);
  1705.                     }
  1706.                     else
  1707.                     {
  1708.                         strcpy(Config -> FileConfig -> TranslationFileName,FileName);
  1709.  
  1710.                         strcpy(LastTranslation,FileName);
  1711.  
  1712.                         FreeTranslationTable(SendTable);
  1713.                         FreeTranslationTable(ReceiveTable);
  1714.  
  1715.                         SendTable    = Send;
  1716.                         ReceiveTable    = Receive;
  1717.                     }
  1718.                 }
  1719.  
  1720.                 break;
  1721.  
  1722.                 case DATATYPE_FUNCTIONKEYS:
  1723.                 {
  1724.                     if(!LoadMacros(FileName,MacroKeys))
  1725.                     {
  1726.                         Results[0] = RC_ERROR;
  1727.                         Results[1] = IoErr();
  1728.                     }
  1729.                     else
  1730.                     {
  1731.                         MacroChanged = FALSE;
  1732.  
  1733.                         strcpy(Config -> FileConfig -> MacroFileName,FileName);
  1734.  
  1735.                         strcpy(LastMacros,FileName);
  1736.                     }
  1737.                 }
  1738.  
  1739.                 break;
  1740.  
  1741.                 case DATATYPE_CURSORKEYS:
  1742.                 {
  1743.                     if(!ReadIFFData(FileName,CursorKeys,sizeof(struct CursorKeys),ID_KEYS))
  1744.                     {
  1745.                         Results[0] = RC_ERROR;
  1746.                         Results[1] = IoErr();
  1747.                     }
  1748.                     else
  1749.                     {
  1750.                         CursorKeysChanged = FALSE;
  1751.  
  1752.                         strcpy(Config -> FileConfig -> CursorFileName,FileName);
  1753.  
  1754.                         strcpy(LastCursorKeys,FileName);
  1755.                     }
  1756.                 }
  1757.  
  1758.                 break;
  1759.  
  1760.                 case DATATYPE_FASTMACROS:
  1761.                 {
  1762.                     if(FastWindow)
  1763.                     {
  1764.                         GT_SetGadgetAttrs(FastGadget,FastWindow,NULL,
  1765.                             GTLV_Labels,    ~0,
  1766.                         TAG_DONE);
  1767.                     }
  1768.  
  1769.                     if(!LoadFastMacros(FileName))
  1770.                     {
  1771.                         Results[0] = RC_ERROR;
  1772.                         Results[1] = IoErr();
  1773.                     }
  1774.                     else
  1775.                     {
  1776.                         strcpy(Config -> FileConfig -> FastMacroFileName,FileName);
  1777.  
  1778.                         strcpy(LastFastMacros,FileName);
  1779.  
  1780.                         FastMacrosChanged = FALSE;
  1781.                     }
  1782.  
  1783.                     if(FastWindow)
  1784.                     {
  1785.                         GT_SetGadgetAttrs(FastGadget,FastWindow,NULL,
  1786.                             GTLV_Labels,    &FastMacroList,
  1787.                         TAG_DONE);
  1788.                     }
  1789.                 }
  1790.  
  1791.                 break;
  1792.  
  1793.                 case DATATYPE_HOTKEYS:
  1794.                 {
  1795.                     if(!LoadHotkeys(FileName,&Hotkeys))
  1796.                     {
  1797.                         Results[0] = RC_ERROR;
  1798.                         Results[1] = IoErr();
  1799.                     }
  1800.                     else
  1801.                     {
  1802.                         strcpy(LastKeys,FileName);
  1803.  
  1804.                         HotkeysChanged = FALSE;
  1805.  
  1806.                         SetupCx();
  1807.                     }
  1808.                 }
  1809.  
  1810.                 break;
  1811.  
  1812.                 case DATATYPE_SPEECH:
  1813.                 {
  1814.                     if(!ReadIFFData(FileName,&SpeechConfig,sizeof(struct SpeechConfig),ID_SPEK))
  1815.                     {
  1816.                         Results[0] = RC_ERROR;
  1817.                         Results[1] = IoErr();
  1818.                     }
  1819.                     else
  1820.                     {
  1821.                         strcpy(LastSpeech,FileName);
  1822.  
  1823.                         SpeechSetup();
  1824.  
  1825.                         SpeechChanged = FALSE;
  1826.                     }
  1827.                 }
  1828.  
  1829.                 break;
  1830.  
  1831.                 case DATATYPE_BUFFER:
  1832.                 {
  1833.                     BPTR SomeFile;
  1834.  
  1835.                     if(SomeFile = Open(FileName,MODE_OLDFILE))
  1836.                     {
  1837.                         LONG Len;
  1838.  
  1839.                         LineRead(NULL,NULL,NULL);
  1840.  
  1841.                         while((Len = LineRead(SomeFile,FileName,80)) > 0)
  1842.                             StoreBuffer(FileName,Len);
  1843.  
  1844.                         Close(SomeFile);
  1845.  
  1846.                         BufferChanged = TRUE;
  1847.                     }
  1848.                     else
  1849.                     {
  1850.                         Results[0] = RC_ERROR;
  1851.                         Results[1] = IoErr();
  1852.                     }
  1853.                 }
  1854.  
  1855.                 break;
  1856.  
  1857.                 case DATATYPE_CONFIGURATION:
  1858.                 {
  1859.                     if(ReadConfig(FileName,PrivateConfig))
  1860.                     {
  1861.                         SwapConfig(PrivateConfig,Config);
  1862.  
  1863.                         strcpy(FileName,LastConfig);
  1864.  
  1865.                         ConfigSetup();
  1866.  
  1867.                         ConfigChanged = FALSE;
  1868.                     }
  1869.                     else
  1870.                     {
  1871.                         Results[0] = RC_ERROR;
  1872.                         Results[1] = IoErr();
  1873.                     }
  1874.                 }
  1875.  
  1876.                 break;
  1877.  
  1878.                 case DATATYPE_PHONEBOOK:
  1879.                 {
  1880.                     if(ChosenEntry)
  1881.                     {
  1882.                         Results[0] = RC_ERROR;
  1883.                         Results[1] = ERROR_OBJECT_IN_USE;
  1884.                     }
  1885.                     else
  1886.                     {
  1887.                         if(!LoadPhonebook(FileName))
  1888.                         {
  1889.                             Results[0] = RC_ERROR;
  1890.                             Results[1] = IoErr();
  1891.                         }
  1892.                         else
  1893.                         {
  1894.                             strcpy(LastPhone,FileName);
  1895.  
  1896.                             PhonebookChanged = FALSE;
  1897.                         }
  1898.                     }
  1899.                 }
  1900.  
  1901.                 break;
  1902.             }
  1903.  
  1904.             ReleaseWindows();
  1905.         }
  1906.         else
  1907.             Results[0] = RC_WARN;
  1908.     }
  1909.  
  1910.     return(NULL);
  1911. }
  1912.  
  1913. STRPTR __regargs
  1914. RexxOpenDevice(struct RexxPkt *Pkt)
  1915. {
  1916.     enum    {    ARG_OPENDEVICE_NAME,ARG_OPENDEVICE_UNIT };
  1917.  
  1918.     if(ReadRequest)
  1919.     {
  1920.         Results[0] = RC_ERROR;
  1921.         Results[1] = TERMERROR_DEVICE_DRIVER_STILL_OPEN;
  1922.     }
  1923.     else
  1924.     {
  1925.         if(Args[ARG_OPENDEVICE_NAME])
  1926.         {
  1927.             strcpy(Config -> SerialConfig -> SerialDevice,Args[ARG_OPENDEVICE_NAME]);
  1928.  
  1929.             ConfigChanged = TRUE;
  1930.         }
  1931.  
  1932.         if(Args[ARG_OPENDEVICE_UNIT])
  1933.         {
  1934.             Config -> SerialConfig -> UnitNumber = *(LONG *)Args[ARG_OPENDEVICE_UNIT];
  1935.  
  1936.             ConfigChanged = TRUE;
  1937.         }
  1938.  
  1939.         BlockWindows();
  1940.  
  1941.         ReopenSerial();
  1942.  
  1943.         ReleaseWindows();
  1944.     }
  1945.  
  1946.     return(NULL);
  1947. }
  1948.  
  1949. STRPTR __regargs
  1950. RexxOpenRequester(struct RexxPkt *Pkt)
  1951. {
  1952.     enum    {    ARG_OPENREQUESTER_REQUESTER };
  1953.  
  1954.     WORD Index;
  1955.  
  1956.     if((Index = ToRequester(Args[ARG_OPENREQUESTER_REQUESTER])) == -1)
  1957.     {
  1958.         Results[0] = RC_ERROR;
  1959.         Results[1] = ERROR_OBJECT_NOT_FOUND;
  1960.     }
  1961.     else
  1962.     {
  1963.         ULONG    Code;
  1964.         WORD    i;
  1965.  
  1966.         switch(Index)
  1967.         {
  1968.             case REQUESTER_SERIAL:
  1969.  
  1970.                 Code = MEN_SERIAL;
  1971.                 break;
  1972.  
  1973.             case REQUESTER_MODEM:
  1974.  
  1975.                 Code = MEN_MODEM;
  1976.                 break;
  1977.  
  1978.             case REQUESTER_SCREEN:
  1979.  
  1980.                 Code = MEN_SCREEN;
  1981.                 break;
  1982.  
  1983.             case REQUESTER_TERMINAL:
  1984.  
  1985.                 Code = MEN_TERMINAL;
  1986.                 break;
  1987.  
  1988.             case REQUESTER_EMULATION:
  1989.  
  1990.                 Code = MEN_SET_EMULATION;
  1991.                 break;
  1992.  
  1993.             case REQUESTER_CLIPBOARD:
  1994.  
  1995.                 Code = MEN_CLIPBOARD;
  1996.                 break;
  1997.  
  1998.             case REQUESTER_CAPTURE:
  1999.  
  2000.                 Code = MEN_CAPTURE;
  2001.                 break;
  2002.  
  2003.             case REQUESTER_COMMANDS:
  2004.  
  2005.                 Code = MEN_COMMANDS;
  2006.                 break;
  2007.  
  2008.             case REQUESTER_MISC:
  2009.  
  2010.                 Code = MEN_MISC;
  2011.                 break;
  2012.  
  2013.             case REQUESTER_PATH:
  2014.  
  2015.                 Code = MEN_PATH;
  2016.                 break;
  2017.  
  2018.             case REQUESTER_TRANSFER:
  2019.  
  2020.                 Code = MEN_TRANSFER;
  2021.                 break;
  2022.  
  2023.             case REQUESTER_TRANSLATIONS:
  2024.  
  2025.                 Code = MEN_TRANSLATION;
  2026.                 break;
  2027.  
  2028.             case REQUESTER_FUNCTIONKEYS:
  2029.  
  2030.                 Code = MEN_MACROS;
  2031.                 break;
  2032.  
  2033.             case REQUESTER_CURSORKEYS:
  2034.  
  2035.                 Code = MEN_CURSORKEYS;
  2036.                 break;
  2037.  
  2038.             case REQUESTER_FASTMACROS:
  2039.  
  2040.                 Code = MEN_FAST_MACROS;
  2041.                 break;
  2042.  
  2043.             case REQUESTER_HOTKEYS:
  2044.  
  2045.                 Code = MEN_HOTKEYS;
  2046.                 break;
  2047.  
  2048.             case REQUESTER_SPEECH:
  2049.  
  2050.                 Code = MEN_SPEECH;
  2051.                 break;
  2052.  
  2053.  
  2054.             case REQUESTER_PHONE:
  2055.  
  2056.                 Code = MEN_PHONEBOOK;
  2057.                 break;
  2058.         }
  2059.  
  2060.             /* Scan the menu list... */
  2061.  
  2062.         for(i = 0 ; TermMenu[i] . nm_Type != NM_END ; i++)
  2063.         {
  2064.                 /* Did we get a valid name string? */
  2065.  
  2066.             if(TermMenu[i] . nm_Label != NM_BARLABEL)
  2067.             {
  2068.                 if((ULONG)TermMenu[i] . nm_UserData == Code)
  2069.                 {
  2070.                     HandleMenuCode((ULONG)TermMenu[i] . nm_UserData,NULL);
  2071.  
  2072.                     break;
  2073.                 }
  2074.             }
  2075.         }
  2076.     }
  2077.  
  2078.     return(NULL);
  2079. }
  2080.  
  2081. STRPTR __regargs
  2082. RexxParity(struct RexxPkt *Pkt)
  2083. {
  2084.     enum    {    ARG_PARITY_EVEN,ARG_PARITY_ODD,ARG_PARITY_NONE,ARG_PARITY_MARK,ARG_PARITY_SPACE };
  2085.  
  2086.     BYTE Mode;
  2087.  
  2088.     if(Args[ARG_PARITY_EVEN])
  2089.         Mode = PARITY_EVEN;
  2090.  
  2091.     if(Args[ARG_PARITY_ODD])
  2092.         Mode = PARITY_ODD;
  2093.  
  2094.     if(Args[ARG_PARITY_NONE])
  2095.         Mode = PARITY_NONE;
  2096.  
  2097.     if(Args[ARG_PARITY_MARK])
  2098.         Mode = PARITY_MARK;
  2099.  
  2100.     if(Args[ARG_PARITY_SPACE])
  2101.         Mode = PARITY_SPACE;
  2102.  
  2103.     if(Config -> SerialConfig -> Parity != Mode)
  2104.     {
  2105.         Config -> SerialConfig -> Parity = Mode;
  2106.  
  2107.         UpdateRequired = TRUE;
  2108.  
  2109.         ConfigChanged = TRUE;
  2110.     }
  2111.  
  2112.     return(NULL);
  2113. }
  2114.  
  2115. STRPTR __regargs
  2116. RexxPasteClip(struct RexxPkt *Pkt)
  2117. {
  2118.     enum    {    ARG_PASTECLIP_UNIT };
  2119.  
  2120.     LONG Unit;
  2121.  
  2122.     if(Args[ARG_PASTECLIP_UNIT])
  2123.         Unit = *(LONG *)Args[ARG_PASTECLIP_UNIT];
  2124.     else
  2125.         Unit = Config -> ClipConfig -> ClipboardUnit;
  2126.  
  2127.     if(!OpenClip(Unit))
  2128.         ClipInput = TRUE;
  2129.     else
  2130.         ClipInput = FALSE;
  2131.  
  2132.     return(NULL);
  2133. }
  2134.  
  2135. STRPTR __regargs
  2136. RexxPrint(struct RexxPkt *Pkt)
  2137. {
  2138.     enum    {    ARG_PRINT_FROM,ARG_PRINT_TO,ARG_PRINT_SERIAL,ARG_PRINT_MODEM,ARG_PRINT_SCREEN,
  2139.             ARG_PRINT_TERMINAL,ARG_PRINT_USER,ARG_PRINT_COMMENT,ARG_PRINT_SIZE,
  2140.             ARG_PRINT_DATE,ARG_PRINT_BITS };
  2141.  
  2142.     WORD    Index,Mode = -1;
  2143.     ULONG    Flags = NULL;
  2144.  
  2145.     if(Args[ARG_PRINT_SERIAL])
  2146.         Flags |= PRINT_SERIAL;
  2147.  
  2148.     if(Args[ARG_PRINT_MODEM])
  2149.         Flags |= PRINT_MODEM;
  2150.  
  2151.     if(Args[ARG_PRINT_SCREEN])
  2152.         Flags |= PRINT_SCREEN;
  2153.  
  2154.     if(Args[ARG_PRINT_TERMINAL])
  2155.         Flags |= PRINT_TERMINAL;
  2156.  
  2157.     if(Args[ARG_PRINT_USER])
  2158.         Flags |= PRINT_USERNAME;
  2159.  
  2160.     if(Args[ARG_PRINT_COMMENT])
  2161.         Flags |= PRINT_COMMENT;
  2162.  
  2163.     if(Args[ARG_PRINT_SIZE])
  2164.         Flags |= PRINT_SIZE;
  2165.  
  2166.     if(Args[ARG_PRINT_DATE])
  2167.         Flags |= PRINT_DATE;
  2168.  
  2169.     if(Args[ARG_PRINT_BITS])
  2170.         Flags |= PRINT_BITS;
  2171.  
  2172.     if((Index = ToList(Args[ARG_PRINT_FROM])) == -1)
  2173.     {
  2174.         if(!Stricmp(Args[ARG_PRINT_FROM],"SCREENTEXT"))
  2175.         {
  2176.             if(!RasterEnabled)
  2177.             {
  2178.                 Results[0] = RC_ERROR;
  2179.                 Results[1] = TERMERROR_NO_DATA_TO_PROCESS;
  2180.  
  2181.                 return(NULL);
  2182.             }
  2183.             else
  2184.                 Mode = 0;
  2185.         }
  2186.  
  2187.         if(!Stricmp(Args[ARG_PRINT_FROM],"CLIPBOARD"))
  2188.             Mode = 1;
  2189.  
  2190.         if(!Stricmp(Args[ARG_PRINT_FROM],"BUFFER"))
  2191.             Mode = 2;
  2192.     }
  2193.  
  2194.     if(Index == -1 && Mode == -1)
  2195.     {
  2196.         Results[0] = RC_ERROR;
  2197.         Results[1] = TERMERROR_UNKNOWN_LIST;
  2198.     }
  2199.     else
  2200.     {
  2201.         BYTE    Continue = TRUE;
  2202.         LONG    Error = 0;
  2203.         BPTR    File;
  2204.         STRPTR    Name;
  2205.  
  2206.         if(Args[ARG_PRINT_TO])
  2207.             Name = Args[ARG_PRINT_TO];
  2208.         else
  2209.             Name = "PRT:";
  2210.  
  2211.         if(File = Open(Name,MODE_NEWFILE))
  2212.         {
  2213.             struct Window        *ReqWindow;
  2214.             struct EasyStruct     Easy;
  2215.  
  2216.             Easy . es_StructSize    = sizeof(struct EasyStruct);
  2217.             Easy . es_Flags        = NULL;
  2218.             Easy . es_Title        = (UBYTE *)LocaleString(MSG_TERMAUX_TERM_REQUEST_TXT);
  2219.             Easy . es_GadgetFormat    = (UBYTE *)LocaleString(MSG_PRINT_STOP_TXT);
  2220.             Easy . es_TextFormat    = (UBYTE *)LocaleString(MSG_GLOBAL_PRINTING_TXT);
  2221.  
  2222.             BlockWindows();
  2223.  
  2224.             if(ReqWindow = BuildEasyRequest(Window,&Easy,NULL))
  2225.             {
  2226.                 switch(Index)
  2227.                 {
  2228.                     case GLIST_DIAL:
  2229.                     {
  2230.                         struct GenericList *List = GenericListTable[Index];
  2231.  
  2232.                         ObtainSemaphore(&List -> ListSemaphore);
  2233.  
  2234.                         if(List -> ListHeader . mlh_Head -> mln_Succ)
  2235.                         {
  2236.                             struct DialNode *TempNode;
  2237.  
  2238.                             for(TempNode = (struct DialNode *)List -> ListHeader . mlh_Head ; Continue && TempNode -> Node . ln_Succ ; TempNode = (struct DialNode *)TempNode -> Node . ln_Succ)
  2239.                             {
  2240.                                 if(TempNode -> Entry)
  2241.                                     Continue = PrintEntry(File,ReqWindow,TRUE,&Error,TempNode -> Entry,Flags);
  2242.                                 else
  2243.                                     Continue = PrintText(File,ReqWindow,&Error,"\n\"???\" (%s)",TempNode -> Node . ln_Name);
  2244.                             }
  2245.                         }
  2246.  
  2247.                         ReleaseSemaphore(&List -> ListSemaphore);
  2248.                     }
  2249.  
  2250.                     break;
  2251.  
  2252.                     case GLIST_UPLOAD:
  2253.                     case GLIST_DOWNLOAD:
  2254.                     {
  2255.                         struct GenericList *List = GenericListTable[Index];
  2256.  
  2257.                         ObtainSemaphore(&List -> ListSemaphore);
  2258.  
  2259.                         if(List -> ListHeader . mlh_Head -> mln_Succ)
  2260.                         {
  2261.                             struct Node *TempNode;
  2262.  
  2263.                             for(TempNode = (struct Node *)List -> ListHeader . mlh_Head ; Continue && TempNode -> ln_Succ ; TempNode = TempNode -> ln_Succ)
  2264.                                 Continue = PrintFileInformation(File,ReqWindow,&Error,TempNode -> ln_Name,Flags);
  2265.                         }
  2266.  
  2267.                         ReleaseSemaphore(&List -> ListSemaphore);
  2268.                     }
  2269.  
  2270.                     break;
  2271.  
  2272.                     case GLIST_WAIT:
  2273.                     {
  2274.                         struct GenericList *List = GenericListTable[Index];
  2275.  
  2276.                         ObtainSemaphore(&List -> ListSemaphore);
  2277.  
  2278.                         if(List -> ListHeader . mlh_Head -> mln_Succ)
  2279.                         {
  2280.                             struct Node *TempNode;
  2281.  
  2282.                             for(TempNode = (struct Node *)List -> ListHeader . mlh_Head ; Continue && TempNode -> ln_Succ ; TempNode = TempNode -> ln_Succ)
  2283.                                 Continue = PrintText(File,ReqWindow,&Error,"%s\n",TempNode -> ln_Name);
  2284.                         }
  2285.  
  2286.                         ReleaseSemaphore(&List -> ListSemaphore);
  2287.                     }
  2288.  
  2289.                     break;
  2290.  
  2291.                     default:
  2292.                     {
  2293.                         switch(Mode)
  2294.                         {
  2295.                             case 0:
  2296.  
  2297.                                 Continue = PrintScreen(File,ReqWindow,&Error);
  2298.                                 break;
  2299.  
  2300.                             case 1:
  2301.  
  2302.                                 Continue = PrintClip(File,ReqWindow,&Error);
  2303.                                 break;
  2304.  
  2305.                             case 2:
  2306.  
  2307.                                 Continue = PrintBuffer(File,ReqWindow,&Error);
  2308.                                 break;
  2309.                         }
  2310.  
  2311.                         break;
  2312.                     }
  2313.  
  2314.                     break;
  2315.                 }
  2316.  
  2317.                 FreeSysRequest(ReqWindow);
  2318.             }
  2319.  
  2320.             ReleaseWindows();
  2321.  
  2322.             Close(File);
  2323.         }
  2324.         else
  2325.             Error = IoErr();
  2326.  
  2327.         if(Error)
  2328.         {
  2329.             Results[0] = RC_ERROR;
  2330.             Results[1] = Error;
  2331.         }
  2332.         else
  2333.         {
  2334.             if(!Continue)
  2335.                 Results[0] = RC_WARN;
  2336.         }
  2337.     }
  2338.  
  2339.     return(NULL);
  2340. }
  2341.  
  2342. STRPTR __regargs
  2343. RexxProtocol(struct RexxPkt *Pkt)
  2344. {
  2345.     enum    {    ARG_PROTOCOL_NONE,ARG_PROTOCOL_RTSCTS,ARG_PROTOCOL_RTSCTSDTR };
  2346.  
  2347.     BYTE Mode;
  2348.  
  2349.     if(Args[ARG_PROTOCOL_NONE])
  2350.         Mode = HANDSHAKING_NONE;
  2351.  
  2352.     if(Args[ARG_PROTOCOL_RTSCTS])
  2353.         Mode = HANDSHAKING_RTSCTS;
  2354.  
  2355.     if(Args[ARG_PROTOCOL_RTSCTSDTR])
  2356.         Mode = HANDSHAKING_RTSCTS_DSR;
  2357.  
  2358.     if(Config -> SerialConfig -> HandshakingProtocol != Mode)
  2359.     {
  2360.         Config -> SerialConfig -> HandshakingProtocol = Mode;
  2361.  
  2362.         UpdateRequired = TRUE;
  2363.  
  2364.         ConfigChanged = TRUE;
  2365.     }
  2366.  
  2367.     return(NULL);
  2368. }
  2369.  
  2370. STRPTR __regargs
  2371. RexxPutClip(struct RexxPkt *Pkt)
  2372. {
  2373.     enum    {    ARG_PUTCLIP_UNIT,ARG_PUTCLIP_TEXT };
  2374.  
  2375.     struct IFFHandle    *Handle;
  2376.     LONG             Unit;
  2377.     BYTE             Success = FALSE;
  2378.  
  2379.     if(Args[ARG_PUTCLIP_UNIT])
  2380.         Unit = *(LONG *)Args[ARG_PUTCLIP_UNIT];
  2381.     else
  2382.         Unit = Config -> ClipConfig -> ClipboardUnit;
  2383.  
  2384.     if(Handle = AllocIFF())
  2385.     {
  2386.         if(Handle -> iff_Stream = (ULONG)OpenClipboard(Unit))
  2387.         {
  2388.             InitIFFasClip(Handle);
  2389.  
  2390.             if(!OpenIFF(Handle,IFFF_WRITE))
  2391.             {
  2392.                 if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  2393.                 {
  2394.                     if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
  2395.                     {
  2396.                         LONG Len = strlen(Args[ARG_PUTCLIP_TEXT]);
  2397.  
  2398.                         if(WriteChunkBytes(Handle,Args[ARG_PUTCLIP_TEXT],Len) == Len)
  2399.                         {
  2400.                             if(!PopChunk(Handle))
  2401.                                 Success = TRUE;
  2402.                         }
  2403.                     }
  2404.                 }
  2405.  
  2406.                 if(PopChunk(Handle))
  2407.                     Success = FALSE;
  2408.  
  2409.                 CloseIFF(Handle);
  2410.             }
  2411.             else
  2412.             {
  2413.                 Results[0] = RC_ERROR;
  2414.                 Results[1] = ERROR_NO_FREE_STORE;
  2415.             }
  2416.  
  2417.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  2418.         }
  2419.         else
  2420.         {
  2421.             Results[0] = RC_ERROR;
  2422.             Results[1] = TERMERROR_UNIT_NOT_AVAILABLE;
  2423.         }
  2424.  
  2425.         FreeIFF(Handle);
  2426.     }
  2427.     else
  2428.     {
  2429.         Results[0] = RC_ERROR;
  2430.         Results[1] = ERROR_NO_FREE_STORE;
  2431.     }
  2432.  
  2433.     if(!Success && !Results[0])
  2434.     {
  2435.         Results[0] = RC_ERROR;
  2436.         Results[1] = TERMERROR_CLIPBOARD_ERROR;
  2437.     }
  2438.  
  2439.     return(NULL);
  2440. }
  2441.  
  2442. STRPTR __regargs
  2443. RexxQuit(struct RexxPkt *Pkt)
  2444. {
  2445.     enum    {    ARG_QUIT_FORCE };
  2446.  
  2447.     if(Args[ARG_QUIT_FORCE])
  2448.         MainTerminated = TRUE;
  2449.     else
  2450.         HandleMenuCode(MEN_QUIT,NULL);
  2451.  
  2452.     return(NULL);
  2453. }
  2454.  
  2455. STRPTR __regargs
  2456. RexxRead(struct RexxPkt *Pkt)
  2457. {
  2458.     enum    {    ARG_READ_NUM,ARG_READ_CR,ARG_READ_NOECHO,ARG_READ_PROMPT };
  2459.  
  2460.     LONG Len,BytesRead = 0;
  2461.  
  2462.     if(Args[ARG_READ_NUM])
  2463.     {
  2464.         Len = *(LONG *)Args[ARG_READ_NUM] + 1;
  2465.  
  2466.         if(Len < 1)
  2467.         {
  2468.             Results[0] = RC_ERROR;
  2469.             Results[1] = ERROR_BAD_NUMBER;
  2470.  
  2471.             return(NULL);
  2472.         }
  2473.  
  2474.         if(Len > MAX_RESULT_LEN + 1)
  2475.             Len = MAX_RESULT_LEN + 1;
  2476.     }
  2477.     else
  2478.         Len = MAX_RESULT_LEN + 1;
  2479.  
  2480.     if(Args[ARG_READ_PROMPT])
  2481.         LocalRexxSerialCommand(Args[ARG_READ_PROMPT],NULL);
  2482.  
  2483.     BlockWindows();
  2484.  
  2485.     Status = STATUS_READY;
  2486.  
  2487.     if(Args[ARG_READ_NUM])
  2488.     {
  2489.         STRPTR Buffer;
  2490.  
  2491.         if(Buffer = (STRPTR)AllocVec(Len,MEMF_ANY))
  2492.         {
  2493.             ULONG    Signals,SignalMask = SIG_SERIAL | SIG_TIMER | SIG_BREAK;
  2494.             STRPTR    Result;
  2495.  
  2496.             ClearSerial();
  2497.  
  2498.             ReadRequest -> IOSer . io_Command    = CMD_READ;
  2499.             ReadRequest -> IOSer . io_Data        = Buffer;
  2500.             ReadRequest -> IOSer . io_Length    = Len - 1;
  2501.  
  2502.             SetSignal(0,SignalMask);
  2503.  
  2504.             if(RexxTimeoutVal)
  2505.             {
  2506.                 TimeRequest -> tr_node . io_Command    = TR_ADDREQUEST;
  2507.                 TimeRequest -> tr_time . tv_secs    = RexxTimeoutVal;
  2508.                 TimeRequest -> tr_time . tv_micro    = 0;
  2509.  
  2510.                 BeginIO(TimeRequest);
  2511.             }
  2512.  
  2513.             BeginIO(ReadRequest);
  2514.  
  2515.             FOREVER
  2516.             {
  2517.                 Signals = Wait(SignalMask);
  2518.  
  2519.                 if(Signals & SIG_BREAK)
  2520.                 {
  2521.                     if(!CheckIO(ReadRequest))
  2522.                         AbortIO(ReadRequest);
  2523.  
  2524.                     WaitIO(ReadRequest);
  2525.  
  2526.                     if(RexxTimeoutVal)
  2527.                     {
  2528.                         if(!CheckIO(TimeRequest))
  2529.                             AbortIO(TimeRequest);
  2530.  
  2531.                         WaitIO(TimeRequest);
  2532.                     }
  2533.  
  2534.                     Results[0] = RC_WARN;
  2535.  
  2536.                     break;
  2537.                 }
  2538.  
  2539.                 if(Signals & SIG_SERIAL)
  2540.                 {
  2541.                     if(RexxTimeoutVal)
  2542.                     {
  2543.                         if(!CheckIO(TimeRequest))
  2544.                             AbortIO(TimeRequest);
  2545.  
  2546.                         WaitIO(TimeRequest);
  2547.                     }
  2548.  
  2549.                         /* Did the request terminate gracefully? */
  2550.  
  2551.                     if(!WaitIO(ReadRequest))
  2552.                     {
  2553.                         BytesIn += ReadRequest -> IOSer . io_Actual;
  2554.  
  2555.                         BytesRead = ReadRequest -> IOSer . io_Actual;
  2556.                     }
  2557.                     else
  2558.                         Results[0] = RC_ERROR;
  2559.  
  2560.                     break;
  2561.                 }
  2562.  
  2563.                 if(Signals & SIG_TIMER)
  2564.                 {
  2565.                     if(!CheckIO(ReadRequest))
  2566.                         AbortIO(ReadRequest);
  2567.  
  2568.                     WaitIO(ReadRequest);
  2569.  
  2570.                     WaitIO(TimeRequest);
  2571.  
  2572.                     if(ReadRequest -> IOSer . io_Actual)
  2573.                     {
  2574.                         BytesIn += ReadRequest -> IOSer . io_Actual;
  2575.  
  2576.                         BytesRead = ReadRequest -> IOSer . io_Actual;
  2577.                     }
  2578.                     else
  2579.                     {
  2580.                         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  2581.  
  2582.                         DoIO(WriteRequest);
  2583.  
  2584.                         if(WriteRequest -> IOSer . io_Actual)
  2585.                         {
  2586.                                 /* Don't read more than actually wanted. */
  2587.  
  2588.                             ReadRequest -> IOSer . io_Command    = CMD_READ;
  2589.                             ReadRequest -> IOSer . io_Data        = Buffer;
  2590.                             ReadRequest -> IOSer . io_Length    = MIN(Len - 1,WriteRequest -> IOSer . io_Actual);
  2591.  
  2592.                             if(!DoIO(ReadRequest))
  2593.                             {
  2594.                                 BytesIn += ReadRequest -> IOSer . io_Actual;
  2595.  
  2596.                                 BytesRead = ReadRequest -> IOSer . io_Actual;
  2597.                             }
  2598.                         }
  2599.                     }
  2600.  
  2601.                     break;
  2602.                 }
  2603.             }
  2604.  
  2605.             if(BytesRead)
  2606.             {
  2607.                 Buffer[BytesRead] = 0;
  2608.  
  2609.                 Result = CreateResult(Buffer,Results);
  2610.             }
  2611.             else
  2612.             {
  2613.                 Results[0] = RC_WARN;
  2614.  
  2615.                 Result = NULL;
  2616.             }
  2617.  
  2618.             FreeVec(Buffer);
  2619.  
  2620.             ReadRequest -> IOSer . io_Command    = CMD_READ;
  2621.             ReadRequest -> IOSer . io_Data        = ReadBuffer;
  2622.             ReadRequest -> IOSer . io_Length    = 1;
  2623.  
  2624.             SetSignal(0,SIG_SERIAL);
  2625.  
  2626.             BeginIO(ReadRequest);
  2627.  
  2628.             ReleaseWindows();
  2629.  
  2630.             return(Result);
  2631.         }
  2632.         else
  2633.         {
  2634.             Results[0] = RC_ERROR;
  2635.             Results[1] = ERROR_NO_FREE_STORE;
  2636.         }
  2637.  
  2638.         ReadRequest -> IOSer . io_Command    = CMD_READ;
  2639.         ReadRequest -> IOSer . io_Data        = ReadBuffer;
  2640.         ReadRequest -> IOSer . io_Length    = 1;
  2641.  
  2642.         SetSignal(0,SIG_SERIAL);
  2643.  
  2644.         BeginIO(ReadRequest);
  2645.     }
  2646.     else
  2647.     {
  2648.         ULONG     Signals,SignalMask = SIG_SERIAL | SIG_TIMER | SIG_BREAK;
  2649.         UBYTE    *Char = ReadBuffer;
  2650.         BYTE     Echo,Done = FALSE;
  2651.         LONG     Index = 0;
  2652.  
  2653.         if(Args[ARG_READ_NOECHO])
  2654.             Echo = FALSE;
  2655.         else
  2656.             Echo = TRUE;
  2657.  
  2658.         if(RexxTimeoutVal)
  2659.         {
  2660.             TimeRequest -> tr_node . io_Command    = TR_ADDREQUEST;
  2661.             TimeRequest -> tr_time . tv_secs    = RexxTimeoutVal;
  2662.             TimeRequest -> tr_time . tv_micro    = 0;
  2663.  
  2664.             SetSignal(0,SIG_TIMER);
  2665.  
  2666.             BeginIO(TimeRequest);
  2667.         }
  2668.  
  2669.         do
  2670.         {
  2671.             Signals = Wait(SignalMask);
  2672.  
  2673.             if(Signals & (SIG_BREAK | SIG_TIMER))
  2674.             {
  2675.                 if(!CheckIO(ReadRequest))
  2676.                     AbortIO(ReadRequest);
  2677.  
  2678.                 WaitIO(ReadRequest);
  2679.  
  2680.                 ReadRequest -> IOSer . io_Command    = CMD_READ;
  2681.                 ReadRequest -> IOSer . io_Data        = ReadBuffer;
  2682.                 ReadRequest -> IOSer . io_Length     = 1;
  2683.  
  2684.                 SetSignal(0,SIG_SERIAL);
  2685.  
  2686.                 BeginIO(ReadRequest);
  2687.  
  2688.                 Results[0] = RC_WARN;
  2689.  
  2690.                 break;
  2691.             }
  2692.  
  2693.             if(Signals & SIG_SERIAL)
  2694.             {
  2695.                 if(!WaitIO(ReadRequest))
  2696.                 {
  2697.                     BytesIn++;
  2698.  
  2699.                     switch(*Char)
  2700.                     {
  2701.                         case '\n':
  2702.                         case '\r':
  2703.  
  2704.                             Done = TRUE;
  2705.  
  2706.                             if(Echo)
  2707.                                 SerWrite(ReadBuffer,1);
  2708.  
  2709.                             break;
  2710.  
  2711.                         case '\b':
  2712.  
  2713.                             if(Index > 0)
  2714.                             {
  2715.                                 Index--;
  2716.  
  2717.                                 if(Echo)
  2718.                                     SerWrite(ReadBuffer,1);
  2719.                             }
  2720.  
  2721.                             break;
  2722.  
  2723.                         case '\30':
  2724.  
  2725.                             if(Echo)
  2726.                             {
  2727.                                 while(Index > 0)
  2728.                                 {
  2729.                                     Index--;
  2730.  
  2731.                                     SerWrite("\b",1);
  2732.                                 }
  2733.                             }
  2734.                             else
  2735.                                 Index = 0;
  2736.  
  2737.                         default:
  2738.  
  2739.                             if(Index < 255 && ((*Char >= ' ' && *Char < 127) || *Char >= 160 || Config -> TerminalConfig -> FontMode == FONT_IBM))
  2740.                             {
  2741.                                 SharedBuffer[Index++] = *Char;
  2742.  
  2743.                                 if(Echo)
  2744.                                     SerWrite(ReadBuffer,1);
  2745.                             }
  2746.  
  2747.                             break;
  2748.                     }
  2749.                 }
  2750.  
  2751.                 ReadRequest -> IOSer . io_Command    = CMD_READ;
  2752.                 ReadRequest -> IOSer . io_Data        = ReadBuffer;
  2753.                 ReadRequest -> IOSer . io_Length     = 1;
  2754.  
  2755.                 SetSignal(0,SIG_SERIAL);
  2756.  
  2757.                 BeginIO(ReadRequest);
  2758.             }
  2759.         }
  2760.         while(!Done);
  2761.  
  2762.         if(RexxTimeoutVal)
  2763.         {
  2764.             if(!CheckIO(TimeRequest))
  2765.                 AbortIO(TimeRequest);
  2766.  
  2767.             WaitIO(TimeRequest);
  2768.         }
  2769.  
  2770.         if(Index)
  2771.         {
  2772.             SharedBuffer[Index] = 0;
  2773.  
  2774.             ReleaseWindows();
  2775.  
  2776.             return(CreateResult(SharedBuffer,Results));
  2777.         }
  2778.         else
  2779.             Results[0] = RC_WARN;
  2780.     }
  2781.  
  2782.     ReleaseWindows();
  2783.  
  2784.     return(NULL);
  2785. }
  2786.  
  2787. STRPTR __regargs
  2788. RexxReceiveFile(struct RexxPkt *Pkt)
  2789. {
  2790.     enum    {    ARG_RECEIVEFILE_MODE,ARG_RECEIVEFILE_NAME };
  2791.  
  2792.     WORD Mode = TRANSFER_BINARY;
  2793.  
  2794.     if(Args[ARG_RECEIVEFILE_MODE])
  2795.         Mode = ToMode(Args[ARG_RECEIVEFILE_MODE]);
  2796.  
  2797.     if(Mode == -1)
  2798.     {
  2799.         Results[0] = RC_ERROR;
  2800.         Results[1] = ERROR_ACTION_NOT_KNOWN;
  2801.     }
  2802.     else
  2803.     {
  2804.         BlockWindows();
  2805.  
  2806.         switch(Mode)
  2807.         {
  2808.             case TRANSFER_ASCII:
  2809.  
  2810.                 if(ASCIISetup())
  2811.                 {
  2812.                     StartXprReceive(TRANSFER_ASCII,NULL,FALSE);
  2813.  
  2814.                     ASCIIShutdown();
  2815.  
  2816.                     LocalRexxSerialCommand(Config -> CommandConfig -> DownloadMacro,NULL);
  2817.                 }
  2818.                 else
  2819.                 {
  2820.                     Results[0] = RC_ERROR;
  2821.                     Results[1] = ERROR_NO_FREE_STORE;
  2822.                 }
  2823.  
  2824.                 break;
  2825.  
  2826.             case TRANSFER_TEXT:
  2827.  
  2828.                 BinaryTransfer = FALSE;
  2829.  
  2830.                 StartXprReceive(TRANSFER_TEXT,NULL,FALSE);
  2831.  
  2832.                 BinaryTransfer = TRUE;
  2833.  
  2834.                 LocalRexxSerialCommand(Config -> CommandConfig -> DownloadMacro,NULL);
  2835.  
  2836.                 break;
  2837.  
  2838.             case TRANSFER_BINARY:
  2839.  
  2840.                 BinaryTransfer = TRUE;
  2841.  
  2842.                 StartXprReceive(TRANSFER_BINARY,NULL,FALSE);
  2843.  
  2844.                 LocalRexxSerialCommand(Config -> CommandConfig -> DownloadMacro,NULL);
  2845.  
  2846.                 break;
  2847.         }
  2848.  
  2849.         if(TransferFailed)
  2850.             Results[0] = RC_ERROR;
  2851.  
  2852.         if(TransferAborted)
  2853.             Results[0] = RC_WARN;
  2854.  
  2855.         ReleaseWindows();
  2856.     }
  2857.  
  2858.     return(NULL);
  2859. }
  2860.  
  2861. STRPTR __regargs
  2862. RexxRedial(struct RexxPkt *Pkt)
  2863. {
  2864.     if(DialList)
  2865.     {
  2866.         if(DialList -> lh_Head -> ln_Succ)
  2867.             DoDial = DIAL_REDIAL;
  2868.         else
  2869.             Results[0] = RC_WARN;
  2870.     }
  2871.     else
  2872.         Results[0] = RC_WARN;
  2873.  
  2874.     return(NULL);
  2875. }
  2876.  
  2877. STRPTR __regargs
  2878. RexxRemove(struct RexxPkt *Pkt)
  2879. {
  2880.     enum    {    ARG_REMOVE_FROM,ARG_REMOVE_NAME };
  2881.  
  2882.     WORD Index;
  2883.  
  2884.     if((Index = ToList(Args[ARG_REMOVE_FROM])) == -1)
  2885.     {
  2886.         Results[0] = RC_ERROR;
  2887.         Results[1] = TERMERROR_UNKNOWN_LIST;
  2888.     }
  2889.     else
  2890.     {
  2891.         if(Args[ARG_REMOVE_NAME] && Index == GLIST_DIAL)
  2892.         {
  2893.             Results[0] = RC_ERROR;
  2894.             Results[1] = TERMERROR_DATA_TYPES_INCOMPATIBLE;
  2895.         }
  2896.         else
  2897.         {
  2898.             struct GenericList *List;
  2899.  
  2900.             List = GenericListTable[Index];
  2901.  
  2902.             if(Args[ARG_REMOVE_NAME])
  2903.             {
  2904.                 STRPTR Buffer;
  2905.  
  2906.                 if(Buffer = CreateMatchBuffer(Args[ARG_REMOVE_NAME]))
  2907.                 {
  2908.                     struct Node *Node,*NextNode;
  2909.  
  2910.                     ObtainSemaphore(&List -> ListSemaphore);
  2911.  
  2912.                     Node = (struct Node *)List -> ListHeader . mlh_Head;
  2913.  
  2914.                     while(NextNode = Node -> ln_Succ)
  2915.                     {
  2916.                         if(MatchBuffer(Buffer,Node -> ln_Name))
  2917.                         {
  2918.                             Forbid();
  2919.  
  2920.                             ReleaseSemaphore(&List -> ListSemaphore);
  2921.  
  2922.                             DeleteGenericListNode(List,Node);
  2923.  
  2924.                             ObtainSemaphore(&List -> ListSemaphore);
  2925.  
  2926.                             Permit();
  2927.                         }
  2928.  
  2929.                         Node = NextNode;
  2930.                     }
  2931.  
  2932.                     ReleaseSemaphore(&List -> ListSemaphore);
  2933.  
  2934.                     DeleteMatchBuffer(Buffer);
  2935.                 }
  2936.                 else
  2937.                 {
  2938.                     Results[0] = RC_ERROR;
  2939.                     Results[1] = ERROR_NO_FREE_STORE;
  2940.                 }
  2941.             }
  2942.             else
  2943.                 DeleteGenericListNode(List,NULL);
  2944.  
  2945.             if(!GenericListCount(List))
  2946.                 Results[0] = RC_WARN;
  2947.         }
  2948.     }
  2949.  
  2950.     return(NULL);
  2951. }
  2952.  
  2953. STRPTR __regargs
  2954. RexxRequestFile(struct RexxPkt *Pkt)
  2955. {
  2956.     enum    {    ARG_REQUESTFILE_TITLE,ARG_REQUESTFILE_PATH,ARG_REQUESTFILE_FILE,
  2957.             ARG_REQUESTFILE_PATTERN,ARG_REQUESTFILE_MULTI,ARG_REQUESTFILE_NAME };
  2958.  
  2959.     if(Args[ARG_REQUESTFILE_MULTI] && !Args[ARG_REQUESTFILE_NAME])
  2960.     {
  2961.         Results[0] = RC_ERROR;
  2962.         Results[1] = TERMERROR_RESULT_VARIABLE_REQUIRED;
  2963.     }
  2964.     else
  2965.     {
  2966.         struct FileRequester    *FileRequester;
  2967.         UBYTE             DummyBuffer[MAX_FILENAME_LENGTH],
  2968.                     *DummyChar;
  2969.         STRPTR             FileName,
  2970.                      PathName;
  2971.  
  2972.         if(!Args[ARG_REQUESTFILE_PATH])
  2973.         {
  2974.             PathName = Args[ARG_REQUESTFILE_PATH];
  2975.  
  2976.             if(Args[ARG_REQUESTFILE_FILE])
  2977.                 FileName = Args[ARG_REQUESTFILE_FILE];
  2978.             else
  2979.                 FileName = "";
  2980.         }
  2981.         else
  2982.         {
  2983.             PathName = "";
  2984.  
  2985.             if(Args[ARG_REQUESTFILE_FILE])
  2986.             {
  2987.                 strcpy(DummyBuffer,Args[ARG_REQUESTFILE_FILE]);
  2988.  
  2989.                 DummyChar = PathPart(DummyBuffer);
  2990.  
  2991.                 *DummyChar = 0;
  2992.  
  2993.                 PathName = DummyBuffer;
  2994.                 FileName = FilePart(Args[ARG_REQUESTFILE_FILE]);
  2995.             }
  2996.             else
  2997.                 FileName = "";
  2998.         }
  2999.  
  3000.         BlockWindows();
  3001.  
  3002.         if(FileRequester = GetFile(Args[ARG_REQUESTFILE_TITLE],PathName,FileName,DummyBuffer,Args[ARG_REQUESTFILE_PATTERN],FALSE,Args[ARG_REQUESTFILE_MULTI] != NULL,FALSE,"Ok"))
  3003.         {
  3004.             if(Args[ARG_REQUESTFILE_NAME])
  3005.             {
  3006.                 if(Args[ARG_REQUESTFILE_MULTI])
  3007.                 {
  3008.                     UBYTE         DummyBuffer[MAX_FILENAME_LENGTH];
  3009.                     struct WBArg    *ArgList = FileRequester -> rf_ArgList;
  3010.                     LONG         i,Counted = 0;
  3011.  
  3012.                     for(i = 0 ; i < FileRequester -> rf_NumArgs ; i++)
  3013.                     {
  3014.                         if(ArgList[i] . wa_Name)
  3015.                         {
  3016.                             if(ArgList[i] . wa_Lock)
  3017.                             {
  3018.                                 if(!NameFromLock(ArgList[i] . wa_Lock,DummyBuffer,MAX_FILENAME_LENGTH))
  3019.                                 {
  3020.                                     Results[0] = RC_ERROR;
  3021.                                     Results[1] = IoErr();
  3022.  
  3023.                                     break;
  3024.                                 }
  3025.                             }
  3026.                             else
  3027.                                 strcpy(DummyBuffer,FileRequester -> rf_Dir);
  3028.  
  3029.                             if(AddPart(DummyBuffer,ArgList[i] . wa_Name,MAX_FILENAME_LENGTH))
  3030.                             {
  3031.                                 if(CreateVarArgs(DummyBuffer,Pkt,"%s.%ld",Args[ARG_REQUESTFILE_NAME],i))
  3032.                                     Counted++;
  3033.                                 else
  3034.                                     break;
  3035.                             }
  3036.                             else
  3037.                             {
  3038.                                 Results[0] = RC_ERROR;
  3039.                                 Results[1] = IoErr();
  3040.  
  3041.                                 break;
  3042.                             }
  3043.                         }
  3044.                     }
  3045.  
  3046.                     if(Counted)
  3047.                     {
  3048.                         SPrintf(DummyBuffer,"%ld",Counted);
  3049.  
  3050.                         CreateVarArgs(DummyBuffer,Pkt,"%s.COUNT",Args[ARG_REQUESTFILE_NAME]);
  3051.                     }
  3052.  
  3053.                     FreeAslRequest(FileRequester);
  3054.                 }
  3055.                 else
  3056.                 {
  3057.                     FreeAslRequest(FileRequester);
  3058.  
  3059.                     return(CreateVar(DummyBuffer,Pkt,Args[ARG_REQUESTFILE_NAME]));
  3060.                 }
  3061.             }
  3062.             else
  3063.             {
  3064.                 FreeAslRequest(FileRequester);
  3065.  
  3066.                 return(CreateResult(DummyBuffer,Results));
  3067.             }
  3068.         }
  3069.         else
  3070.             Results[0] = RC_WARN;
  3071.  
  3072.         ReleaseWindows();
  3073.     }
  3074.  
  3075.     return(NULL);
  3076. }
  3077.  
  3078. STRPTR __regargs
  3079. RexxRequestNotify(struct RexxPkt *Pkt)
  3080. {
  3081.     enum    {    ARG_REQUESTNOTIFY_TITLE,ARG_REQUESTNOTIFY_PROMPT };
  3082.  
  3083.     struct EasyStruct    Easy;
  3084.     ULONG            IDCMP = NULL;
  3085.  
  3086.     Easy . es_StructSize    = sizeof(struct EasyStruct);
  3087.     Easy . es_Flags        = NULL;
  3088.     Easy . es_TextFormat    = Args[ARG_REQUESTNOTIFY_PROMPT];
  3089.     Easy . es_GadgetFormat    = LocaleString(MSG_GLOBAL_CONTINUE_TXT);
  3090.  
  3091.     if(Args[ARG_REQUESTNOTIFY_TITLE])
  3092.         Easy . es_Title    = Args[ARG_REQUESTNOTIFY_TITLE];
  3093.     else
  3094.         Easy . es_Title    = LocaleString(MSG_TERMAUX_TERM_REQUEST_TXT);
  3095.  
  3096.     BlockWindows();
  3097.  
  3098.     EasyRequestArgs(Window,&Easy,&IDCMP,NULL);
  3099.  
  3100.     ReleaseWindows();
  3101.  
  3102.     return(NULL);
  3103. }
  3104.  
  3105. STRPTR __regargs
  3106. RexxRequestNumber(struct RexxPkt *Pkt)
  3107. {
  3108.     enum    {    ARG_REQUESTNUMBER_DEFAULT,ARG_REQUESTNUMBER_PROMPT };
  3109.  
  3110.     UBYTE DummyBuffer[256];
  3111.  
  3112.     if(Args[ARG_REQUESTNUMBER_DEFAULT])
  3113.         SPrintf(DummyBuffer,"%ld",*(LONG *)Args[ARG_REQUESTNUMBER_DEFAULT]);
  3114.     else
  3115.         DummyBuffer[0] = 0;
  3116.  
  3117.     BlockWindows();
  3118.  
  3119.     if(GetString(FALSE,FALSE,255,Args[ARG_REQUESTNUMBER_PROMPT],DummyBuffer))
  3120.     {
  3121.         STRPTR Index = DummyBuffer;
  3122.  
  3123.         while(*Index == ' ' || *Index == '\t')
  3124.             Index++;
  3125.  
  3126.         if(*Index)
  3127.         {
  3128.             LONG Value;
  3129.  
  3130.             if(StrToLong(DummyBuffer,&Value) == -1)
  3131.             {
  3132.                 Results[0] = RC_ERROR;
  3133.                 Results[1] = ERROR_BAD_NUMBER;
  3134.             }
  3135.             else
  3136.             {
  3137.                 SPrintf(DummyBuffer,"%ld",Value);
  3138.  
  3139.                 return(CreateResult(DummyBuffer,Results));
  3140.             }
  3141.         }
  3142.         else
  3143.             Results[0] = RC_WARN;
  3144.     }
  3145.     else
  3146.         Results[0] = RC_WARN;
  3147.  
  3148.     ReleaseWindows();
  3149.  
  3150.     return(NULL);
  3151. }
  3152.  
  3153. STRPTR __regargs
  3154. RexxRequestResponse(struct RexxPkt *Pkt)
  3155. {
  3156.     enum    {    ARG_REQUESTRESPONSE_TITLE,ARG_REQUESTRESPONSE_OPTIONS,
  3157.             ARG_REQUESTRESPONSE_PROMPT };
  3158.  
  3159.     struct EasyStruct    Easy;
  3160.     ULONG            IDCMP = NULL;
  3161.     WORD            Result;
  3162.  
  3163.     Easy . es_StructSize    = sizeof(struct EasyStruct);
  3164.     Easy . es_Flags        = NULL;
  3165.     Easy . es_TextFormat    = Args[ARG_REQUESTRESPONSE_PROMPT];
  3166.  
  3167.     if(Args[ARG_REQUESTRESPONSE_OPTIONS])
  3168.         Easy . es_GadgetFormat = Args[ARG_REQUESTRESPONSE_OPTIONS];
  3169.     else
  3170.         Easy . es_GadgetFormat = LocaleString(MSG_GLOBAL_YES_NO_TXT);
  3171.  
  3172.     if(Args[ARG_REQUESTRESPONSE_TITLE])
  3173.         Easy . es_Title    = Args[ARG_REQUESTRESPONSE_TITLE];
  3174.     else
  3175.         Easy . es_Title    = LocaleString(MSG_TERMAUX_TERM_REQUEST_TXT);
  3176.  
  3177.     BlockWindows();
  3178.  
  3179.     Result = EasyRequestArgs(Window,&Easy,&IDCMP,NULL);
  3180.  
  3181.     ReleaseWindows();
  3182.  
  3183.     if(Result)
  3184.     {
  3185.         UBYTE DummyBuffer[20];
  3186.  
  3187.         SPrintf(DummyBuffer,"%ld",Result);
  3188.  
  3189.         return(CreateResult(DummyBuffer,Results));
  3190.     }
  3191.     else
  3192.     {
  3193.         Results[0] = RC_WARN;
  3194.  
  3195.         return(NULL);
  3196.     }
  3197. }
  3198.  
  3199. STRPTR __regargs
  3200. RexxRequestString(struct RexxPkt *Pkt)
  3201. {
  3202.     enum    {    ARG_REQUESTSTRING_SECRET,ARG_REQUESTSTRING_DEFAULT,ARG_REQUESTSTRING_PROMPT };
  3203.  
  3204.     UBYTE DummyBuffer[256];
  3205.  
  3206.     if(Args[ARG_REQUESTSTRING_DEFAULT])
  3207.         strcpy(DummyBuffer,Args[ARG_REQUESTSTRING_DEFAULT]);
  3208.     else
  3209.         DummyBuffer[0] = 0;
  3210.  
  3211.     BlockWindows();
  3212.  
  3213.     if(GetString(FALSE,Args[ARG_REQUESTSTRING_SECRET] != NULL,255,Args[ARG_REQUESTSTRING_PROMPT],DummyBuffer))
  3214.         return(CreateResult(DummyBuffer,Results));
  3215.     else
  3216.         Results[0] = RC_WARN;
  3217.  
  3218.     ReleaseWindows();
  3219.  
  3220.     return(NULL);
  3221. }
  3222.  
  3223. STRPTR __regargs
  3224. RexxResetScreen(struct RexxPkt *Pkt)
  3225. {
  3226.     if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3227.         XEmulatorResetConsole(XEM_IO);
  3228.     else
  3229.     {
  3230.         FreeMarker();
  3231.  
  3232.         ClearCursor();
  3233.  
  3234.         DoCancel();
  3235.  
  3236.         Reset();
  3237.  
  3238.         DrawCursor();
  3239.     }
  3240.  
  3241.     return(NULL);
  3242. }
  3243.  
  3244. STRPTR __regargs
  3245. RexxResetStyles(struct RexxPkt *Pkt)
  3246. {
  3247.     if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3248.         XEmulatorResetTextStyles(XEM_IO);
  3249.     else
  3250.     {
  3251.         DropMarker();
  3252.  
  3253.         ClearCursor();
  3254.  
  3255.         SetAttributes("0m");
  3256.  
  3257.         Config -> EmulationConfig -> FontScale = SCALE_NORMAL;
  3258.  
  3259.         FgPen = GetPenIndex(SafeTextPen);
  3260.         BgPen = 0;
  3261.  
  3262.         if(ReadAPen(RPort) != MappedPens[0][FgPen])
  3263.             SetAPen(RPort,MappedPens[0][FgPen]);
  3264.  
  3265.         if(ReadBPen(RPort) != MappedPens[0][BgPen])
  3266.             SetBPen(RPort,MappedPens[0][BgPen]);
  3267.  
  3268.         SetWrMsk(RPort,DepthMask);
  3269.  
  3270.         ConFontScaleUpdate();
  3271.  
  3272.         DrawCursor();
  3273.     }
  3274.  
  3275.     return(NULL);
  3276. }
  3277.  
  3278. STRPTR __regargs
  3279. RexxResetText(struct RexxPkt *Pkt)
  3280. {
  3281.     if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3282.         XEmulatorResetCharset(XEM_IO);
  3283.     else
  3284.     {
  3285.         DropMarker();
  3286.  
  3287.         CurrentFont = TextFont;
  3288.  
  3289.         SetFont(RPort,CurrentFont);
  3290.  
  3291.         ConOutputUpdate();
  3292.     }
  3293.  
  3294.     return(NULL);
  3295. }
  3296.  
  3297. STRPTR __regargs
  3298. RexxSaveAs(struct RexxPkt *Pkt)
  3299. {
  3300.     enum    {    ARG_SAVEAS_NAME,ARG_SAVEAS_FROM };
  3301.  
  3302.     WORD Index = ToConfig(Args[ARG_SAVEAS_FROM]);
  3303.  
  3304.     if(Index == -1)
  3305.     {
  3306.         Results[0] = RC_ERROR;
  3307.         Results[1] = ERROR_OBJECT_NOT_FOUND;
  3308.     }
  3309.     else
  3310.     {
  3311.         UBYTE    DummyBuffer[MAX_FILENAME_LENGTH];
  3312.         STRPTR    FileName;
  3313.  
  3314.         if(Args[ARG_SAVEAS_NAME])
  3315.             FileName = Args[ARG_SAVEAS_NAME];
  3316.         else
  3317.         {
  3318.             STRPTR             Title;
  3319.             struct FileRequester    *FileRequest;
  3320.  
  3321.             FileName = NULL;
  3322.  
  3323.             switch(Index)
  3324.             {
  3325.                 case DATATYPE_TRANSLATIONS:
  3326.  
  3327.                     Title = LocaleString(MSG_TRANSLATIONPANEL_SAVE_TRANSLATION_TABLES_TXT);
  3328.                     break;
  3329.  
  3330.                 case DATATYPE_FUNCTIONKEYS:
  3331.  
  3332.                     Title = LocaleString(MSG_MACROPANEL_SAVE_MACRO_KEYS_TXT);
  3333.                     break;
  3334.  
  3335.                 case DATATYPE_CURSORKEYS:
  3336.  
  3337.                     Title = LocaleString(MSG_CURSORPANEL_SAVE_CURSOR_KEYS_TXT);
  3338.                     break;
  3339.  
  3340.                 case DATATYPE_FASTMACROS:
  3341.  
  3342.                     Title = LocaleString(MSG_FASTMACROPANEL_SAVE_FAST_MACRO_SETTINGS_TXT);
  3343.                     break;
  3344.  
  3345.                 case DATATYPE_HOTKEYS:
  3346.  
  3347.                     Title = LocaleString(MSG_HOTKEYPANEL_SAVE_HOTKEYS_TXT);
  3348.                     break;
  3349.  
  3350.                 case DATATYPE_SPEECH:
  3351.  
  3352.                     Title = LocaleString(MSG_SPEECHPANEL_SAVE_SPEECH_SETTINGS_TXT);
  3353.                     break;
  3354.  
  3355.                 case DATATYPE_BUFFER:
  3356.  
  3357.                     Title = LocaleString(MSG_TERMMAIN_SAVE_BUFFER_TXT);
  3358.                     break;
  3359.  
  3360.                 case DATATYPE_CONFIGURATION:
  3361.  
  3362.                     Title = LocaleString(MSG_TERMMAIN_SAVE_PREFERENCES_AS_TXT);
  3363.                     break;
  3364.  
  3365.                 case DATATYPE_PHONEBOOK:
  3366.  
  3367.                     Title = LocaleString(MSG_PHONEPANEL_SAVE_PHONEBOOK_TXT);
  3368.                     break;
  3369.  
  3370.                 case DATATYPE_SCREENTEXT:
  3371.  
  3372.                     Title = LocaleString(MSG_TERMMAIN_SAVE_SCREEN_ASCII_TXT);
  3373.                     break;
  3374.  
  3375.                 case DATATYPE_SCREENIMAGE:
  3376.  
  3377.                     Title = LocaleString(MSG_TERMMAIN_SAVE_SCREEN_IFF_TXT);
  3378.                     break;
  3379.             }
  3380.  
  3381.             BlockWindows();
  3382.  
  3383.             if(FileRequest = GetFile(Title,"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,NULL))
  3384.             {
  3385.                 FileName = DummyBuffer;
  3386.  
  3387.                 FreeAslRequest(FileRequest);
  3388.             }
  3389.  
  3390.             ReleaseWindows();
  3391.         }
  3392.  
  3393.         if(FileName)
  3394.         {
  3395.             switch(Index)
  3396.             {
  3397.                 case DATATYPE_TRANSLATIONS:
  3398.                 {
  3399.                     if(SendTable && ReceiveTable)
  3400.                     {
  3401.                         if(!SaveTranslationTables(FileName,SendTable,ReceiveTable))
  3402.                         {
  3403.                             Results[0] = RC_ERROR;
  3404.                             Results[1] = IoErr();
  3405.                         }
  3406.                         else
  3407.                         {
  3408.                             strcpy(LastTranslation,FileName);
  3409.  
  3410.                             TranslationChanged = FALSE;
  3411.                         }
  3412.                     }
  3413.                     else
  3414.                         Results[0] = RC_WARN;
  3415.                 }
  3416.  
  3417.                 break;
  3418.  
  3419.                 case DATATYPE_FUNCTIONKEYS:
  3420.                 {
  3421.                     if(!WriteIFFData(FileName,MacroKeys,sizeof(struct MacroKeys),ID_KEYS))
  3422.                     {
  3423.                         Results[0] = RC_ERROR;
  3424.                         Results[1] = IoErr();
  3425.                     }
  3426.                     else
  3427.                     {
  3428.                         strcpy(LastMacros,FileName);
  3429.  
  3430.                         MacroChanged = FALSE;
  3431.                     }
  3432.                 }
  3433.  
  3434.                 break;
  3435.  
  3436.                 case DATATYPE_CURSORKEYS:
  3437.                 {
  3438.                     if(!WriteIFFData(FileName,CursorKeys,sizeof(struct CursorKeys),ID_KEYS))
  3439.                     {
  3440.                         Results[0] = RC_ERROR;
  3441.                         Results[1] = IoErr();
  3442.                     }
  3443.                     else
  3444.                     {
  3445.                         strcpy(LastCursorKeys,FileName);
  3446.  
  3447.                         CursorKeysChanged = FALSE;
  3448.                     }
  3449.                 }
  3450.  
  3451.                 break;
  3452.  
  3453.                 case DATATYPE_FASTMACROS:
  3454.                 {
  3455.                     if(!SaveFastMacros(FileName))
  3456.                     {
  3457.                         Results[0] = RC_ERROR;
  3458.                         Results[1] = IoErr();
  3459.                     }
  3460.                     else
  3461.                     {
  3462.                         strcpy(LastFastMacros,FileName);
  3463.  
  3464.                         FastMacrosChanged = FALSE;
  3465.                     }
  3466.                 }
  3467.  
  3468.                 break;
  3469.  
  3470.                 case DATATYPE_HOTKEYS:
  3471.                 {
  3472.                     if(!WriteIFFData(FileName,&Hotkeys,sizeof(struct Hotkeys),ID_HOTK))
  3473.                     {
  3474.                         Results[0] = RC_ERROR;
  3475.                         Results[1] = IoErr();
  3476.                     }
  3477.                     else
  3478.                     {
  3479.                         strcpy(LastKeys,FileName);
  3480.  
  3481.                         HotkeysChanged = FALSE;
  3482.                     }
  3483.                 }
  3484.  
  3485.                 break;
  3486.  
  3487.                 case DATATYPE_SPEECH:
  3488.                 {
  3489.                     if(!WriteIFFData(FileName,&SpeechConfig,sizeof(struct SpeechConfig),ID_SPEK))
  3490.                     {
  3491.                         Results[0] = RC_ERROR;
  3492.                         Results[1] = IoErr();
  3493.                     }
  3494.                     else
  3495.                     {
  3496.                         strcpy(LastSpeech,FileName);
  3497.  
  3498.                         SpeechChanged = FALSE;
  3499.                     }
  3500.                 }
  3501.  
  3502.                 break;
  3503.  
  3504.                 case DATATYPE_BUFFER:
  3505.                 {
  3506.                     if(BufferLines && Lines)
  3507.                     {
  3508.                         BPTR SomeFile;
  3509.  
  3510.                         if(GetFileSize(FileName))
  3511.                         {
  3512.                             if(SomeFile = Open(FileName,MODE_READWRITE))
  3513.                             {
  3514.                                 if(Seek(SomeFile,0,OFFSET_END) == -1)
  3515.                                 {
  3516.                                     Close(SomeFile);
  3517.  
  3518.                                     SomeFile = NULL;
  3519.  
  3520.                                     SetIoErr(ERROR_SEEK_ERROR);
  3521.                                 }
  3522.                             }
  3523.                         }
  3524.                         else
  3525.                             SomeFile = Open(FileName,MODE_NEWFILE);
  3526.  
  3527.                         if(SomeFile)
  3528.                         {
  3529.                             LONG i,Len;
  3530.  
  3531.                                 /* Obtain the semaphore required
  3532.                                  * to gain access to the line buffer
  3533.                                  */
  3534.  
  3535.                             ObtainSemaphore(BufferSemaphore);
  3536.  
  3537.                             for(i = 0 ; i < Lines ; i++)
  3538.                             {
  3539.                                 Len = BufferLines[i][-1];
  3540.  
  3541.                                 if(Len)
  3542.                                 {
  3543.                                     if(FWrite(SomeFile,BufferLines[i],Len,1) != 1)
  3544.                                     {
  3545.                                         Results[0] = RC_ERROR;
  3546.                                         Results[1] = IoErr();
  3547.  
  3548.                                         break;
  3549.                                     }
  3550.                                 }
  3551.  
  3552.                                 if(FPrintf(SomeFile,"\n") < 1)
  3553.                                 {
  3554.                                     Results[0] = RC_ERROR;
  3555.                                     Results[1] = IoErr();
  3556.  
  3557.                                     break;
  3558.                                 }
  3559.                             }
  3560.  
  3561.                             ReleaseSemaphore(BufferSemaphore);
  3562.  
  3563.                             Close(SomeFile);
  3564.  
  3565.                             SetProtection(FileName,FIBF_EXECUTE);
  3566.  
  3567.                             BufferChanged = FALSE;
  3568.                         }
  3569.                         else
  3570.                         {
  3571.                             Results[0] = RC_ERROR;
  3572.                             Results[1] = IoErr();
  3573.                         }
  3574.                     }
  3575.                     else
  3576.                     {
  3577.                         Results[0] = RC_ERROR;
  3578.                         Results[1] = TERMERROR_NO_DATA_TO_PROCESS;
  3579.                     }
  3580.                 }
  3581.  
  3582.                 break;
  3583.  
  3584.                 case DATATYPE_CONFIGURATION:
  3585.                 {
  3586.                     if(!WriteConfig(FileName,Config))
  3587.                     {
  3588.                         Results[0] = RC_ERROR;
  3589.                         Results[1] = IoErr();
  3590.                     }
  3591.                     else
  3592.                     {
  3593.                         strcpy(LastConfig,FileName);
  3594.  
  3595.                         ConfigChanged = FALSE;
  3596.                     }
  3597.                 }
  3598.  
  3599.                 break;
  3600.  
  3601.                 case DATATYPE_PHONEBOOK:
  3602.                 {
  3603.                     if(!SavePhonebook(FileName))
  3604.                     {
  3605.                         Results[0] = RC_ERROR;
  3606.                         Results[1] = IoErr();
  3607.                     }
  3608.                     else
  3609.                     {
  3610.                         strcpy(LastPhone,FileName);
  3611.  
  3612.                         PhonebookChanged = FALSE;
  3613.                     }
  3614.                 }
  3615.  
  3616.                 break;
  3617.  
  3618.                 case DATATYPE_SCREENTEXT:
  3619.                 {
  3620.                     if(RasterEnabled)
  3621.                     {
  3622.                         BPTR SomeFile;
  3623.  
  3624.                         if(GetFileSize(FileName))
  3625.                         {
  3626.                             if(SomeFile = Open(FileName,MODE_READWRITE))
  3627.                             {
  3628.                                 if(Seek(SomeFile,0,OFFSET_END) == -1)
  3629.                                 {
  3630.                                     Close(SomeFile);
  3631.  
  3632.                                     SomeFile = NULL;
  3633.  
  3634.                                     SetIoErr(ERROR_SEEK_ERROR);
  3635.                                 }
  3636.                             }
  3637.                         }
  3638.                         else
  3639.                             SomeFile = Open(FileName,MODE_NEWFILE);
  3640.  
  3641.                         if(SomeFile)
  3642.                         {
  3643.                             LONG     i,j;
  3644.                             UBYTE    *Buffer;
  3645.  
  3646.                             for(i = 0 ; i < RasterHeight ; i++)
  3647.                             {
  3648.                                 Buffer = &Raster[i * RasterWidth];
  3649.  
  3650.                                 j = LastColumn;
  3651.  
  3652.                                 while(j >= 0 && Buffer[j] == ' ')
  3653.                                     j--;
  3654.  
  3655.                                 if(j >= 0)
  3656.                                 {
  3657.                                     if(!FWrite(SomeFile,Buffer,j + 1,1))
  3658.                                     {
  3659.                                         Results[0] = RC_ERROR;
  3660.                                         Results[1] = IoErr();
  3661.  
  3662.                                         break;
  3663.                                     }
  3664.                                 }
  3665.  
  3666.                                 if(!FWrite(SomeFile,"\n",1,1))
  3667.                                 {
  3668.                                     Results[0] = RC_ERROR;
  3669.                                     Results[1] = IoErr();
  3670.  
  3671.                                     break;
  3672.                                 }
  3673.                             }
  3674.  
  3675.                             Close(SomeFile);
  3676.  
  3677.                             SetProtection(FileName,FIBF_EXECUTE);
  3678.                         }
  3679.                         else
  3680.                         {
  3681.                             Results[0] = RC_ERROR;
  3682.                             Results[1] = IoErr();
  3683.                         }
  3684.                     }
  3685.                     else
  3686.                     {
  3687.                         Results[0] = RC_ERROR;
  3688.                         Results[1] = TERMERROR_NO_DATA_TO_PROCESS;
  3689.                     }
  3690.                 }
  3691.  
  3692.                 break;
  3693.  
  3694.                 case DATATYPE_SCREENIMAGE:
  3695.                 {
  3696.                     if(!SaveWindow(FileName,Window))
  3697.                     {
  3698.                         Results[0] = RC_ERROR;
  3699.                         Results[1] = IoErr();
  3700.                     }
  3701.                 }
  3702.  
  3703.                 break;
  3704.             }
  3705.         }
  3706.         else
  3707.             Results[0] = RC_WARN;
  3708.     }
  3709.  
  3710.     return(NULL);
  3711. }
  3712.  
  3713. STRPTR __regargs
  3714. RexxSave(struct RexxPkt *Pkt)
  3715. {
  3716.     enum    {    ARG_SAVE_FROM };
  3717.  
  3718.     Args[1] = Args[ARG_SAVE_FROM];
  3719.     Args[0] = NULL;
  3720.  
  3721.     return(RexxSaveAs(Pkt));
  3722. }
  3723.  
  3724. STRPTR __regargs
  3725. RexxSelect(struct RexxPkt *Pkt)
  3726. {
  3727.     enum    {    ARG_SELECT_NAME,ARG_SELECT_FROM,ARG_SELECT_NEXT,ARG_SELECT_PREVIOUS,
  3728.             ARG_SELECT_TOP,ARG_SELECT_BOTTOM };
  3729.  
  3730.     WORD Index;
  3731.  
  3732.     if((Index = ToList(Args[ARG_SELECT_FROM])) == -1)
  3733.     {
  3734.         Results[0] = RC_ERROR;
  3735.         Results[1] = TERMERROR_UNKNOWN_LIST;
  3736.     }
  3737.     else
  3738.     {
  3739.         if(Args[ARG_SELECT_NAME] && Index == GLIST_DIAL)
  3740.         {
  3741.             Results[0] = RC_ERROR;
  3742.             Results[1] = TERMERROR_DATA_TYPES_INCOMPATIBLE;
  3743.         }
  3744.         else
  3745.         {
  3746.             struct GenericList *List;
  3747.  
  3748.             List = GenericListTable[Index];
  3749.  
  3750.             if(Args[ARG_SELECT_NAME])
  3751.             {
  3752.                 STRPTR Buffer;
  3753.  
  3754.                 if(Buffer = CreateMatchBuffer(Args[ARG_SELECT_NAME]))
  3755.                 {
  3756.                     struct Node *Node,*NextNode;
  3757.  
  3758.                     ObtainSemaphore(&List -> ListSemaphore);
  3759.  
  3760.                     Node = (struct Node *)List -> ListHeader . mlh_Head;
  3761.  
  3762.                     while(NextNode = Node -> ln_Succ)
  3763.                     {
  3764.                         if(MatchBuffer(Buffer,Node -> ln_Name))
  3765.                         {
  3766.                             List -> ListNode = Node;
  3767.  
  3768.                             Node = NULL;
  3769.  
  3770.                             break;
  3771.                         }
  3772.  
  3773.                         Node = NextNode;
  3774.                     }
  3775.  
  3776.                     if(Node)
  3777.                         Results[0] = RC_WARN;
  3778.  
  3779.                     ReleaseSemaphore(&List -> ListSemaphore);
  3780.  
  3781.                     DeleteMatchBuffer(Buffer);
  3782.                 }
  3783.                 else
  3784.                 {
  3785.                     Results[0] = RC_ERROR;
  3786.                     Results[1] = ERROR_NO_FREE_STORE;
  3787.                 }
  3788.             }
  3789.             else
  3790.             {
  3791.                 if(Args[ARG_SELECT_NEXT])
  3792.                 {
  3793.                     if(!NextGenericListNode(List))
  3794.                     {
  3795.                         Results[0] = RC_WARN;
  3796.  
  3797.                         return(NULL);
  3798.                     }
  3799.                 }
  3800.  
  3801.                 if(Args[ARG_SELECT_PREVIOUS])
  3802.                 {
  3803.                     if(!PrevGenericListNode(List))
  3804.                     {
  3805.                         Results[0] = RC_WARN;
  3806.  
  3807.                         return(NULL);
  3808.                     }
  3809.                 }
  3810.  
  3811.                 if(Args[ARG_SELECT_TOP])
  3812.                 {
  3813.                     if(!FirstGenericListNode(List))
  3814.                     {
  3815.                         Results[0] = RC_WARN;
  3816.  
  3817.                         return(NULL);
  3818.                     }
  3819.                 }
  3820.  
  3821.                 if(Args[ARG_SELECT_BOTTOM])
  3822.                 {
  3823.                     if(!LastGenericListNode(List))
  3824.                     {
  3825.                         Results[0] = RC_WARN;
  3826.  
  3827.                         return(NULL);
  3828.                     }
  3829.                 }
  3830.             }
  3831.  
  3832.             ObtainSemaphore(&List -> ListSemaphore);
  3833.  
  3834.             if(List -> ListNode)
  3835.             {
  3836.                 if(Index != GLIST_DIAL)
  3837.                 {
  3838.                     struct Node    *Node = (struct Node *)List -> ListNode;
  3839.                     STRPTR         Result;
  3840.  
  3841.                     Result = CreateResult(Node -> ln_Name,Results);
  3842.  
  3843.                     ReleaseSemaphore(&List -> ListSemaphore);
  3844.  
  3845.                     return(Result);
  3846.                 }
  3847.             }
  3848.             else
  3849.                 Results[0] = RC_WARN;
  3850.  
  3851.             ReleaseSemaphore(&List -> ListSemaphore);
  3852.         }
  3853.     }
  3854.  
  3855.     return(NULL);
  3856. }
  3857.  
  3858. STRPTR __regargs
  3859. RexxSend(struct RexxPkt *Pkt)
  3860. {
  3861.     enum    {    ARG_SEND_NOECHO,ARG_SEND_BYTE,ARG_SEND_TEXT };
  3862.  
  3863.     if(Args[ARG_SEND_NOECHO])
  3864.         Quiet = TRUE;
  3865.  
  3866.     if(Args[ARG_SEND_TEXT])
  3867.         LocalRexxSerialCommand(Args[ARG_SEND_TEXT],Pkt);
  3868.     else
  3869.     {
  3870.         UBYTE Byte = *(LONG *)Args[ARG_SEND_BYTE];
  3871.  
  3872.         SerWrite(&Byte,1);
  3873.     }
  3874.  
  3875.     Quiet = FALSE;
  3876.  
  3877.     return(NULL);
  3878. }
  3879.  
  3880. STRPTR __regargs
  3881. RexxSendBreak(struct RexxPkt *Pkt)
  3882. {
  3883.     if(WriteRequest)
  3884.     {
  3885.         BYTE OldStatus = Status;
  3886.  
  3887.         Status = STATUS_BREAKING;
  3888.  
  3889.         WriteRequest -> IOSer . io_Command = SDCMD_BREAK;
  3890.  
  3891.         BlockWindows();
  3892.  
  3893.         DoIO(WriteRequest);
  3894.  
  3895.         ReleaseWindows();
  3896.  
  3897.         Status = OldStatus;
  3898.     }
  3899.     else
  3900.         Results[0] = RC_WARN;
  3901.  
  3902.     return(NULL);
  3903. }
  3904.  
  3905. STRPTR __regargs
  3906. RexxSendFile(struct RexxPkt *Pkt)
  3907. {
  3908.     enum    {    ARG_SENDFILE_MODE,ARG_SENDFILE_NAMES };
  3909.  
  3910.     WORD Mode = TRANSFER_BINARY;
  3911.  
  3912.     if(Args[ARG_SENDFILE_MODE])
  3913.         Mode = ToMode(Args[ARG_SENDFILE_MODE]);
  3914.  
  3915.     if(Mode == -1)
  3916.     {
  3917.         Results[0] = RC_ERROR;
  3918.         Results[1] = ERROR_ACTION_NOT_KNOWN;
  3919.     }
  3920.     else
  3921.     {
  3922.         struct FileTransferInfo    *Info;
  3923.         LONG             FilesFound = 0;
  3924.  
  3925.         if(Info = AllocFileTransferInfo())
  3926.         {
  3927.             struct GenericList *List = GenericListTable[GLIST_UPLOAD];
  3928.  
  3929.             if(Args[ARG_SENDFILE_NAMES])
  3930.             {
  3931.                 struct FileInfoBlock *FileInfo;
  3932.  
  3933.                 if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  3934.                 {
  3935.                     STRPTR    *Names = (STRPTR *)Args[ARG_SENDFILE_NAMES];
  3936.                     BPTR     FileLock;
  3937.  
  3938.                     while(*Names && Results[0] == RC_OK)
  3939.                     {
  3940.                         if(FileLock = Lock(*Names,ACCESS_READ))
  3941.                         {
  3942.                             if(Examine(FileLock,FileInfo))
  3943.                             {
  3944.                                 if(FileInfo -> fib_DirEntryType < 0)
  3945.                                 {
  3946.                                     if(NameFromLock(FileLock,SharedBuffer,512))
  3947.                                     {
  3948.                                         if(AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  3949.                                             FilesFound++;
  3950.                                         else
  3951.                                         {
  3952.                                             Results[0] = RC_ERROR;
  3953.                                             Results[1] = ERROR_NO_FREE_STORE;
  3954.                                         }
  3955.                                     }
  3956.                                     else
  3957.                                     {
  3958.                                         Results[0] = RC_ERROR;
  3959.                                         Results[1] = IoErr();
  3960.                                     }
  3961.                                 }
  3962.                                 else
  3963.                                 {
  3964.                                     Results[0] = RC_ERROR;
  3965.                                     Results[1] = ERROR_OBJECT_WRONG_TYPE;
  3966.                                 }
  3967.                             }
  3968.                             else
  3969.                             {
  3970.                                 Results[0] = RC_ERROR;
  3971.                                 Results[1] = IoErr();
  3972.                             }
  3973.  
  3974.                             UnLock(FileLock);
  3975.                         }
  3976.                         else
  3977.                         {
  3978.                             Results[0] = RC_ERROR;
  3979.                             Results[1] = IoErr();
  3980.                         }
  3981.  
  3982.                         Names++;
  3983.                     }
  3984.  
  3985.                     FreeDosObject(DOS_FIB,FileInfo);
  3986.                 }
  3987.                 else
  3988.                 {
  3989.                     Results[0] = RC_ERROR;
  3990.                     Results[1] = ERROR_NO_FREE_STORE;
  3991.                 }
  3992.             }
  3993.  
  3994.             ObtainSemaphore(&List -> ListSemaphore);
  3995.  
  3996.             if(List -> ListHeader . mlh_Head -> mln_Succ)
  3997.             {
  3998.                 struct Node        *Node = (struct Node *)List -> ListHeader . mlh_Head;
  3999.                 struct FileInfoBlock    *FileInfo;
  4000.  
  4001.                 if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  4002.                 {
  4003.                     BPTR FileLock;
  4004.  
  4005.                     while(Node -> ln_Succ && Results[0] == RC_OK)
  4006.                     {
  4007.                         if(FileLock = Lock(Node -> ln_Name,ACCESS_READ))
  4008.                         {
  4009.                             if(Examine(FileLock,FileInfo))
  4010.                             {
  4011.                                 if(FileInfo -> fib_DirEntryType < 0)
  4012.                                 {
  4013.                                     if(NameFromLock(FileLock,SharedBuffer,512))
  4014.                                     {
  4015.                                         if(AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  4016.                                             FilesFound++;
  4017.                                         else
  4018.                                         {
  4019.                                             Results[0] = RC_ERROR;
  4020.                                             Results[1] = ERROR_NO_FREE_STORE;
  4021.                                         }
  4022.                                     }
  4023.                                     else
  4024.                                     {
  4025.                                         Results[0] = RC_ERROR;
  4026.                                         Results[1] = IoErr();
  4027.                                     }
  4028.                                 }
  4029.                                 else
  4030.                                 {
  4031.                                     Results[0] = RC_ERROR;
  4032.                                     Results[1] = ERROR_OBJECT_WRONG_TYPE;
  4033.                                 }
  4034.                             }
  4035.                             else
  4036.                             {
  4037.                                 Results[0] = RC_ERROR;
  4038.                                 Results[1] = IoErr();
  4039.                             }
  4040.  
  4041.                             UnLock(FileLock);
  4042.                         }
  4043.                         else
  4044.                         {
  4045.                             Results[0] = RC_ERROR;
  4046.                             Results[1] = IoErr();
  4047.                         }
  4048.  
  4049.                         Node = Node -> ln_Succ;
  4050.                     }
  4051.  
  4052.                     FreeDosObject(DOS_FIB,FileInfo);
  4053.                 }
  4054.                 else
  4055.                 {
  4056.                     Results[0] = RC_ERROR;
  4057.                     Results[1] = ERROR_NO_FREE_STORE;
  4058.                 }
  4059.             }
  4060.  
  4061.             ReleaseSemaphore(&List -> ListSemaphore);
  4062.  
  4063.             if(Results[0] == RC_OK)
  4064.             {
  4065.                 BlockWindows();
  4066.  
  4067.                 if(FilesFound)
  4068.                 {
  4069.                     SortFileTransferInfo(Info);
  4070.  
  4071.                     FileTransferInfo = Info;
  4072.                 }
  4073.  
  4074.                 switch(Mode)
  4075.                 {
  4076.                     case TRANSFER_ASCII:
  4077.  
  4078.                         if(ASCIISetup())
  4079.                         {
  4080.                             if(FilesFound)
  4081.                                 StartXprSendFromList(TRANSFER_ASCII,FALSE);
  4082.                             else
  4083.                                 StartXprSend(TRANSFER_ASCII,FALSE);
  4084.  
  4085.                             ASCIIShutdown();
  4086.  
  4087.                             LocalRexxSerialCommand(Config -> CommandConfig -> UploadMacro,NULL);
  4088.                         }
  4089.                         else
  4090.                         {
  4091.                             Results[0] = RC_ERROR;
  4092.                             Results[1] = ERROR_NO_FREE_STORE;
  4093.                         }
  4094.  
  4095.                         break;
  4096.  
  4097.                     case TRANSFER_TEXT:
  4098.  
  4099.                         BinaryTransfer = FALSE;
  4100.  
  4101.                         if(FilesFound)
  4102.                             StartXprSendFromList(TRANSFER_TEXT,FALSE);
  4103.                         else
  4104.                             StartXprSend(TRANSFER_TEXT,FALSE);
  4105.  
  4106.                         BinaryTransfer = TRUE;
  4107.  
  4108.                         LocalRexxSerialCommand(Config -> CommandConfig -> UploadMacro,NULL);
  4109.  
  4110.                         break;
  4111.  
  4112.                     case TRANSFER_BINARY:
  4113.  
  4114.                         BinaryTransfer = TRUE;
  4115.  
  4116.                         if(FilesFound)
  4117.                             StartXprSendFromList(TRANSFER_BINARY,FALSE);
  4118.                         else
  4119.                             StartXprSend(TRANSFER_BINARY,FALSE);
  4120.  
  4121.                         LocalRexxSerialCommand(Config -> CommandConfig -> UploadMacro,NULL);
  4122.  
  4123.                         break;
  4124.                 }
  4125.  
  4126.                 if(TransferFailed)
  4127.                     Results[0] = RC_ERROR;
  4128.  
  4129.                 if(TransferAborted)
  4130.                     Results[0] = RC_WARN;
  4131.  
  4132.                 ReleaseWindows();
  4133.             }
  4134.             else
  4135.                 FreeFileTransferInfo(Info);
  4136.         }
  4137.         else
  4138.         {
  4139.             Results[0] = RC_ERROR;
  4140.             Results[1] = ERROR_NO_FREE_STORE;
  4141.         }
  4142.     }
  4143.  
  4144.     return(NULL);
  4145. }
  4146.  
  4147. STRPTR __regargs
  4148. RexxSpeak(struct RexxPkt *Pkt)
  4149. {
  4150.     enum    {    ARG_SPEAK_TEXT };
  4151.  
  4152.     if(SpeechConfig . Enabled && English)
  4153.         Say(Args[ARG_SPEAK_TEXT]);
  4154.     else
  4155.         Results[0] = RC_WARN;
  4156.  
  4157.     return(NULL);
  4158. }
  4159.  
  4160. STRPTR __regargs
  4161. RexxStopBits(struct RexxPkt *Pkt)
  4162. {
  4163.     enum    {    ARG_STOPBITS_0,ARG_STOPBITS_1 };
  4164.  
  4165.     BYTE Bits;
  4166.  
  4167.     if(Args[ARG_STOPBITS_0])
  4168.         Bits = 0;
  4169.  
  4170.     if(Args[ARG_STOPBITS_1])
  4171.         Bits = 1;
  4172.  
  4173.     if(Config -> SerialConfig -> StopBits != Bits)
  4174.     {
  4175.         Config -> SerialConfig -> StopBits = Bits;
  4176.  
  4177.         UpdateRequired = TRUE;
  4178.  
  4179.         ConfigChanged = TRUE;
  4180.     }
  4181.  
  4182.     return(NULL);
  4183. }
  4184.  
  4185. STRPTR __regargs
  4186. RexxTextBuffer(struct RexxPkt *Pkt)
  4187. {
  4188.     enum    {    ARG_TEXTBUFFER_LOCK,ARG_TEXTBUFFER_UNLOCK };
  4189.  
  4190.     if(Args[ARG_TEXTBUFFER_LOCK])
  4191.         BufferFrozen = TRUE;
  4192.  
  4193.     if(Args[ARG_TEXTBUFFER_UNLOCK])
  4194.         BufferFrozen = FALSE;
  4195.  
  4196.     CheckItem(MEN_FREEZE_BUFFER,BufferFrozen);
  4197.  
  4198.     return(NULL);
  4199. }
  4200.  
  4201. STRPTR __regargs
  4202. RexxTimeout(struct RexxPkt *Pkt)
  4203. {
  4204.     enum    {    ARG_TIMEOUT_SECONDS,ARG_TIMEOUT_OFF };
  4205.  
  4206.     if(Args[ARG_TIMEOUT_OFF])
  4207.         RexxTimeoutVal = 0;
  4208.     else
  4209.         RexxTimeoutVal = *(LONG *)Args[ARG_TIMEOUT_SECONDS];
  4210.  
  4211.     return(NULL);
  4212.  
  4213. }
  4214.  
  4215. STRPTR __regargs
  4216. RexxWait(struct RexxPkt *Pkt)
  4217. {
  4218.     enum    {    ARG_WAIT_NOECHO,ARG_WAIT_TEXT };
  4219.  
  4220.     ULONG         Signals;
  4221.     STRPTR         Result = NULL;
  4222.     BYTE         Echo;
  4223.     struct WaitNode    *WaitNode,
  4224.              Node;
  4225.     UBYTE         DummyBuffer[256];
  4226.  
  4227.     if(Args[ARG_WAIT_NOECHO])
  4228.         Echo = FALSE;
  4229.     else
  4230.         Echo = TRUE;
  4231.  
  4232.     if(Args[ARG_WAIT_TEXT])
  4233.     {
  4234.         WORD i;
  4235.  
  4236.         memcpy(DummyBuffer,Args[ARG_WAIT_TEXT],255);
  4237.  
  4238.         DummyBuffer[255] = 0;
  4239.  
  4240.         for(i = 0 ; i < strlen(DummyBuffer) ; i++)
  4241.             DummyBuffer[i] = ToUpper(DummyBuffer[i]);
  4242.  
  4243.         Node . Node . ln_Name    = DummyBuffer;
  4244.         Node . Count        = 0;
  4245.  
  4246.         WaitNode = &Node;
  4247.     }
  4248.     else
  4249.     {
  4250.         if(!GenericListCount(GenericListTable[GLIST_WAIT]))
  4251.         {
  4252.             Results[0] = RC_ERROR;
  4253.             Results[1] = TERMERROR_LIST_IS_ALREADY_EMPTY;
  4254.  
  4255.             return(NULL);
  4256.         }
  4257.         else
  4258.         {
  4259.             WaitNode = (struct WaitNode *)GenericListTable[GLIST_WAIT] -> ListHeader . mlh_Head;
  4260.  
  4261.             while(WaitNode -> Node . ln_Succ)
  4262.             {
  4263.                 WaitNode -> Count = 0;
  4264.  
  4265.                 WaitNode = (struct WaitNode *)WaitNode -> Node . ln_Succ;
  4266.             }
  4267.  
  4268.             WaitNode = NULL;
  4269.         }
  4270.     }
  4271.  
  4272.     if(RexxTimeoutVal)
  4273.     {
  4274.         TimeRequest -> tr_node . io_Command    = TR_ADDREQUEST;
  4275.         TimeRequest -> tr_time . tv_secs    = RexxTimeoutVal;
  4276.         TimeRequest -> tr_time . tv_micro    = 0;
  4277.  
  4278.         SetSignal(0,SIG_TIMER);
  4279.  
  4280.         BeginIO(TimeRequest);
  4281.     }
  4282.  
  4283.     WaitCount = 0;
  4284.  
  4285.     BlockWindows();
  4286.  
  4287.     if(Marking)
  4288.         DropMarker();
  4289.  
  4290.     ClearCursor();
  4291.  
  4292.     do
  4293.     {
  4294.         Signals = Wait(SIG_SERIAL | SIG_TIMER | SIG_BREAK);
  4295.  
  4296.         if(Signals & (SIG_BREAK | SIG_TIMER))
  4297.         {
  4298.             Results[0] = RC_WARN;
  4299.  
  4300.             if(!CheckIO(ReadRequest))
  4301.                 AbortIO(ReadRequest);
  4302.  
  4303.             WaitIO(ReadRequest);
  4304.  
  4305.             ReadRequest -> IOSer . io_Command    = CMD_READ;
  4306.             ReadRequest -> IOSer . io_Data        = ReadBuffer;
  4307.             ReadRequest -> IOSer . io_Length     = 1;
  4308.  
  4309.             SetSignal(0,SIG_SERIAL);
  4310.  
  4311.             BeginIO(ReadRequest);
  4312.  
  4313.             break;
  4314.         }
  4315.  
  4316.         if(Signals & SIG_SERIAL)
  4317.         {
  4318.             if(!WaitIO(ReadRequest))
  4319.             {
  4320.                 LONG Length;
  4321.  
  4322.                 BytesIn++;
  4323.  
  4324.                 if(Echo)
  4325.                 {
  4326.                     ConProcess(ReadBuffer,1);
  4327.  
  4328.                     Status = STATUS_READY;
  4329.                 }
  4330.  
  4331.                 if(!Result)
  4332.                     Result = ScanNodeFilter(ReadBuffer,1,WaitNode);
  4333.  
  4334.                 do
  4335.                 {
  4336.                         /* Check how many bytes are still in
  4337.                          * the serial buffer.
  4338.                          */
  4339.  
  4340.                     WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  4341.  
  4342.                     DoIO(WriteRequest);
  4343.  
  4344.                     if(Length = WriteRequest -> IOSer . io_Actual)
  4345.                     {
  4346.                         if(Length > Config -> SerialConfig -> SerialBufferSize)
  4347.                             Length = Config -> SerialConfig -> SerialBufferSize;
  4348.  
  4349.                         ReadRequest -> IOSer . io_Command    = CMD_READ;
  4350.                         ReadRequest -> IOSer . io_Data        = ReadBuffer;
  4351.                         ReadRequest -> IOSer . io_Length    = Length;
  4352.  
  4353.                         if(!DoIO(ReadRequest))
  4354.                         {
  4355.                             BytesIn += ReadRequest -> IOSer . io_Actual;
  4356.  
  4357.                                 /* Send the data to the console. */
  4358.  
  4359.                             if(Echo)
  4360.                             {
  4361.                                 ConProcess(ReadBuffer,Length);
  4362.  
  4363.                                 Status = STATUS_READY;
  4364.                             }
  4365.                         }
  4366.  
  4367.                         if(!Result)
  4368.                             Result = ScanNodeFilter(ReadBuffer,Length,WaitNode);
  4369.                     }
  4370.                 }
  4371.                 while(Length);
  4372.             }
  4373.  
  4374.             ReadRequest -> IOSer . io_Command    = CMD_READ;
  4375.             ReadRequest -> IOSer . io_Data        = ReadBuffer;
  4376.             ReadRequest -> IOSer . io_Length     = 1;
  4377.  
  4378.             SetSignal(0,SIG_SERIAL);
  4379.  
  4380.             BeginIO(ReadRequest);
  4381.         }
  4382.     }
  4383.     while(!Result);
  4384.  
  4385.     DrawCursor();
  4386.  
  4387.     ReleaseWindows();
  4388.  
  4389.     if(RexxTimeoutVal)
  4390.     {
  4391.         if(!CheckIO(TimeRequest))
  4392.             AbortIO(TimeRequest);
  4393.  
  4394.         WaitIO(TimeRequest);
  4395.     }
  4396.  
  4397.     if(Result)
  4398.         return(CreateResult(Result,Results));
  4399.     else
  4400.         return(NULL);
  4401. }
  4402.  
  4403. STRPTR __regargs
  4404. RexxWindow(struct RexxPkt *Pkt)
  4405. {
  4406.     enum    {    ARG_WINDOW_NAMES,ARG_WINDOW_OPEN,ARG_WINDOW_CLOSE,ARG_WINDOW_ACTIVATE,
  4407.             ARG_WINDOW_MIN,ARG_WINDOW_MAX,ARG_WINDOW_FRONT,ARG_WINDOW_BACK,
  4408.             ARG_WINDOW_TOP,ARG_WINDOW_BOTTOM,ARG_WINDOW_UP,ARG_WINDOW_DOWN };
  4409.  
  4410.     STRPTR    *Names = (STRPTR *)Args[ARG_WINDOW_NAMES];
  4411.     WORD     Index;
  4412.  
  4413.     while(*Names)
  4414.     {
  4415.         if((Index = ToWindow(*Names++)) != -1)
  4416.         {
  4417.             if(Args[ARG_WINDOW_OPEN])
  4418.             {
  4419.                 switch(Index)
  4420.                 {
  4421.                     case WINDOW_BUFFER:
  4422.  
  4423.                         if(!BufferProcess)
  4424.                             LaunchBuffer();
  4425.  
  4426.                         break;
  4427.  
  4428.                     case WINDOW_REVIEW:
  4429.  
  4430.                         if(!ReviewWindow)
  4431.                             CreateReview();
  4432.  
  4433.                         break;
  4434.  
  4435.                     case WINDOW_PACKET:
  4436.  
  4437.                         if(!PacketWindow)
  4438.                             CreatePacketWindow();
  4439.  
  4440.                         break;
  4441.  
  4442.                     case WINDOW_FASTMACROS:
  4443.  
  4444.                         if(!FastWindow)
  4445.                             OpenFastWindow();
  4446.  
  4447.                         break;
  4448.  
  4449.                     case WINDOW_STATUS:
  4450.  
  4451.                         if(!InfoWindow)
  4452.                             OpenInfoWindow();
  4453.  
  4454.                         break;
  4455.  
  4456.                     case WINDOW_MAIN:
  4457.  
  4458.                         if(!IconTerminated)
  4459.                             IconTerminated = TRUE;
  4460.  
  4461.                         break;
  4462.                 }
  4463.             }
  4464.  
  4465.             if(Args[ARG_WINDOW_CLOSE])
  4466.             {
  4467.                 switch(Index)
  4468.                 {
  4469.                     case WINDOW_BUFFER:
  4470.  
  4471.                         if(BufferProcess)
  4472.                         {
  4473.                             Forbid();
  4474.  
  4475.                             Signal(BufferProcess,SIG_KILL);
  4476.  
  4477.                             SetSignal(0,SIG_HANDSHAKE);
  4478.  
  4479.                             Wait(SIG_HANDSHAKE);
  4480.  
  4481.                             Permit();
  4482.                         }
  4483.  
  4484.                         break;
  4485.  
  4486.                     case WINDOW_REVIEW:
  4487.  
  4488.                         if(ReviewWindow)
  4489.                             DeleteReview();
  4490.  
  4491.                         break;
  4492.  
  4493.                     case WINDOW_PACKET:
  4494.  
  4495.                         if(PacketWindow)
  4496.                             DeletePacketWindow(FALSE);
  4497.  
  4498.                         break;
  4499.  
  4500.                     case WINDOW_FASTMACROS:
  4501.  
  4502.                         if(FastWindow)
  4503.                             CloseFastWindow();
  4504.  
  4505.                         break;
  4506.  
  4507.                     case WINDOW_STATUS:
  4508.  
  4509.                         if(InfoWindow)
  4510.                             CloseInfoWindow();
  4511.  
  4512.                         break;
  4513.  
  4514.                     case WINDOW_MAIN:
  4515.  
  4516.                         if(Window)
  4517.                             DoIconify = TRUE;
  4518.  
  4519.                         break;
  4520.                 }
  4521.             }
  4522.  
  4523.             if(Args[ARG_WINDOW_ACTIVATE])
  4524.             {
  4525.                 switch(Index)
  4526.                 {
  4527.                     case WINDOW_BUFFER:
  4528.  
  4529.                         if(BufferProcess)
  4530.                             LaunchBuffer();
  4531.  
  4532.                         break;
  4533.  
  4534.                     case WINDOW_REVIEW:
  4535.  
  4536.                         if(ReviewWindow)
  4537.                             BumpWindow(ReviewWindow);
  4538.  
  4539.                         break;
  4540.  
  4541.                     case WINDOW_PACKET:
  4542.  
  4543.                         if(PacketWindow)
  4544.                             BumpWindow(PacketWindow);
  4545.  
  4546.                         break;
  4547.  
  4548.                     case WINDOW_FASTMACROS:
  4549.  
  4550.                         if(FastWindow)
  4551.                             BumpWindow(FastWindow);
  4552.  
  4553.                         break;
  4554.  
  4555.                     case WINDOW_STATUS:
  4556.  
  4557.                         if(InfoWindow)
  4558.                             BumpWindow(InfoWindow);
  4559.  
  4560.                         break;
  4561.  
  4562.                     case WINDOW_MAIN:
  4563.  
  4564.                         if(Window)
  4565.                             BumpWindow(Window);
  4566.  
  4567.                         break;
  4568.                 }
  4569.             }
  4570.  
  4571.             if(Args[ARG_WINDOW_MIN])
  4572.             {
  4573.                 struct Window *SomeWindow = NULL;
  4574.  
  4575.                 switch(Index)
  4576.                 {
  4577.                     case WINDOW_REVIEW:
  4578.  
  4579.                         SomeWindow = ReviewWindow;
  4580.                         break;
  4581.  
  4582.                     case WINDOW_PACKET:
  4583.  
  4584.                         SomeWindow = PacketWindow;
  4585.                         break;
  4586.  
  4587.                     case WINDOW_FASTMACROS:
  4588.  
  4589.                         SomeWindow = FastWindow;
  4590.                         break;
  4591.  
  4592.                     case WINDOW_STATUS:
  4593.  
  4594.                         SomeWindow = InfoWindow;
  4595.                         break;
  4596.                 }
  4597.  
  4598.                 if(SomeWindow)
  4599.                     ChangeWindowBox(SomeWindow,SomeWindow -> LeftEdge,SomeWindow -> TopEdge,SomeWindow -> MinWidth,SomeWindow -> MinHeight);
  4600.             }
  4601.  
  4602.             if(Args[ARG_WINDOW_MAX])
  4603.             {
  4604.                 struct Window *SomeWindow = NULL;
  4605.  
  4606.                 switch(Index)
  4607.                 {
  4608.                     case WINDOW_REVIEW:
  4609.  
  4610.                         SomeWindow = ReviewWindow;
  4611.                         break;
  4612.  
  4613.                     case WINDOW_PACKET:
  4614.  
  4615.                         SomeWindow = PacketWindow;
  4616.                         break;
  4617.  
  4618.                     case WINDOW_FASTMACROS:
  4619.  
  4620.                         SomeWindow = FastWindow;
  4621.                         break;
  4622.  
  4623.                     case WINDOW_STATUS:
  4624.  
  4625.                         SomeWindow = InfoWindow;
  4626.                         break;
  4627.                 }
  4628.  
  4629.                 if(SomeWindow)
  4630.                     ChangeWindowBox(SomeWindow,0,0,SomeWindow -> MaxWidth,SomeWindow -> MaxHeight);
  4631.             }
  4632.  
  4633.             if(Args[ARG_WINDOW_FRONT])
  4634.             {
  4635.                 switch(Index)
  4636.                 {
  4637.                     case WINDOW_BUFFER:
  4638.  
  4639.                         if(BufferProcess)
  4640.                             LaunchBuffer();
  4641.  
  4642.                         break;
  4643.  
  4644.                     case WINDOW_REVIEW:
  4645.  
  4646.                         if(ReviewWindow)
  4647.                             WindowToFront(ReviewWindow);
  4648.  
  4649.                         break;
  4650.  
  4651.                     case WINDOW_PACKET:
  4652.  
  4653.                         if(PacketWindow)
  4654.                             WindowToFront(PacketWindow);
  4655.  
  4656.                         break;
  4657.  
  4658.                     case WINDOW_FASTMACROS:
  4659.  
  4660.                         if(FastWindow)
  4661.                             WindowToFront(FastWindow);
  4662.  
  4663.                         break;
  4664.  
  4665.                     case WINDOW_STATUS:
  4666.  
  4667.                         if(InfoWindow)
  4668.                             WindowToFront(InfoWindow);
  4669.  
  4670.                         break;
  4671.  
  4672.                     case WINDOW_MAIN:
  4673.  
  4674.                         if(Window)
  4675.                             WindowToFront(Window);
  4676.  
  4677.                         break;
  4678.                 }
  4679.             }
  4680.  
  4681.             if(Args[ARG_WINDOW_BACK])
  4682.             {
  4683.                 switch(Index)
  4684.                 {
  4685.                     case WINDOW_REVIEW:
  4686.  
  4687.                         if(ReviewWindow)
  4688.                             WindowToBack(ReviewWindow);
  4689.  
  4690.                         break;
  4691.  
  4692.                     case WINDOW_PACKET:
  4693.  
  4694.                         if(PacketWindow)
  4695.                             WindowToBack(PacketWindow);
  4696.  
  4697.                         break;
  4698.  
  4699.                     case WINDOW_FASTMACROS:
  4700.  
  4701.                         if(FastWindow)
  4702.                             WindowToBack(FastWindow);
  4703.  
  4704.                         break;
  4705.  
  4706.                     case WINDOW_STATUS:
  4707.  
  4708.                         if(InfoWindow)
  4709.                             WindowToBack(InfoWindow);
  4710.  
  4711.                         break;
  4712.  
  4713.                     case WINDOW_MAIN:
  4714.  
  4715.                         if(Window)
  4716.                             WindowToBack(Window);
  4717.  
  4718.                         break;
  4719.                 }
  4720.             }
  4721.  
  4722.             if(Index == WINDOW_REVIEW && ReviewWindow)
  4723.             {
  4724.                 if(Args[ARG_WINDOW_TOP])
  4725.                     MoveReview(REVIEW_MOVE_TOP);
  4726.  
  4727.                 if(Args[ARG_WINDOW_BOTTOM])
  4728.                     MoveReview(REVIEW_MOVE_BOTTOM);
  4729.  
  4730.                 if(Args[ARG_WINDOW_UP])
  4731.                     MoveReview(REVIEW_MOVE_UP);
  4732.  
  4733.                 if(Args[ARG_WINDOW_DOWN])
  4734.                     MoveReview(REVIEW_MOVE_DOWN);
  4735.             }
  4736.         }
  4737.     }
  4738.  
  4739.     return(NULL);
  4740. }
  4741.  
  4742. STRPTR __regargs
  4743. RexxRX(struct RexxPkt *Pkt)
  4744. {
  4745.     enum    {    ARG_RX_CONSOLE,ARG_RX_ASYNC,ARG_RX_COMMAND };
  4746.  
  4747.     struct MsgPort    *RexxPort;
  4748.     BYTE         Eaten = FALSE;
  4749.  
  4750.     if(RexxPort = FindPort(RXSDIR))
  4751.     {
  4752.         struct MsgPort __aligned     SinglePort;
  4753.         struct RexxMsg            *HostMessage;
  4754.  
  4755.         InitSinglePort(&SinglePort);
  4756.  
  4757.         if(HostMessage = CreateRexxMsg(&SinglePort,"term",RexxPortName))
  4758.         {
  4759.             if(HostMessage -> rm_Args[0] = CreateArgstring(Args[ARG_RX_COMMAND],strlen(Args[ARG_RX_COMMAND])))
  4760.             {
  4761.                 HostMessage -> rm_Action = RXCOMM;
  4762.  
  4763.                 if(!GoodStream(NULL))
  4764.                     HostMessage -> rm_Action |= RXFF_NOIO;
  4765.  
  4766.                 if(Args[ARG_RX_ASYNC])
  4767.                 {
  4768.                     RexxPktCleanup(Pkt,NULL);
  4769.  
  4770.                     Eaten = TRUE;
  4771.                 }
  4772.  
  4773.                 Forbid();
  4774.  
  4775.                 PutMsg(RexxPort,HostMessage);
  4776.  
  4777.                 SetSignal(0,SIGF_SINGLE);
  4778.  
  4779.                 WaitPort(&SinglePort);
  4780.  
  4781.                 Permit();
  4782.  
  4783.                 GetMsg(&SinglePort);
  4784.  
  4785.                 if(!Eaten)
  4786.                 {
  4787.                     Results[0] = HostMessage -> rm_Result1;
  4788.                     Results[1] = HostMessage -> rm_Result2;
  4789.                 }
  4790.             }
  4791.             else
  4792.             {
  4793.                 Results[0] = RC_ERROR;
  4794.                 Results[1] = ERR10_003;
  4795.             }
  4796.  
  4797.             DeleteRexxMsg(HostMessage);
  4798.         }
  4799.         else
  4800.         {
  4801.             Results[0] = RC_ERROR;
  4802.             Results[1] = ERR10_003;
  4803.         }
  4804.     }
  4805.     else
  4806.     {
  4807.         Results[0] = RC_ERROR;
  4808.         Results[1] = ERR10_013;
  4809.     }
  4810.  
  4811.     if(!Eaten)
  4812.         RexxPktCleanup(Pkt,NULL);
  4813.  
  4814.     return(NULL);
  4815. }
  4816.  
  4817. STRPTR __regargs
  4818. RexxExecTool(struct RexxPkt *Pkt)
  4819. {
  4820.     enum    {    ARG_EXECTOOL_CONSOLE,ARG_EXECTOOL_ASYNC,ARG_EXECTOOL_PORT,ARG_EXECTOOL_COMMAND };
  4821.  
  4822.     LONG     Error;
  4823.     UBYTE     CommandName[256],
  4824.          CommandArgs[256],
  4825.         *Index = Args[ARG_EXECTOOL_COMMAND];
  4826.     WORD     i;
  4827.     BYTE     Eaten = FALSE;
  4828.  
  4829.     while(*Index == ' ' || *Index == '\t')
  4830.         Index++;
  4831.  
  4832.     for(i = 0 ; Index[i] != ' ' && Index[i] != '\t' ; i++)
  4833.         CommandName[i] = Index[i];
  4834.  
  4835.     CommandName[i] = 0;
  4836.  
  4837.     Index += i;
  4838.  
  4839.     while(*Index == ' ' || *Index == '\t')
  4840.         Index++;
  4841.  
  4842.     if(Args[ARG_EXECTOOL_PORT])
  4843.         SPrintf(CommandArgs,"%s %s\n",Index,RexxPortName);
  4844.     else
  4845.         SPrintf(CommandArgs,"%s\n",Index);
  4846.  
  4847.     if(Args[ARG_EXECTOOL_ASYNC])
  4848.     {
  4849.         RexxPktCleanup(Pkt,NULL);
  4850.  
  4851.         Eaten = TRUE;
  4852.     }
  4853.  
  4854.     Error = SystemTags(CommandName,
  4855.         NP_Arguments,CommandArgs,
  4856.     TAG_DONE);
  4857.  
  4858.     if(!Eaten)
  4859.     {
  4860.         if(Error)
  4861.         {
  4862.             Results[0] = RC_ERROR;
  4863.             Results[1] = Error;
  4864.         }
  4865.  
  4866.         RexxPktCleanup(Pkt,NULL);
  4867.     }
  4868.  
  4869.     return(NULL);
  4870. }
  4871.