/*
 *	ListDevs.c
 *
 *	This program produces a list of devices on it's standard.
 *	output.
 *
 *	Program		Date		Action
 *	D. Thomas	24 April 1987	v1.0 Initial Coding.
 *
 */

#include "exec/execbase.h"
#include "exec/devices.h
#include "exec/memory.h"
#include "functions.h"

extern struct ExecBase *SysBase;	/* Exec's base ptr */

main ()

{

  register struct Device *t;   	/* ptr to lib list */
  register struct List     head;	/* for my copy of the lib list */
  char                    *flag;

  NewList (&head);

  Disable ();

  if (getlist (&SysBase->DeviceList, &head))
    cleanup (&head);

  Enable ();

  puts ("Flags   NegS PosS Version Revision OpenCnt Name");

  while (t = (struct Device *) RemHead (&head)) {

    if (t->dd_Library.lib_Flags & LIBF_SUMMING)
      flag = "Summing";
    else if (t->dd_Library.lib_Flags & LIBF_CHANGED)
      flag = "Changed";
    else if (t->dd_Library.lib_Flags & LIBF_SUMUSED)
      flag = "Sumused";
    else if (t->dd_Library.lib_Flags & LIBF_DELEXP)
      flag = "Expunge";
    else
      flag = "";

    printf ("%-7.7s ", flag);
    printf ("%4x %4x %7u %8u %7u %s\n",
      t->dd_Library.lib_NegSize, t->dd_Library.lib_PosSize,
      t->dd_Library.lib_Version, t->dd_Library.lib_Revision,
      t->dd_Library.lib_OpenCnt, 
      (t->dd_Library.lib_Node.ln_Name ? t->dd_Library.lib_Node.ln_Name : "<unset>"));
    
    if (t->dd_Library.lib_Node.ln_Name)
      FreeMem (t->dd_Library.lib_Node.ln_Name, (long) strlen (t->dd_Library.lib_Node.ln_Name) + 1);
    FreeMem (t, (long) sizeof *t);

  }

  exit (0);

}

freelist (l)

struct List *l;

{

  struct Device *t;

  while (t = (struct Device *) RemHead (l)) {
    if (t->dd_Library.lib_Node.ln_Name)
      FreeMem (t->dd_Library.lib_Node.ln_Name, (long) strlen (t->dd_Library.lib_Node.ln_Name) + 1);
    FreeMem (t, (long) sizeof *t);
  }

}

cleanup (l)

struct List *l;

{

  Enable ();
  freelist (l);
  puts ("Out of Memory!");
  exit (0);

}

getlist (tl, l)

struct List *tl;
struct List *l;

{

  register struct Device *t;

  for (t = (struct Device *) tl->lh_Head;
       t->dd_Library.lib_Node.ln_Succ;
       t = (struct Device *) t->dd_Library.lib_Node.ln_Succ)
    if (onenode (t, l))
      return TRUE;

  return FALSE;

}

onenode (t, l)

struct Device *t;
struct List    *l;

{

  register struct Device *tc;

  if (!(tc = (struct Device *) AllocMem ((long) sizeof *t, MEMF_CLEAR)))
      return TRUE;
  *tc = *t;

  if (t->dd_Library.lib_Node.ln_Name) {
    if (!(tc->dd_Library.lib_Node.ln_Name = (char *) AllocMem ((long) strlen (t->dd_Library.lib_Node.ln_Name) + 1, 0L))) {
      FreeMem (tc, (long) sizeof *tc);
      return TRUE;
    }
    strcpy (tc->dd_Library.lib_Node.ln_Name, t->dd_Library.lib_Node.ln_Name);
  }

  AddTail (l, tc);

  return FALSE;

}
