/*
***************************************************************************
*
* 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"

	/*
	 * MakeAssignList() erzeugt eine Liste aller Assigns im
	 * System
	 */
void
MakeAssignList(void)
{
	int	i = 0;
	char	helpdir[MAXFULLNAME],dir[39];
	struct 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;
	struct 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)
{
	struct List *DispList;
	struct Remember *DispKey = NULL;
	struct Node *node;
   struct lockentry {
      struct Node node;
      struct objectid obj;
   } *LockNode;
	BPTR	lo;
	struct DosList *dl;
	register struct FileLock *lptr,
									 *alptr = NULL;
	char buffer[MAXFULLNAME], *access[] = { "-----", "WRITE", "READ" };
	int i;

   HandleHelp(MN_RSysLockList);

	PrintHeader(VOLLOCKS, NULL);

	EmptyListView();

	DispList = AllocRemember(&DispKey,sizeof(struct 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, ":");

				if (lo = Lock((UBYTE *)buffer, ACCESS_READ))
				{
					for (lptr = BPTR_TO_C(FileLock, lo);lptr != NULL; lptr = BPTR_TO_C(FileLock, lptr->fl_Link))
					{
						if (NameFromLock(C_TO_BPTR(lptr), (UBYTE *)buffer, MAXFULLNAME-1) &&
							 (LockNode = AllocRemember(&DispKey,sizeof(struct lockentry), MEMF_CLEAR)) &&
							 (LockNode->node.ln_Name = AllocRemember(&DispKey,BUFSIZE, MEMF_CLEAR)))
						{
							sprintf(LockNode->node.ln_Name,EntryAttr[VOLLOCKS].ea_dataformat,
                             (APTR)C_TO_BPTR(lptr),
									  buffer, access[-lptr->fl_Access]);

                     strncpy(LockNode->obj.fullname, buffer, MAXFULLNAME);
                     LockNode->obj.address = (APTR)C_TO_BPTR(lptr);

							AddNodeSorted(DispList,&(LockNode->node), 9);
						}

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

						alptr = lptr;
					}

					UnLock(lo);
				}
			}

			dl = NextDosEntry(dl, LDF_VOLUMES | LDF_READ);
		}

		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 = ((struct lockentry *)node)->obj.address;
            strcpy(Entries[i].se_obj_id.fullname, ((struct 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;
	struct FileSysStartupMsg *fssm;
	struct DosList *dl;
	char devhandler[30];

	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;
	struct 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)
{
   struct ResidentList
   {
   	BPTR	rl_Next;
   	LONG	rl_UseCount;
   	BPTR	rl_SegList;
   	BSTR	rl_SegName;
   };
	char	name[BUFSIZE];
   struct RootNode *RN = DOSBase->dl_Root;
   struct DosInfo *di = (struct DosInfo *) BADDR(RN->rn_Info);
   struct ResidentList *RL = (struct 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 = (struct 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 = (struct 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;
}
