/*
***************************************************************************
*
* Datei:
*    RSysExecLists.c
*
* Inhalt:
*    void MakeLibList(void);
*    void MakeResList(void);
*    void MakeIntrList(void);
*    void MakePortList(void);
*    void MakeTaskList(void);
*    void SysSemaphoreList(void);
*    void SysVectorList(void);
*    void SysSoftDeviceList(void);
*
* Bemerkungen:
*    Erzeugung von EXEC-Listen (Tasks, Ports, Libraries etc.).
*
* Erstellungsdatum:
*    07-Jul-93    Rolf Böhme
*
* Änderungen:
*    07-Jul-93    Rolf Böhme    Erstellung
*
***************************************************************************
*/

#include "RSysDebug.h"
#include "RSysFunc.h"

   /*
    * MakeLibList() erzeugt eine Liste aus allen im System
    * angemeldeten Libraries.
    */
void
MakeLibList(void)
{
   struct Node *node;
   struct Library *lib;
   int   i = 0;

   DPOS;

   countentries = CountNodes(&SysBase->LibList);

   if (NoEntries())
      return;

   Entries = AllocScrollEntries(countentries);

   Forbid();

   for (node = SysBase->LibList.lh_Head;
        node->ln_Succ && (i < countentries); node = node->ln_Succ)
   {
      lib = (struct Library *) node;

      Entries[i].se_obj_id.address = lib;
      savestrcpy(Entries[i].se_obj_id.fullname, node,
                 MAXFULLNAME - 1, NT_LIBRARY);

      sprintf(Entries[i].se_Entry, EntryAttr[LIBRARIES].ea_dataformat,
              Entries[i].se_obj_id.fullname,
              lib->lib_Version,
              lib->lib_Revision,
              lib->lib_OpenCnt,
              (lib->lib_OpenCnt ? '*' : ' '));

      i++;
   }

   countentries = i;

   Permit();

   CreateEntryList(SORT);

   return;
}

   /*
    * MakeResList() erzeugt eine Liste der Ressourcen, die
    * in der ExecBase eingetragen sind
    */
void
MakeResList(void)
{
   struct Node *node;
   struct Library *lib;
   int   i;

   DPOS;

   countentries = CountNodes(&SysBase->ResourceList);

   if (NoEntries())
      return;

   Entries = AllocScrollEntries(countentries);

   Forbid();

   i = 0;

   for (node = SysBase->ResourceList.lh_Head;
        node->ln_Succ && (i < countentries); node = node->ln_Succ)
   {
      lib = (struct Library *) node;

      Entries[i].se_obj_id.address = lib;
      savestrcpy(Entries[i].se_obj_id.fullname, node,
                 MAXFULLNAME - 1, NT_RESOURCE);

      sprintf(Entries[i].se_Entry, EntryAttr[RESOURCES].ea_dataformat,
              Entries[i].se_obj_id.fullname,
              lib->lib_Version,
              lib->lib_Revision,
              lib->lib_OpenCnt);

      i++;
   }

   countentries = i;

   Permit();

   CreateEntryList(SORT);

   return;
}

   /*
    * MakeIntrList() listet alle 16 Interrupts auf, die vom System
    * verwaltet werden können
    */
void
MakeIntrList(void)
{
   struct Node *node;
   int   i;

   DPOS;

   countentries = 16;

   Entries = AllocScrollEntries(countentries);

   Disable();

   for (i = 0; i < countentries; i++)
   {
      node = SysBase->IntVects[i].iv_Node;

      if (node)
      {
         savestrcpy(Entries[i].se_obj_id.fullname, node,
                    MAXFULLNAME - 1, NT_INTERRUPT);

         sprintf(Entries[i].se_Entry, EntryAttr[INTERRUPTS].ea_dataformat,
                 Entries[i].se_obj_id.fullname,
                 node->ln_Pri,
                 (long)((struct Interrupt *) node)->is_Data,
                 (long)(((struct Interrupt *) node)->is_Code));
      }
      else
         sprintf(Entries[i].se_Entry, EntryAttr[INTERRUPTS].ea_dataformat,
                 "<no node>", 0, 0L, 0L);
   }

   Enable();

   CreateEntryList(NO_SORT);

   return;
}

   /*
    * MakePortList() erzeugt eine Liste der im System angemeldeten
    * öffentlichen Ports
    */
