/*
   ***************************************************************************
   *
   * Datei:
   *      RSysDosLists.c
   *
   * Inhalt:
   *
   *      --- Globale Routinen ---
   *
   *    void MakeAssignList ( void );
   *    void MakeVolumeList ( void );
   *    void RSysLockList ( void );
   *    void SysCLIList ( void );
   *    void SysResidentList ( void );
   *    void SysResidentProg ( void );
   *
   *      --- Lokale  Routinen ---
   *
   *
   * Bemerkungen:
   *      Erzeugung von Listen der DOS-Library.
   *
   * Erstellungsdatum:
   *      07-Jul-93     Rolf Böhme
   *
   * Änderungen:
   *      07-Jul-93     Rolf Böhme        Erstellung
   *
   ***************************************************************************
 */

#include "RSys.h"
#include "protos.h"

 /*
  * MakeAssignList() erzeugt eine Liste aller Assigns im
  * System
  */
void
MakeAssignList (void)
{
  int i = 0;
  char helpdir[MAXFULLNAME], dir[39];
  DOSLIST *dl;
  BPTR lock;

  DPOS;

  countentries = CountDevices (LDF_ASSIGNS);

  if (NoEntries ())
    return;

  Entries = AllocScrollEntries (countentries);

  dl = LockDosList (LDF_ASSIGNS | LDF_READ);

  while ((dl = NextDosEntry (dl, LDF_ASSIGNS | LDF_READ)) && (i < countentries))
    {
      B2CStr (Entries[i].se_obj_id.fullname, dl->dol_Name);
      strcat (Entries[i].se_obj_id.fullname, ":");

      if (lock = Lock ((UBYTE *) Entries[i].se_obj_id.fullname, ACCESS_READ))
	{
	  NameFromLock (lock, (UBYTE *) helpdir, 107);
	  strncpy (dir, helpdir, 38);

	  UnLock (lock);
	}
      else
	strcpy (dir, field[NO_LOCK]);

      sprintf (Entries[i].se_Entry, EntryAttr[ASSIGNS].ea_dataformat,
	       Entries[i].se_obj_id.fullname, dir);

      AddNodeToList (i, SORT, 0);

      i++;
    }

  UnLockDosList (LDF_ASSIGNS | LDF_READ);

  PrintStatistics ();

  return;
}

 /*
  * MakeVolumeList() erzeugt eine Liste aller Volumes im
  * System
  */
void
MakeVolumeList (void)
{
  int i = 0;
  DOSLIST *dl;
  long free, used, percentused;
  char state[6], type[6];

  DPOS;

  DisableSysRequest (TRUE);

  countentries = CountDevices (LDF_VOLUMES);

  if (NoEntries ())
    return;

  Entries = AllocScrollEntries (countentries);

  dl = LockDosList (LDF_VOLUMES | LDF_READ);

  while ((dl = NextDosEntry (dl, LDF_VOLUMES | LDF_READ)) && (i < countentries))
    {
      B2CStr (Entries[i].se_obj_id.fullname, dl->dol_Name);
      strcat (Entries[i].se_obj_id.fullname, ":");

      FreeBytes (Entries[i].se_obj_id.fullname, &free, &used, &percentused, state, type);

      sprintf (Entries[i].se_Entry, EntryAttr[VOLUMES].ea_dataformat,
	       Entries[i].se_obj_id.fullname,
	       free, used, percentused,
	       (percentused > 90L) ? '*' : ' ',
	       state, type);

      AddNodeToList (i, SORT, 0);

      i++;
    }

  UnLockDosList (LDF_VOLUMES | LDF_READ);

  DisableSysRequest (FALSE);

  PrintStatistics ();

  return;
}


