/*
 * libs.c - shows all libraries, devices and resources currently installed
 *
 * Bruno Costa - 31 Mar 90 - 27 Mar 91
 *
 */

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/tasks.h>
#include <exec/execbase.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <proto/exec.h>
#include <proto/dos.h>

#define EOS '\0'
#define BUFSIZE 5000

int bufpos = 0;
char buffer[BUFSIZE];

void print (char *str)
{
 if (str == NULL)
   str = "NULL";

 while (bufpos < BUFSIZE  &&  *str != EOS)
   buffer[bufpos++] = *str++;
}

void printc (int c)
{
 if (bufpos < BUFSIZE)
   buffer[bufpos++] = c;
}

void flush (void)
{
 char *p, *q;

 for (p = buffer, q = p + bufpos; p < q; p += 100)
   if (p + 100 >= q)
     Write (Output (), p, q - p);
   else
     Write (Output (), p, 100);
}

#define isempty(list) (list->lh_Head->ln_Succ == NULL)

void dumpport (struct Node *portnode)
{
 struct MsgPort *port = (struct MsgPort *) portnode;

 if (portnode == NULL)
   return;

 print ("\t");
 print (portnode->ln_Name);
 if (port->mp_Flags == PA_SIGNAL  &&  port->mp_SigTask)
 {
   print ("\t; signal ");
   print (port->mp_SigTask->tc_Node.ln_Name);
 }
 print ("\n");
}

void dumpname (struct Node *node)
{
 if (node == NULL)
   return;

 print ("\t");
 print (node->ln_Name);
 print ("\n");
}

void dumptask (struct Node *tasknode)
{
 struct Process *proc = (struct Process *) tasknode;	/* may be invalid */

 if (tasknode == NULL)
   return;

 print ("\t");
 print (tasknode->ln_Name);
 if (tasknode->ln_Type == NT_PROCESS  &&  proc->pr_CLI)
 {
   struct CommandLineInterface *cli = BADDR (proc->pr_CLI);
   unsigned char *src = BADDR (cli->cli_CommandName);
   unsigned char *p, *q;

   print (" (");
   for (p = src + 1, q = p + *src; p < q; p++)
     printc (*p);
   print (")");
 }
 print ("\n");
}

void dumplib (struct Node *libnode)
{
 struct Library *lib = (struct Library *)libnode;

 if (libnode == NULL)
   return;

 print ("\t");
 print (libnode->ln_Name);
 print ("\t; ");
 if (lib->lib_IdString)
   print ((char *)lib->lib_IdString);
 else
   print ("\n");
}

void dumplist (struct List *list, void (*dumpnode) (struct Node *))
{
 struct Node *node;

 if (!isempty (list))
   for (node = list->lh_Head; node->ln_Succ; node = node->ln_Succ)
     (*dumpnode) (node);
}

void main (void)
{
 extern struct ExecBase *SysBase;

 print ("\x1b[33mLibs v1.2\x1b[31m - \xa9 1990 by Bruno Costa\n");

 Disable ();

 print ("\n\x1b[1mLibraries:\x1b[0m\n");
 dumplist (&SysBase->LibList, dumplib);

 print ("\n\x1b[1mDevices:\x1b[0m\n");
 dumplist (&SysBase->DeviceList, dumplib);

 print ("\n\x1b[1mResources:\x1b[0m\n");
 dumplist (&SysBase->ResourceList, dumpname);

 print ("\n\x1b[1mPorts:\x1b[0m\n");
 dumplist (&SysBase->PortList, dumpport);

 print ("\n\x1b[1mReady tasks:\x1b[0m\n");
 dumplist (&SysBase->TaskReady, dumptask);

 print ("\n\x1b[1mWaiting tasks:\x1b[0m\n");
 dumplist (&SysBase->TaskWait, dumptask);

 Enable ();
 flush ();
}
