/**
 * Scout - The Amiga System Monitor
 *
 *------------------------------------------------------------------
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * You must not use this source code to gain profit of any kind!
 *
 *------------------------------------------------------------------
 *
 * @author Andreas Gelhausen
 * @author Richard Körber <rkoerber@gmx.de>
 */



#include "scout_arexx.h"
#include <libraries/commodities_private.h>

extern struct ExecBase  *SysBase;

/********************************************************************/
/*            Hilfsroutinen für die ARexx-Funktionen                */
/********************************************************************/
BOOL IsReal (char *text) {
   int   i = 0,punkte = 0;

   while (text[i]) {
      if (text[i] == '.') {
         if (punkte) {
            return (FALSE);
         }
         punkte++;
      } else if (! isdigit (text[i])) {
         return (FALSE);
      }
      i++;
   }
   return (TRUE);
}

BOOL IsHex (char *text, long *result) {
   int i = 0;

   if (text) {
      if (text[0] == '$')
         i = 1;
      else if (! strnicmp ("0x", text, 2))
         i = 2;
      else 
         return (FALSE);
      
      if (strlen (text + i) < 9) {
         *result = strtol (text + i, NULL, 16);
         return (TRUE);
      }
   }
   return (FALSE);
}

BOOL IsDec (char *text, long *result) {

   if ((text) && (strlen (text) < 9)) {
      *result = atol (text);
      return (TRUE);
   }
   return (FALSE);
}

/*
struct WinEntry *SearchWinEntry (UBYTE *title) {
   struct   WinEntry *winentry;

   GetWindows (&winentry);
   while (winentry) {
      if ((winentry->wn_type == 'S') && (! strcmp (((struct Screen *) winentry->wn_adr)->Title, title)))
         return (winentry);
      if (! stricmp (((struct Window *) winentry->wn_adr)->Title, title))
         return (winentry);
      winentry = winentry->wn_next;
   }
   return (NULL);
}
*/

/********************************************************************/
/*                        ARexx-Funktionen                          */
/********************************************************************/
__asm long printlist_rxfunc (register __a1 ULONG *arg) {

   if (arg[2])
      PrintHandleMode = MODE_OLDFILE;
   else
      PrintHandleMode = MODE_NEWFILE;

   if (stricmp ("L", (char *) arg[0]) == 0)
      PrintLibraries ((char *) arg[1]);
   else if (stricmp ("D", (char *) arg[0]) == 0)
      PrintDevices ((char *) arg[1]);
   else if (stricmp ("U", (char *) arg[0]) == 0)
      PrintResources ((char *) arg[1]);
   else if (stricmp ("T", (char *) arg[0]) == 0)
      PrintTasks ((char *) arg[1]);
   else if (stricmp ("P", (char *) arg[0]) == 0)
      PrintPorts ((char *) arg[1]);
   else if (stricmp ("C", (char *) arg[0]) == 0)
      PrintCommands ((char *) arg[1]);
   else if (stricmp ("X", (char *) arg[0]) == 0)
      PrintExpansions ((char *) arg[1]);
   else if (stricmp ("M", (char *) arg[0]) == 0)
      PrintMemory ((char *) arg[1]);
   else if (stricmp ("R", (char *) arg[0]) == 0)
      PrintResidents ((char *) arg[1]);
   else if (stricmp ("G", (char *) arg[0]) == 0)
      PrintAssigns ((char *) arg[1]);
   else if (stricmp ("O", (char *) arg[0]) == 0)
      PrintLocks ((char *) arg[1]);
   else if (stricmp ("N", (char *) arg[0]) == 0)
      PrintMounts ((char *) arg[1]);
   else if (stricmp ("H", (char *) arg[0]) == 0)
      PrintInputHandlers ((char *) arg[1]);
   else if (stricmp ("I", (char *) arg[0]) == 0)
      PrintInterrupts ((char *) arg[1]);
   else if (stricmp ("V", (char *) arg[0]) == 0)
      PrintVectors ((char *) arg[1]);
   else if (stricmp ("F", (char *) arg[0]) == 0)
      PrintFonts ((char *) arg[1]);
   else if (stricmp ("S", (char *) arg[0]) == 0)
      PrintSemaphores ((char *) arg[1]);
   else if (stricmp ("W", (char *) arg[0]) == 0)
      PrintWindows ((char *) arg[1]);
   else if (stricmp ("J", (char *) arg[0]) == 0)
      PrintLowMemory ((char *) arg[1]);
   else if (stricmp ("K", (char *) arg[0]) == 0)
      PrintCx ((char *) arg[1]);
   else if (stricmp ("Z", (char *) arg[0]) == 0)
      PrintSMode ((char *) arg[1]);
   else if (stricmp ("Y", (char *) arg[0]) == 0)
      PrintSystem ((char *) arg[1]);
   else if (stricmp ("A", (char *) arg[0]) == 0)
      PrintAllocations ((char *) arg[1]);
   else if (stricmp ("B", (char *) arg[0]) == 0)
      PrintClass ((char *) arg[1]);
   return (RETURN_OK);
}

static const struct Hook printlist_rxhook = {
   {NULL, NULL},
   (void *)printlist_rxfunc,
   NULL,NULL
};

__asm long findtask_rxfunc (register __a1 ULONG *arg) {
   struct   Task     *task;

   Forbid();
   if (task = MyFindTask ((char *) arg[0])) {
      if (SendResultString ("0x%08x", task))
         Permit();
         return (RETURN_OK);
   }
   Permit();
   return (RETURN_ERROR);
}