void
RSysLockList (void)
{
  LIST *DispList;
  REMEMBER *DispKey = NULL;
  NODE *node;
  RSYS_LOCKENTRY *LockNode;
  char *b_ptr;
  char *ac_ptr;
  BPTR lo;
  DOSLIST *dl;
  FILELOCK *lptr, *alptr = NULL;
  char buffer[MAXFULLNAME];
  char vol_buffer[MAXFULLNAME];
  int i;
  int retval;			/*GMD */
  int lock_flag;

  HandleHelp (MN_RSysLockList);

  PrintHeader (VOLLOCKS, NULL);

  EmptyListView ();

  DispList = AllocRemember (&DispKey, sizeof (LIST), MEMF_CLEAR);
  if (DispList)
    {
      NewList (DispList);
      Forbid ();
      dl = LockDosList (LDF_VOLUMES | LDF_READ);

      while (dl)
	{

	  if ((dl->dol_Type == DLT_VOLUME) && B2CStr (buffer, dl->dol_Name))
	    {
	      strcat (buffer, ":");
	      strcpy (vol_buffer, buffer);
	      strcat (vol_buffer, " <inv lock>");

	      if (lo = Lock ((UBYTE *) buffer, ACCESS_READ))
		{
		  for (lptr = BPTR_TO_C (FileLock, lo), lock_flag = TRUE;
		       lptr != NULL;
		       lptr = BPTR_TO_C (FileLock, lptr->fl_Link)
		    )

		    {
		      retval = DOSTRUE;
		      LockNode = AllocRemember (&DispKey,
				       sizeof (RSYS_LOCKENTRY), MEMF_CLEAR);

		      LockNode->node.ln_Name = AllocRemember (&DispKey,
						       BUFSIZE, MEMF_CLEAR);

		      /*
		       * test for valid lock
		       *
		       */
		      if ((TypeOfMem (lptr) == 0) ||
			  (BPTR_TO_C (FileLock, lptr->fl_Volume) !=
			   (FILELOCK *) dl))
			{
			  lock_flag = FALSE;	/* invalid lock */
			  ac_ptr = "";
			  b_ptr = vol_buffer;
			}
		      else
			{

			  ac_ptr = "!!!!!";
			  b_ptr = "<NameFromLock Fail>";
			  retval = NameFromLock (C_TO_BPTR (lptr),
					 (UBYTE *) buffer, MAXFULLNAME - 1);

			  if (retval != DOSFALSE)
			    {
			      switch (-lptr->fl_Access)
				{
				case 0:
				  ac_ptr = "--0--";
				  break;

				case 1:
				  ac_ptr = "WRITE";
				  break;

				case 2:
				  ac_ptr = "READ";
				  break;

				default:
				  ac_ptr = "?????";
				  break;
				}

			      b_ptr = buffer;
			    }
			}

		      sprintf (LockNode->node.ln_Name,
			       EntryAttr[VOLLOCKS].ea_dataformat,
			       lptr,
			       b_ptr, ac_ptr);

		      strncpy (LockNode->obj.fullname, buffer, MAXFULLNAME);

		      LockNode->obj.address = lptr;
		      AddNodeSorted (DispList, &(LockNode->node), 9);

		      if ((lock_flag == FALSE) || (retval == DOSFALSE))
			break;	/* bad lock */

		      if (BPTR_TO_C (FileLock, lptr->fl_Link) == alptr)
			break;

		      alptr = lptr;

		    }		/*end-for */

		  UnLock (lo);

		}		/*end-if lo */

	    }			/*end-if dl */

	  dl = NextDosEntry (dl, LDF_VOLUMES | LDF_READ);

	}			/*end-while */

      UnLockDosList (LDF_VOLUMES | LDF_READ);

      Permit ();

      countentries = CountNodes (DispList);

      if (!NoEntries ())
	{
	  Entries = AllocScrollEntries (countentries);

	  for (node = DispList->lh_Head, i = 0;
	       node->ln_Succ && (i < countentries);
	       node = node->ln_Succ, i++)
	    {
	      strcpy (Entries[i].se_Entry, node->ln_Name);
	      Entries[i].se_obj_id.address = ((RSYS_LOCKENTRY *) node)->obj.address;
	      strcpy (Entries[i].se_obj_id.fullname,
		      ((RSYS_LOCKENTRY *) node)->obj.fullname);
	    }

	  CreateEntryList (SORT, 9);
	}

      FreeRemember (&DispKey, TRUE);

      PrintStatistics ();
    }
  else
    ErrorHandle ("Tmp LockList", MEMORY_ERR, ALLOC_FAIL, KILL);

  return;
}

/*
 * SysResidentList() listet die residenten Handler
 * aller Devices auf
 */
void
SysResidentList (void)
{
  int i = 0;
  FILESYSSTARTUPMSG *fssm;
  DOSLIST *dl;

  char devhandler[100];

  DPOS;

  HandleHelp (MN_SysResidentList);

  PrintHeader (DEVS, NULL);

  EmptyListView ();

  countentries = CountDevices (CNTMASK);

  if (NoEntries ())
    return;

  Entries = AllocScrollEntries (countentries);

  DisableSysRequest (TRUE);

  dl = LockDosList (MASK);

  while ((dl = NextDosEntry (dl, MASK)) && (i < countentries))
    {
      B2CStr (Entries[i].se_obj_id.fullname, dl->dol_Name);
      strcat (Entries[i].se_obj_id.fullname, ":");

      Entries[i].se_obj_id.address = dl;

      if (dl->dol_Task && (fssm = B2C (dl->dol_misc.dol_handler.dol_Startup)))
	{
	  B2CStr (devhandler, fssm->fssm_Device);
	}
      else if (dl->dol_misc.dol_handler.dol_Handler)
	{
	  B2CStr (devhandler, dl->dol_misc.dol_handler.dol_Handler);
	}
      else
	{
	  strcpy (devhandler, field[NO_HANDLER]);
	}

      sprintf (Entries[i].se_Entry,
	       EntryAttr[DEVS].ea_dataformat,
	       Entries[i].se_obj_id.fullname,
	       devhandler);

      i++;
    }

  countentries = i;

  UnLockDosList (MASK);

  DisableSysRequest (FALSE);

  CreateEntryList (SORT, 0);

  PrintStatistics ();

  return;
}