void
MakePortList(void)
{
   struct Node *node;
   struct Task *task;
   struct MsgPort *port;
   char sigtask[16];
   int   i = 0;

   DPOS;

   countentries = CountNodes(&SysBase->PortList);

   if (NoEntries())
      return;

   Entries = AllocScrollEntries(countentries);

   Forbid();

   for (node = SysBase->PortList.lh_Head;
        node->ln_Succ && (i < countentries); node = node->ln_Succ)
   {
      Entries[i].se_obj_id.address = node;
      savestrcpy(Entries[i].se_obj_id.fullname, node,
                 MAXFULLNAME - 1, NT_MSGPORT);

      port = (struct MsgPort *)node;
      task = (struct Task *) port->mp_SigTask;
      if (task)
         savestrcpy(sigtask, &(task->tc_Node), 15, NT_TASK);
      else
         strcpy(sigtask, field[NO_TASK]);

      sprintf(Entries[i].se_Entry, EntryAttr[PORTS].ea_dataformat,
              Entries[i].se_obj_id.fullname,
              sigtask, node->ln_Pri);

      i++;
   }

   countentries = i;

   Permit();

   CreateEntryList(SORT);

   return;
}


   /*
    * CopyTaskNode() kopiert die Daten eines Tasks in eine interne
    * Listenstruktur
    */
static void
CopyTaskNode(int entrynum, struct Node *node)
{
   char *status[]=
   {
      "Inv", "Add", "Run", "Rdy", "Wait", "Excp", "Rem"
   },
   cli[5];

   Entries[entrynum].se_obj_id.address = node;

   savestrcpy(Entries[entrynum].se_obj_id.fullname, node,
              MAXFULLNAME - 1, NT_TASK);

   if ((node->ln_Type == NT_PROCESS) && ((struct Process *) node)->pr_CLI)
      sprintf(cli, "%3ld", ((struct Process *) node)->pr_TaskNum);
   else
      strcpy(cli, field[NO_FIELD]);

   sprintf(Entries[entrynum].se_Entry, EntryAttr[TASKS].ea_dataformat,
           Entries[entrynum].se_obj_id.fullname,
           (node->ln_Type == NT_PROCESS) ? (char *)"Proc" : (char *)"Task",
           node->ln_Pri,
           ((ULONG) ((struct Task *) node)->tc_SPUpper -
            (ULONG) ((struct Task *) node)->tc_SPLower),
           status[((struct Task *) node)->tc_State],
           cli);

   return;
}

   /*
    * MakeTaskList() erzeugt eine Liste der im System angemeldeten Tasks und
    * Prozesse
    */
void
MakeTaskList(void)
{
   struct Node *node,
       **membernode;
   register int i = 0;

   DPOS;

   countentries = CountNodes(&SysBase->TaskWait);
   countentries += CountNodes(&SysBase->TaskReady) + 1;

   if (NoEntries())
      return;

   Entries = AllocScrollEntries(countentries);

   membernode = (struct Node **) MyAllocVec(countentries * sizeof(struct Node *),
                                            MEMF_ANY | MEMF_CLEAR, KILL);

   Forbid();
   Disable();

   for (node = SysBase->TaskWait.lh_Head;
        node->ln_Succ && (i < countentries); node = node->ln_Succ)
      membernode[i++] = node;

   for (node = SysBase->TaskReady.lh_Head;
        node->ln_Succ && (i < countentries); node = node->ln_Succ)
      membernode[i++] = node;

   if (i < countentries)
      membernode[i++] = &SysBase->ThisTask->tc_Node;

   Enable();

   countentries = i;

   for (i = 0; i < countentries; i++)
      CopyTaskNode(i,membernode[i]);

   Permit();

   MyFreeVec(membernode);

   CreateEntryList(SORT);

   return;
}

   /*
    * SysSemaphoreList() listet alle angemeldeten Semaphoren
    * auf, die in der ExecBase eingetragen sind
    */