static const struct Hook findtask_rxhook = {
   {NULL, NULL},
   (void *)findtask_rxfunc,
   NULL,NULL
};

__asm long removetask_rxfunc (register __a1 ULONG *arg) {

   if (MyRemoveTask ((char *) arg[0]))
      return (RETURN_OK);
   else
      return (RETURN_ERROR);
}

static const struct Hook removetask_rxhook = {
   {NULL, NULL},
   (void *)removetask_rxfunc,
   NULL,NULL
};

__asm long freezetask_rxfunc (register __a1 ULONG *arg) {

   if (MyFreezeTask ((char *) arg[0]))
      return (RETURN_OK);
   else
      return (RETURN_ERROR);
}

static const struct Hook freezetask_rxhook = {
   {NULL, NULL},
   (void *)freezetask_rxfunc,
   NULL,NULL
};


__asm long activatetask_rxfunc (register __a1 ULONG *arg) {

   if (MyActivateTask ((char *) arg[0]))
      return (RETURN_OK);
   else
      return (RETURN_ERROR);
}

static const struct Hook activatetask_rxhook = {
   {NULL, NULL},
   (void *)activatetask_rxfunc,
   NULL,NULL
};

__asm long signaltask_rxfunc (register __a1 ULONG *arg) {

   if (MySignalTask ((char *) arg[0], (char *) arg[1]))
      return (RETURN_OK);
   else
      return (RETURN_ERROR);
}

static const struct Hook signaltask_rxhook = {
   {NULL, NULL},
   (void *)signaltask_rxfunc,
   NULL,NULL
};

__asm long breaktask_rxfunc (register __a1 ULONG *arg) {

   if (MySignalTask ((char *) arg[0], "0x1000"))
      return (RETURN_OK);
   else
      return (RETURN_ERROR);
}

static const struct Hook breaktask_rxhook = {
   {NULL, NULL},
   (void *)breaktask_rxfunc,
   NULL,NULL
};

__asm long settaskpri_rxfunc (register __a1 ULONG *arg) {
   struct   Task     *task;
   long     pri;

   Forbid();
   if ((task = MyFindTask ((char *) arg[0])) && (IsDec ((char *) arg[1], &pri))) {
      SetTaskPri (task, (int) pri);
      Permit();
      return (RETURN_OK);
   }
   Permit();
   return (RETURN_ERROR);
}

static const struct Hook settaskpri_rxhook = {
   {NULL, NULL},
   (void *)settaskpri_rxfunc,
   NULL,NULL
};