/*
 * SysCLIList() erzeugt eine Liste aller CLI's im System
 */
void
SysCLIList (void)
{
  int clicnt, i = 0;
  PROCESS *cliproc;

  HandleHelp (MN_SysCLIList);

  DPOS;

  PrintHeader (CLI, NULL);

  EmptyListView ();

  countentries = MaxCli ();

  if (NoEntries ())
    return;

  Entries = AllocScrollEntries (countentries);

  Forbid ();

  for (clicnt = 1; clicnt < countentries; clicnt++)
    {
      cliproc = FindCliProc ((ULONG) clicnt);
      if (cliproc)
	{
	  savestrcpy (Entries[i].se_obj_id.fullname, &(cliproc->pr_Task.tc_Node),
		      MAXFULLNAME - 1, NT_PROCESS);
	  Entries[i].se_obj_id.address = cliproc;

	  sprintf (Entries[i].se_Entry, EntryAttr[CLI].ea_dataformat,
		   Entries[i].se_obj_id.address,
		   (char) cliproc->pr_TaskNum,
		   Entries[i].se_obj_id.fullname,
		   cliproc->pr_Task.tc_Node.ln_Pri,
		   ((ULONG) cliproc->pr_Task.tc_SPUpper -
		    (ULONG) cliproc->pr_Task.tc_SPLower));

	  i++;
	}
    }

  countentries = i;

  Permit ();

  CreateEntryList (SORT, 9);

  PrintStatistics ();

  return;
}


void
SysResidentProg (void)
{
  char name[BUFSIZE];
  ROOTNODE *RN = DOSBase->dl_Root;
  DOSINFO *di = (DOSINFO *) BADDR (RN->rn_Info);
  RSYS_RESIDENTLIST *RL = (RSYS_RESIDENTLIST *) BADDR (di->di_NetHand),
   *loop = RL;
  int cnt = 0, i;

  DPOS;

  HandleHelp (MN_SysResidentProg);

  PrintHeader (RESIDENTS, NULL);

  EmptyListView ();

  PrintInfo ("Counting residents", NO_SPEAK, 0);

  Forbid ();

  for (loop = RL; loop; loop = (RSYS_RESIDENTLIST *) BADDR (loop->rl_Next))
    cnt++;

  Permit ();

  countentries = cnt;

  if (NoEntries ())
    return;

  Entries = AllocScrollEntries (countentries);

  Forbid ();

  cnt = 0;

  for (loop = RL; loop && (cnt < countentries); loop = (RSYS_RESIDENTLIST *) BADDR (loop->rl_Next))
    {
      for (i = 0; (i < *(UBYTE *) & loop->rl_SegName) && (i < BUFSIZE); i++)
	name[i] = (char) *(UBYTE *) (((BPTR) & loop->rl_SegName) + i + 1L);

      name[i] = STRINGEND;

      Entries[cnt].se_obj_id.address = loop;

      sprintf (Entries[cnt].se_Entry, EntryAttr[RESIDENTS].ea_dataformat,
	       Entries[cnt].se_obj_id.address,
	       name,
	       loop->rl_UseCount,
	       ((loop->rl_UseCount >= 0) ? "EXTERNAL" :
		((loop->rl_UseCount == -1) ? "SYSTEM" : "INTERNAL")));

      cnt++;
    }

  countentries = cnt;

  Permit ();

  CreateEntryList (SORT, 9);

  PrintStatistics ();

  return;
}

void
RSysFaultMessages (void)
{
  int cnt;
  UBYTE fmsg[BUFSIZE];

/*   HandleHelp(MN_SysResidentProg); */

  PrintHeader (FAULTMSG, NULL);

  EmptyListView ();

  countentries = 256;

  Entries = AllocScrollEntries (countentries);

  sprintf (Entries[0].se_Entry, EntryAttr[FAULTMSG].ea_dataformat,
	   0, field[NO_FIELD]);

  for (cnt = 1; cnt < countentries; cnt++)
    {
      Fault (cnt, (UBYTE *) "-", fmsg, BUFSIZE - 1);

      sprintf (Entries[cnt].se_Entry, EntryAttr[FAULTMSG].ea_dataformat,
	       cnt, &fmsg[2]);
    }

  CreateEntryList (NO_SORT, 0);

  PrintStatistics ();

  return;
}