void
SysSemaphoreList(void)
{
   struct Node *node;
   int   i = 0;
   struct SignalSemaphore *SigSem;
   char name[23],
        sigtask[20];

   DPOS;

   PrintHeader(SEMAPHORES, NULL);

   EmptyListView();

   countentries = CountNodes(&SysBase->SemaphoreList);

   if (NoEntries())
      return;

   Entries = AllocScrollEntries(countentries);

   Forbid();

   for (node = SysBase->SemaphoreList.lh_Head;
        node->ln_Succ && (i < countentries); node = node->ln_Succ)
   {
      SigSem = (struct SignalSemaphore *) node;

      savestrcpy(name, node, 22, NT_SEMAPHORE);

      if (SigSem->ss_Owner)
         savestrcpy(sigtask,&(SigSem->ss_Owner->tc_Node), 19, NT_TASK );
      else
         strcpy(sigtask, field[NO_TASK]);

      sprintf(Entries[i].se_Entry, EntryAttr[SEMAPHORES].ea_dataformat,
              name, node->ln_Pri, sigtask);

      i++;
   }

   countentries = i;

   Permit();

   CreateEntryList(SORT);

   PrintStatistics();

   return;
}

   /*
    * SysVectorList() erzeugt eine Liste aller "kritischen"
    * Systemvektoren. Ist eine von ihnen ungleich NULL,
    * sollte dem nachgegangen werden, da diese eine beliebte
    * Einsprungadresse für Viren darstellen
    */
void
SysVectorList(void)
{
   struct ExecBase CopySysBase;
   int   i = 0;

   DPOS;

   PrintHeader(SYSVECTORS, NULL);

   EmptyListView();

   countentries = 14;

   Entries = AllocScrollEntries(countentries);

   Forbid();
   CopyMem((APTR) SysBase, (APTR) &CopySysBase, sizeof(struct ExecBase));
   Permit();

   strcpy(Entries[i].se_Entry, "----- Capture vectors");
   AddNodeToList(i++, NO_SORT);

   MakeHexEntry(&i, "ColdCapture", CopySysBase.ColdCapture);
   MakeHexEntry(&i, "CoolCapture", CopySysBase.CoolCapture);
   MakeHexEntry(&i, "WarmCapture", CopySysBase.WarmCapture);


   MakeHeadEntry(&i, "----- Kick pointer");

   MakeHexEntry(&i, "KickMemPtr", CopySysBase.KickMemPtr);
   MakeHexEntry(&i, "KickTagPtr", CopySysBase.KickTagPtr);
   MakeHexEntry(&i, "KickCheckSum", CopySysBase.KickCheckSum);

   MakeHeadEntry(&i, "----- Exec special pointer");

   MakeHexEntry(&i, "Debug entry", CopySysBase.DebugEntry);
   MakeHexEntry(&i, "ResModules", CopySysBase.ResModules);
   MakeHexEntry(&i, "MMU-Lock", CopySysBase.ex_MMULock);

   PrintStatistics();

   return;
}

   /*
    * SysSoftDeviceList() listet alle *.device auf, die in
    * der ExecBase angemeldet sind
    */
void
SysSoftDeviceList(void)
{
   struct Node *node;
   struct Library *device_lib;
   int   i = 0;

   DPOS;

   PrintHeader(SYSSOFTDEV, NULL);

   EmptyListView();

   countentries = CountNodes(&SysBase->DeviceList);

   if (NoEntries())
      return;

   Entries = AllocScrollEntries(countentries);

   Forbid();

   for (node = SysBase->DeviceList.lh_Head;
        node->ln_Succ && (i < countentries); node = node->ln_Succ)
   {
      device_lib = &((struct Device *) node)->dd_Library;

      Entries[i].se_obj_id.address = device_lib;
      savestrcpy(Entries[i].se_obj_id.fullname, node,
                 MAXFULLNAME - 1, NT_DEVICE);

      sprintf(Entries[i].se_Entry, EntryAttr[RESOURCES].ea_dataformat,
              Entries[i].se_obj_id.fullname,
              device_lib->lib_Version,
              device_lib->lib_Revision,
              device_lib->lib_OpenCnt);
      i++;
   }

   countentries = i;

   Permit();

   CreateEntryList(SORT);

   PrintStatistics();

   return;
}