__asm long removeport_rxfunc (register __a1 ULONG *arg) {
   struct   MsgPort  *port;

   if (port = (struct MsgPort *) MyFindName ("PORT", (char *) arg[0])) {
      RemPort (port);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook removeport_rxhook = {
   {NULL, NULL},
   (void *)removeport_rxfunc,
   NULL,NULL
};

__asm long getlocknumber_rxfunc (register __a1 ULONG *arg) {

   GetLocks (SL_COUNT, (char *) arg[0], NULL);

   if (SendResultString ("%d", lockanzahl))
      return (RETURN_OK);
   return (RETURN_ERROR);
}

static const struct Hook getlocknumber_rxhook = {
   {NULL, NULL},
   (void *)getlocknumber_rxfunc,
   NULL,NULL
};

__asm long removelocks_rxfunc (register __a1 ULONG *arg) {

   GetLocks (SL_REMOVE, (char *) *arg, NULL);
   return (RETURN_OK);
}

static const struct Hook removelocks_rxhook = {
   {NULL, NULL},
   (void *)removelocks_rxfunc,
   NULL,NULL
};

__asm long removelock_rxfunc (register __a1 ULONG *arg) {
   long  nobptr;

   if (IsHex ((char *) arg[0], &nobptr)) {
      UnLock ((BPTR) nobptr>>2);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook removelock_rxhook = {
   {NULL, NULL},
   (void *)removelock_rxfunc,
   NULL,NULL
};

__asm long getpriority_rxfunc (register __a1 ULONG *arg) {
   long  address;

   if (IsHex ((char *) arg[0], &address)) {
      if (SendResultString ("%d", ((struct Node *) address)->ln_Pri))
         return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook getpriority_rxhook = {
   {NULL, NULL},
   (void *)getpriority_rxfunc,
   NULL,NULL
};

__asm long setpriority_rxfunc (register __a1 ULONG *arg) {
   struct   Node  *node;
   struct   List  *list;
   int      value;

   if ((list = MyGetList ((char *) arg[0])) \
     && (node = MyFindName ((char *) arg[0], (char *) arg[1]))) {

      value = (int) *(ULONG *) arg[2];
      if ((value < 128) && (value > -129)) {

         Remove (node);
         node->ln_Pri = value;
         Enqueue (list, node);

         return (RETURN_OK);
      }
   }
   return (RETURN_ERROR);
}

static const struct Hook setpriority_rxhook = {
   {NULL, NULL},
   (void *)setpriority_rxfunc,
   NULL,NULL
};

__asm long findnode_rxfunc (register __a1 ULONG *arg) {
   struct   Node  *node;

   if (node = MyFindName ((char *) arg[0], (char *) arg[1])) {
      if (SendResultString ("0x%08x", node))
         return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook findnode_rxhook = {
   {NULL, NULL},
   (void *)findnode_rxfunc,
   NULL,NULL
};

__asm long closelib_rxfunc (register __a1 ULONG *arg) {
   struct   Node  *node;

   if (node = MyFindName ("LIBRARY", (char *) arg[0])) {
      CloseLibrary ((struct Library *) node);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook closelib_rxhook = {
   {NULL, NULL},
   (void *)closelib_rxfunc,
   NULL,NULL
};

__asm long removelib_rxfunc (register __a1 ULONG *arg) {
   struct   Node  *node;

   if (node = MyFindName ("LIBRARY", (char *) arg[0])) {
      RemLibrary ((struct Library *) node);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook removelib_rxhook = {
   {NULL, NULL},
   (void *)removelib_rxfunc,
   NULL,NULL
};

__asm long removedev_rxfunc (register __a1 ULONG *arg) {
   struct   Node  *node;

   if (node = MyFindName ("DEVICE", (char *) arg[0])) {
      RemDevice ((struct Device *) node);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook removedev_rxhook = {
   {NULL, NULL},
   (void *)removedev_rxfunc,
   NULL,NULL
};

__asm long removeres_rxfunc (register __a1 ULONG *arg) {
   struct   Node  *node;

   if (node = MyFindName ("RESOURCE", (char *) arg[0])) {
      RemResource ((struct Library *) node);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook removeres_rxhook = {
   {NULL, NULL},
   (void *)removeres_rxfunc,
   NULL,NULL
};

__asm long obtainsem_rxfunc (register __a1 ULONG *arg) {
   struct   Node  *node;

   if (node = MyFindName ("SEMAPHORE", (char *) arg[0])) {
      ObtainSemaphore ((struct SignalSemaphore *) node);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook obtainsem_rxhook = {
   {NULL, NULL},
   (void *)obtainsem_rxfunc,
   NULL,NULL
};

__asm long releasesem_rxfunc (register __a1 ULONG *arg) {
   struct   Node  *node;

   if ((node = MyFindName ("SEMAPHORE", (char *) arg[0])) \
      && (((struct SignalSemaphore *) node)->ss_NestCount)) {
      ReleaseSemaphore ((struct SignalSemaphore *) node);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook releasesem_rxhook = {
   {NULL, NULL},
   (void *)releasesem_rxfunc,
   NULL,NULL
};

__asm long removesem_rxfunc (register __a1 ULONG *arg) {
   struct   Node  *node;

   if (node = MyFindName ("SEMAPHORE", (char *) arg[0])) {
      RemSemaphore ((struct SignalSemaphore *) node);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook removesem_rxhook = {
   {NULL, NULL},
   (void *)removesem_rxfunc,
   NULL,NULL
};

__asm long removeinput_rxfunc (register __a1 ULONG *arg) {
   struct   Node  *node;

   if (node = MyFindName ("INPUTHANDLER", (char *) arg[0])) {
      InputIORequest.io_Command = IND_REMHANDLER;
      InputIORequest.io_Data = (void *) node;
      SendIO ((struct IORequest *) &InputIORequest);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook removeinput_rxhook = {
   {NULL, NULL},
   (void *)removeinput_rxfunc,
   NULL,NULL
};

__asm long removelowmemory_rxfunc (register __a1 ULONG *arg) {
   struct Interrupt *intr;

   if (intr = (struct Interrupt *)MyFindName ("LOWMEMORY", (char *) arg[0])) {
      if (SysBase->LibNode.lib_Version >= 39)
         RemMemHandler(intr);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook removelowmemory_rxhook = {
   {NULL, NULL},
   (void *)removelowmemory_rxfunc,
   NULL,NULL
};

/*
__asm long causelowmem_rxfunc (register __a1 ULONG *arg) {
   struct Interrupt *intr;
   struct MemHandlerData mhd = {1000,MEMF_ANY,0};

   if (intr = (struct Interrupt *)MyFindName ("LOWMEMORY", (char *) arg[0])) {
      MyCause(intr,&mhd);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook causelowmem_rxhook = {
   {NULL, NULL},
   (void *)causelowmem_rxfunc,
   NULL,NULL
};
*/

__asm long findresident_rxfunc (register __a1 ULONG *arg) {
   struct   Resident *resi;

   if (resi = FindResident ((char *) arg[0])) {
      if (SendResultString ("0x%08x", resi))
         return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook findresident_rxhook = {
   {NULL, NULL},
   (void *)findresident_rxfunc,
   NULL,NULL
};

__asm long findinterrupt_rxfunc (register __a1 ULONG *arg) {
   struct   Interrupt   *intr;

   if (intr = GetInterrupts (SI_FIND, (char *) arg[0], NULL)) {
      if (SendResultString ("0x%08x", intr))
         return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook findinterrupt_rxhook = {
   {NULL, NULL},
   (void *)findinterrupt_rxfunc,
   NULL,NULL
};

__asm long removeinterrupt_rxfunc (register __a1 ULONG *arg) {
   struct Interrupt *intr;
   
   if (intr = GetInterrupts (SI_REMOVE, (char *) arg[0], NULL)) {
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook removeinterrupt_rxhook = {
   {NULL, NULL},
   (void *)removeinterrupt_rxfunc,
   NULL,NULL
};

__asm long removeclass_rxfunc (register __a1 ULONG *arg) {
   struct IClass *node;
   BOOL ret;

   if (node = (struct IClass *)MyFindName ("CLASSES", (char *) arg[0])) {
      if((!node->cl_ObjectCount) && (!node->cl_SubclassCount))
      {
        ret = FreeClass((struct IClass *)node);
        return (ret ? RETURN_OK : RETURN_ERROR);
      }
   }
   return (RETURN_ERROR);
}

static const struct Hook removeclass_rxhook = {
   {NULL, NULL},
   (void *)removeclass_rxfunc,
   NULL,NULL
};


__asm long flushdevs_rxfunc (register __a1 ULONG *arg) {
   FlushDevices();
   return (RETURN_OK);
}

static const struct Hook flushdevs_rxhook = {
   {NULL, NULL},
   (void *)flushdevs_rxfunc,
   NULL,NULL
};

__asm long flushfonts_rxfunc (register __a1 ULONG *arg) {
   FlushFonts();
   return (RETURN_OK);
}

static const struct Hook flushfonts_rxhook = {
   {NULL, NULL},
   (void *)flushfonts_rxfunc,
   NULL,NULL
};

__asm long flushlibs_rxfunc (register __a1 ULONG *arg) {
   FlushLibraries();
   return (RETURN_OK);
}

static const struct Hook flushlibs_rxhook = {
   {NULL, NULL},
   (void *)flushlibs_rxfunc,
   NULL,NULL
};

__asm long flushall_rxfunc (register __a1 ULONG *arg) {
   FlushDevices();
   FlushFonts();
   FlushLibraries();
   return (RETURN_OK);
}

static const struct Hook flushall_rxhook = {
   {NULL, NULL},
   (void *)flushall_rxfunc,
   NULL,NULL
};

__asm long clearreset_rxfunc (register __a1 ULONG *arg) {
   ClearResetVectors();
   return (RETURN_OK);
}

static const struct Hook clearreset_rxhook = {
   {NULL, NULL},
   (void *)clearreset_rxfunc,
   NULL,NULL
};

__asm long poptofront_rxfunc (register __a1 ULONG *arg) {
   struct   Window   *window;
   struct   Screen   *screen;
   
   if (screen = MyFindScreen ((char *) arg[0])) {
      ScreenToFront (screen);
      return (RETURN_OK);
   } else if (window = MyFindWindow ((char *) arg[0])) {
      WindowToFront (window);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook poptofront_rxhook = {
   {NULL, NULL},
   (void *)poptofront_rxfunc,
   NULL,NULL
};

__asm long closewindow_rxfunc (register __a1 ULONG *arg) {
   struct   Window   *window;

   if (window = MyFindWindow ((char *) arg[0])) {
      CloseWindow (window);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook closewindow_rxhook = {
   {NULL, NULL},
   (void *)closewindow_rxfunc,
   NULL,NULL
};

__asm long closescreen_rxfunc (register __a1 ULONG *arg) {
   struct   Screen   *screen;

   if (screen = MyFindScreen ((char *) arg[0])) {
      CloseScreenAll (screen);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook closescreen_rxhook = {
   {NULL, NULL},
   (void *)closescreen_rxfunc,
   NULL,NULL
};

__asm long closefont_rxfunc (register __a1 ULONG *arg) {
   struct TextFont *font;

   if (IsHex ((char *) arg[0], (long *) &font)) {
      CloseFont (font);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook closefont_rxhook = {
   {NULL, NULL},
   (void *)closefont_rxfunc,
   NULL,NULL
};

__asm long removefont_rxfunc (register __a1 ULONG *arg) {
   struct TextFont *font;

   if (IsHex ((char *) arg[0], (long *) &font)) {
      RemFont (font);
      Remove ((struct Node *) font);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook removefont_rxhook = {
   {NULL, NULL},
   (void *)removefont_rxfunc,
   NULL,NULL
};

__asm long removecommand_rxfunc (register __a1 ULONG *arg) {
   struct   Segment *seg;

   if ((IsHex ((char *) arg[0], (long *) &seg)) && (RemSegment (seg))) {
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook removecommand_rxhook = {
   {NULL, NULL},
   (void *)removecommand_rxfunc,
   NULL,NULL
};

__asm long removeassign_rxfunc (register __a1 ULONG *arg) {

   if (AssignLock ((char *) arg[0], NULL)) {
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}

static const struct Hook removeassign_rxhook = {
   {NULL, NULL},
   (void *)removeassign_rxfunc,
   NULL,NULL
};

__asm long removeassignlist_rxfunc (register __a1 ULONG *arg) {
   BPTR  address;

   if (IsHex ((char *) arg[1], (long *) &address)) {
      if (RemAssignList ((char *) arg[0], address)) {
         return (RETURN_OK);
      }
   }
   return (RETURN_ERROR);
}

static const struct Hook removeassignlist_rxhook = {
   {NULL, NULL},
   (void *)removeassignlist_rxfunc,
   NULL,NULL
};

char  *WindowTexte[] = { AssignsText,DevicesText,CommandsText,
                         ExpansionsText,FontsText,InputHandlersText,
                         InterruptsText,LibrariesText,LocksText,
                         MemoryText,MountText,PortsText,
                         ResidentsText,ResourcesText,SemaphoresText,
                         TasksText,VectorsText,WindowsText,
                         CommoditiesText,LowMemoryText,SystemText,ScreenModeText,ClassesText,
                         AllocationsText,TimerText,NULL
                       };

BYTE  WindowIDs[] = { ID_ASSIGNS,ID_DEVICES,ID_COMMANDS,
                      ID_EXPANSIONS,ID_FONTS,ID_INPUTHANDLER,
                      ID_INTERRUPTS,ID_LIBRARIES,ID_LOCKS,
                      ID_MEMORY,ID_MOUNT,ID_PORTS,
                      ID_RESIDENTS,ID_RESOURCES,ID_SEMAPHORES,
                      ID_TASKS,ID_VECTORS,ID_WINDOWS,
                      ID_COMMODITIES,ID_LOWMEMORY,ID_SYSTEM,
                      ID_SCREENMODE, ID_CLASSES, ID_ALLOCATIONS, ID_TIMER
                    };

__asm long openwindow_rxfunc (register __a1 ULONG *arg) {
   int i = 0;

   if (AP_Scout) {
      while (WindowTexte[i]) {
         if (! stricmp ((char *) *arg, WindowTexte[i])) {

            DoMethod (AP_Scout,MUIM_Application_ReturnID,WindowIDs[i]);
            return (RETURN_OK);
         }
         i++;
      }
   }
   return (RETURN_ERROR);
}

static const struct Hook openwindow_rxhook = {
   {NULL, NULL},
   (void *)openwindow_rxfunc,
   NULL,NULL
};



__asm long cxappear_rxfunc (register __a1 ULONG *arg) {
   return(BrokerCommand((char *) arg[0], CXCMD_APPEAR ) ? RETURN_ERROR : RETURN_OK);
}
static const struct Hook cxappear_rxhook = {
   {NULL, NULL},
   (void *)cxappear_rxfunc,
   NULL,NULL
};

__asm long cxdisappear_rxfunc (register __a1 ULONG *arg) {
   return(BrokerCommand((char *) arg[0], CXCMD_DISAPPEAR ) ? RETURN_ERROR : RETURN_OK);
}
static const struct Hook cxdisappear_rxhook = {
   {NULL, NULL},
   (void *)cxdisappear_rxfunc,
   NULL,NULL
};

__asm long cxenable_rxfunc (register __a1 ULONG *arg) {
   return(BrokerCommand((char *) arg[0], CXCMD_ENABLE ) ? RETURN_ERROR : RETURN_OK);
}
static const struct Hook cxenable_rxhook = {
   {NULL, NULL},
   (void *)cxenable_rxfunc,
   NULL,NULL
};

__asm long cxdisable_rxfunc (register __a1 ULONG *arg) {
   return(BrokerCommand((char *) arg[0], CXCMD_DISABLE ) ? RETURN_ERROR : RETURN_OK);
}
static const struct Hook cxdisable_rxhook = {
   {NULL, NULL},
   (void *)cxdisable_rxfunc,
   NULL,NULL
};

__asm long cxkill_rxfunc (register __a1 ULONG *arg) {
   return(BrokerCommand((char *) arg[0], CXCMD_KILL ) ? RETURN_ERROR : RETURN_OK);
}
static const struct Hook cxkill_rxhook = {
   {NULL, NULL},
   (void *)cxkill_rxfunc,
   NULL,NULL
};

__asm long cxlistchg_rxfunc (register __a1 ULONG *arg) {
   return(BrokerCommand((char *) arg[0], CXCMD_LIST_CHG ) ? RETURN_ERROR : RETURN_OK);
}
static const struct Hook cxlistchg_rxhook = {
   {NULL, NULL},
   (void *)cxlistchg_rxfunc,
   NULL,NULL
};

__asm long cxunique_rxfunc (register __a1 ULONG *arg) {
   return(BrokerCommand((char *) arg[0], CXCMD_UNIQUE ) ? RETURN_ERROR : RETURN_OK);
}
static const struct Hook cxunique_rxhook = {
   {NULL, NULL},
   (void *)cxunique_rxfunc,
   NULL,NULL
};

__asm long removecx_rxfunc (register __a1 ULONG *arg) {
   struct   Node  *node;

   if (node = MyFindName ("COMMODITIES", (char *) arg[0])) {
      RemoveCxObj((CxObj *)node);
      return (RETURN_OK);
   }
   return (RETURN_ERROR);
}
static const struct Hook removecx_rxhook = {
   {NULL, NULL},
   (void *)removecx_rxfunc,
   NULL,NULL
};

__asm long setcxpri_rxfunc (register __a1 ULONG *arg) {
   struct   Node  *node;
   long     pri;

   if ((node = MyFindName ("COMMODITIES", (char *) arg[0])) && (IsDec ((char *) arg[1], &pri))) {
      if((pri>=-128) && (pri<=127)) {
        struct List *list = MyGetList("COMMODITIES");
        Forbid();
        Remove(node);
        node->ln_Pri = pri;
        Enqueue(list,node);
        Permit();
        return (RETURN_OK);
      }
   }
   return (RETURN_ERROR);
}
static const struct Hook setcxpri_rxhook = {
   {NULL, NULL},
   (void *)setcxpri_rxfunc,
   NULL,NULL
};


struct MUI_Command arexx_list[] = {
   {"PrintList"         , "LIST/A,FILENAME/A,APPEND/S", 3, &printlist_rxhook },
   {"FindTask"          , "NAME=ADDRESS/A"           , 1, &findtask_rxhook },
   {"FreezeTask"        , "NAME=ADDRESS/A"           , 1, &freezetask_rxhook },
   {"ActivateTask"      , "NAME=ADDRESS/A"           , 1, &activatetask_rxhook },
   {"RemoveTask"        , "NAME=ADDRESS/A"           , 1, &removetask_rxhook },
   {"BreakTask"         , "NAME=ADDRESS/A"           , 1, &breaktask_rxhook },
   {"SignalTask"        , "NAME=ADDRESS/A,HEXSIGNAL/A", 2, &signaltask_rxhook },
   {"SetTaskPri"        , "NAME=ADDRESS/A,PRIORITY/A", 2, &settaskpri_rxhook },
   {"RemovePort"        , "NAME=ADDRESS/A"           , 1, &removeport_rxhook },
   {"GetLockNumber"     , "LOCKPATTERN/F"            , 1, &getlocknumber_rxhook },
   {"RemoveLocks"       , "LOCKPATTERN/F"            , 1, &removelocks_rxhook },
   {"RemoveLock"        , "ADDRESS/A"                , 1, &removelock_rxhook },
   {"GetPriority"       , "ADDRESS/A"                , 1, &getpriority_rxhook },
   {"SetPriority"       , "TYPE/A,NAME=ADDRESS/A,PRIORITY/N", 3, &setpriority_rxhook },
   {"FindNode"          , "TYPE/A,NAME=ADDRESS/A"    , 2, &findnode_rxhook },
   {"CloseLibrary"      , "NAME=ADDRESS/A"           , 1, &closelib_rxhook },
   {"RemoveLibrary"     , "NAME=ADDRESS/A"           , 1, &removelib_rxhook },
   {"RemoveDevice"      , "NAME=ADDRESS/A"           , 1, &removedev_rxhook },
   {"RemoveResource"    , "NAME=ADDRESS/A"           , 1, &removeres_rxhook },
   {"ObtainSemaphore"   , "NAME=ADDRESS/A"           , 1, &obtainsem_rxhook },
   {"ReleaseSemaphore"  , "NAME=ADDRESS/A"           , 1, &releasesem_rxhook },
   {"RemoveSemaphore"   , "NAME=ADDRESS/A"           , 1, &removesem_rxhook },
   {"RemoveInputhandler", "NAME=ADDRESS/A"           , 1, &removeinput_rxhook },
   {"RemoveLowMemory"   , "NAME=ADDRESS/A"           , 1, &removelowmemory_rxhook },
   {"FindResident"      , "NAME=ADDRESS/A"           , 1, &findresident_rxhook },
   {"FindInterrupt"     , "NAME/A"                   , 1, &findinterrupt_rxhook },
   {"RemoveInterrupt"   , "NAME/A"                   , 1, &removeinterrupt_rxhook },
   {"FlushDevs"         , NULL                       , 0, &flushdevs_rxhook },
   {"FlushFonts"        , NULL                       , 0, &flushfonts_rxhook },
   {"FlushLibs"         , NULL                       , 0, &flushlibs_rxhook },
   {"FlushAll"          , NULL                       , 0, &flushall_rxhook },
   {"ClearResetVectors" , NULL                       , 0, &clearreset_rxhook },
   {"PopToFront"        , "TITLE=ADDRESS/A"          , 1, &poptofront_rxhook },
   {"CloseWindow"       , "TITLE=ADDRESS/A"          , 1, &closewindow_rxhook },
   {"CloseScreen"       , "TITLE=ADDRESS/A"          , 1, &closescreen_rxhook },
   {"CloseFont"         , "ADDRESS/A"                , 1, &closefont_rxhook },
   {"RemoveFont"        , "ADDRESS/A"                , 1, &removefont_rxhook },
   {"RemoveCommand"     , "ADDRESS/A"                , 1, &removecommand_rxhook },
   {"RemoveAssign"      , "NAME/A"                   , 1, &removeassign_rxhook },
   {"RemoveAssignList"  , "NAME/A,ADDRESS/A"         , 2, &removeassignlist_rxhook },
   {"OpenWindow"        , "WINDOWID/F"               , 1, &openwindow_rxhook },
   {"CxAppear"          , "NAME/A"                   , 1, &cxappear_rxhook },
   {"CxDisappear"       , "NAME/A"                   , 1, &cxdisappear_rxhook },
   {"CxEnable"          , "NAME/A"                   , 1, &cxenable_rxhook },
   {"CxDisable"         , "NAME/A"                   , 1, &cxdisable_rxhook },
   {"CxKill"            , "NAME/A"                   , 1, &cxkill_rxhook },
   {"CxListChg"         , "NAME/A"                   , 1, &cxlistchg_rxhook },
   {"CxUnique"          , "NAME/A"                   , 1, &cxunique_rxhook },
   {"RemoveCx"          , "NAME=ADDRESS/A"           , 1, &removecx_rxhook },
   {"SetCxPri"          , "NAME=ADDRESS/A,PRIORITY/A", 2, &setcxpri_rxhook },
//*   {"CauseLowMemory"    , "NAME=ADDRESS/A"           , 1, &causelowmem_rxhook },
   {"RemoveClass"       , "NAME/A"                   , 1, &removeclass_rxhook },
   { NULL, NULL, NULL, NULL }
};

char *FindMyARexxPort (char *name) {
   struct   MsgPort  *port;
   struct   Task     *task;
   int      i;

   task = FindTask (NULL);
   for (i = 0; i < 10; i++) {
      sprintf (tmpstr, "%s.%d", name, i);
      Forbid();
      if ((port = FindPort (tmpstr)) && (port->mp_SigTask == task)) {
         Permit();
         return (port->mp_Node.ln_Name);
      }
      Permit();
   }
   return (NULL);
}

ULONG SafePutToPort(struct Message *message, STRPTR portname) {
   struct MsgPort *port;

   Forbid();
   if (port = FindPort(portname))
      PutMsg (port,message);
   Permit();
   return ((ULONG) port); /* If zero, the port has gone away */
}

short SendStartupMsg (char *PortName,char *RString,BOOL IsFileName) {
   register struct   RexxMsg  *rmsg = NULL;
   register short    flag = FALSE;

   char     *buffer = NULL;
   ULONG    buflen;

   if ((RString) && (rmsg = CreateRexxMsg(&ScoutPort,NULL,PortName))) {

      rmsg->rm_Action = (RXCOMM|RXFF_STRING);

      if (IsFileName) {
         buflen = strlen (RString) + 4;

         if (buffer = AllocMem (buflen,MEMF_ANY)) {
            /*
             * Fill in the hostname and the command
             */
            sprintf (buffer, "'%s'", RString);

            rmsg->rm_Args[0] = CreateArgstring (buffer, buflen);
         }
      } else {          
         rmsg->rm_Args[0] = CreateArgstring (RString,(LONG) strlen (RString));
      }

      if (rmsg->rm_Args[0]) {
         if (SafePutToPort ((struct Message *) rmsg, RXSDIR)) {
            flag=TRUE;
         } else {
            DeleteArgstring (rmsg->rm_Args[0]);
            DeleteRexxMsg (rmsg);
         }
      } else {
            DeleteRexxMsg (rmsg);
      }

      if (buffer) {
         FreeMem (buffer,buflen);
      }
   }
   return (flag);
}


/********************************************************************/
/*         Neue Hilfsroutinen für die ARexx-Funktionen              */
/********************************************************************/

struct Task *MyFindTask (char *stask) {
   struct   Task  *lauf, *task, *result = NULL;

   if (IsHex (stask, (long *) &task)) {
      Forbid();

      lauf = FIRSTTASKREADY;
      while ((! result) && (lauf->tc_Node.ln_Succ != 0)) {
         if (task == lauf)
            result = lauf;
         lauf = (struct Task *) lauf->tc_Node.ln_Succ;
      }

      lauf = FIRSTTASKWAIT;
      while ((! result) && (lauf->tc_Node.ln_Succ != 0)) {
         if (task == lauf)
            result = lauf;
         lauf = (struct Task *) lauf->tc_Node.ln_Succ;
      }
      Permit();

      if ((! result) && (task == FindTask (NULL)))
         result = task;

   } else {
      Forbid();

      lauf = FIRSTTASKREADY;
      while ((! result) && (lauf->tc_Node.ln_Succ != 0)) {
         if (stricmp (stask, GetTaskName (lauf)) == 0) 
            result = lauf;
   
         lauf = (struct Task *) lauf->tc_Node.ln_Succ;
      }

      lauf = FIRSTTASKWAIT;
      while ((! result) && (lauf->tc_Node.ln_Succ != 0)) {
         if (stricmp (stask, GetTaskName (lauf)) == 0) 
            result = lauf;
   
         lauf = (struct Task *) lauf->tc_Node.ln_Succ;
      }
      Permit();

      if ((! result) && (stricmp (stask, GetTaskName (lauf = FindTask (NULL))) == 0)) 
         result = lauf;
   }
   return (result);
}

BOOL MyRemoveTask (char *stask) {
   struct   Task     *task;
//   struct   MsgPort  *port, *nextport;
//   struct   Window   *window, *nextwindow;
//   struct   Screen   *screen, *nextscreen;
//   struct   SignalSemaphore   *sem, *nextsem;
//   BOOL     allwins;

   Forbid();
   if (task = MyFindTask (stask)) {

/* Wegen groben Unfugs gestrichen!

      if (MyFreezeTask (stask) && withports) {
         port = FIRSTPORT;
         while (port) {
            nextport = (struct MsgPort *) port->mp_Node.ln_Succ;
            if (port->mp_SigTask == task) {
               RemPort (port);
            }
            port = nextport;
         }


         sem = FIRSTSEMAPHORE;
         while (nextsem = (struct SignalSemaphore *) sem->ss_Link.ln_Succ) {

            if (sem->ss_Owner == task) {
               int tmpint = sem->ss_NestCount;
               while (tmpint-- > 0) {
                  ReleaseSemaphore (sem);
               }
            }
            sem = nextsem;
         }

         screen = FIRSTSCREEN;
         while (screen) {
            nextscreen = screen->NextScreen;

            if (window = screen->FirstWindow) {
               allwins = TRUE;

               while (window) {
                  nextwindow = window->NextWindow;

                  if (window->UserPort->mp_SigTask == task) {
                     CloseWindow (window);
                  } else {
                     allwins = FALSE;
                  }
                  window = nextwindow;
               }
            }

            if (allwins && !screen->FirstWindow)
               CloseScreen (screen);

            screen = nextscreen;
         }
      }
*/
      RemTask (task);
      Permit();
      return (TRUE);
   }
   Permit();
   return (FALSE);
}

BOOL MyFreezeTask (char *stask) {
   struct   Task     *task;

   Forbid();
   if (task = MyFindTask (stask)) {
      Remove ((struct Node *) task);
      task->tc_State = (BYTE) TS_FROZEN;
      Enqueue ((struct List *) &SysBase->TaskWait, (struct Node *) task);
      Permit();
      return (TRUE);
   }
   Permit();
   return (FALSE);
}

BOOL MyActivateTask (char *stask) {
   struct   Task     *task;

   Forbid();
   if (task = MyFindTask (stask)) {
      Remove ((struct Node *) task);
      task->tc_State = (BYTE) TS_READY;
      Enqueue ((struct List *) &SysBase->TaskReady, (struct Node *) task);
      Permit();
      return (TRUE);
   }
   Permit();
   return (FALSE);
}

BOOL MySignalTask (char *stask, char *ssignal) {
   struct   Task     *task;
   long     signal;

   Forbid();
   if ((task = MyFindTask (stask)) && (IsHex (ssignal, &signal))) {
      Signal (task, signal);
      Permit();
      return (TRUE);
   }
   Permit();
   return (FALSE);
}

static char *nodetype[] = {
   "LIBRARY", "DEVICE", "RESOURCE", "MEMORY", "SEMAPHORE", 
   "PORT", "INPUTHANDLER", "LOWMEMORY", "COMMODITIES", "CLASSES", NULL
};

struct List *MyGetList (char *type) {
   int      i = 0;
   char     *tmp;
   struct   List  *list = NULL;

   while (nodetype[i]) {
      if (! stricmp (nodetype[i], type)) {
         switch (i) {
            case 0:
               list = &SysBase->LibList;
               break;
            case 1:
               list = &SysBase->DeviceList;
               break;
            case 2:
               list = &SysBase->ResourceList;
               break;
            case 3:
               list = &SysBase->MemList;
               break;
            case 4:
               list = &SysBase->SemaphoreList;
               break;
            case 5:
               list = &SysBase->PortList;
               break;
            case 6:
               if (list = (struct List *) FindName (&SysBase->DeviceList, INPUT_DEVNAME)) {
                  tmp = (char *) list;
                  tmp += 148;    /* Mir unbekannter Offsetname! */
                  list = (struct List *) ((struct Node *) tmp)->ln_Succ;
               }
               break;
            case 7:
               if (SysBase->LibNode.lib_Version >= 39)
                 list = (struct List *)&SysBase->ex_MemHandlers;
               else
                 list = NULL;
               break;
            case 8:
               {
                  struct MsgPort *cxport;
                  struct NewBroker cxnewbroker =
                  {
                    NB_VERSION,
                    "« Scout Dummy »",
                    "« Scout Dummy »",
                    "Dummy Broker",
                    0,
                    0,
                    0,
                    NULL,
                    0
                  };
                  struct Node *cxbroker;
                  struct Node *broker;

                  if(cxport = CreateMsgPort()) {
                     cxnewbroker.nb_Port = cxport;
                     if(cxbroker = (struct Node *)CxBroker(&cxnewbroker,NULL)) {
                          Forbid();
                          for(broker=cxbroker; broker->ln_Pred; broker=broker->ln_Pred);   /* Search the list head */
                          list = (struct List *)broker;
                          Permit();
                        DeleteCxObjAll((CxObj *)cxbroker);
                     }
                     DeleteMsgPort(cxport);
                  }
               }
               break;
            case 9:
               {
                  struct IClass *myclass = MakeClass("« Scout Dummy Class »","rootclass",NULL,0,0);
                  struct Node *clist;
                  if(myclass) {
                     AddClass(myclass);
                     Forbid();
                        for(clist=(struct Node *)&myclass->cl_Dispatcher.h_MinNode; clist->ln_Pred; clist=clist->ln_Pred);   /* Search the list head */
                        list = (struct List *)clist;
                     Permit();
                     FreeClass(myclass);
                  }
               }
               break;
          }
      }
      i++;
   }
   return (list);
}

struct Node *MyFindName (char *type, char *sname) {
   struct   List  *list = NULL;
   struct   Node  *lauf, *node = NULL, *result = NULL;

   if (list = MyGetList (type)) {
      if (IsHex (sname, (long *) &node)) {
         Forbid();

         lauf = list->lh_Head;
         while (lauf->ln_Succ != 0) {
            if (node == lauf) {
               result = lauf;
               break;
            }
            lauf = lauf->ln_Succ;
         }

         Permit();
      } else {
         result = FindName (list, sname);
      }
   }
   return (result);
}

struct Screen *MyFindScreen (char *sname) {
   struct   Screen   *screen = NULL, *lauf;

   lauf = FIRSTSCREEN;
   IsHex (sname, (long *) &screen);
   
   while (lauf) {
      if (screen) {
         if (lauf == screen)
            return (lauf);
      } else {
         if (stricmp (sname, nonetest (lauf->Title)) == 0)
            return (lauf);
      }
      lauf = lauf->NextScreen;
   }
   return (NULL);
}

struct Window *MyFindWindow (char *sname) {
   struct   Window   *window, *lauf;
   struct   Screen   *screen;

   screen = FIRSTSCREEN;
   IsHex (sname, (long *) &window);
   
   while (screen) {
      lauf = screen->FirstWindow;

      while (lauf) {
         if (window) {
            if (lauf == window)
               return (lauf);
         } else {
            if (stricmp (sname, nonetest (lauf->Title)) == 0)
               return (lauf);
         }
         lauf = lauf->NextWindow;
      }
      screen = screen->NextScreen;
   }
   return (NULL);
}
