#define NAME     "MakeMountList"
#define REVISION "9"
#define DATE     "09.06.2000"

/* Programmheader

	Name:		MakeMountList
	Author:		SDI
	Distribution:	PD
	Description:	creates MountList entry from DosList

 1.4   12.01.98 : built form GenML 1.3 by Jean-Michel Bezeau
 1.5   14.01.98 : a little addition
 1.6   15.02.98 : compiled with SAS-C
 1.7   20.04.98 : added version string
 1.8   06.09.98 : better checks reducing errors and hits
 1.9   09.06.00 : some fixes
*/

#include <proto/exec.h>
#include <proto/dos.h>
#include <dos/dosextens.h>
#include <dos/filehandler.h>
#include "SDI_version.h"

#define GetDosEnvec(A) ((struct DosEnvec *) BADDR((A)->fssm_Environ))

#define LOWMEMAREA	200	/* security border to find non-pointers */
#define HIGHMEMAREA	-200	/* security border to find non-pointers */

static void MakeMountList(struct DosList *, struct DosLibrary *);

LONG main(void)
{
  ULONG ret = RETURN_FAIL;
  struct DosLibrary *DOSBase;
  struct ExecBase *SysBase;
  struct Process *task;

  SysBase = (*((struct ExecBase **) 4));
  /* test for WB and reply startup-message */
  if(!(task = (struct Process *) FindTask(0))->pr_CLI)
  {
    WaitPort(&task->pr_MsgPort);
    Forbid();
    ReplyMsg(GetMsg(&task->pr_MsgPort));
    return RETURN_FAIL;
  }

  if((DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  {
    struct RDArgs *rda;
    STRPTR devname = 0;

    if((rda = ReadArgs("HANDLER", (LONG *) &devname, 0)))
    {
      struct DosList *dosl, *dsl;
      if((dosl = LockDosList(LDF_DEVICES|LDF_READ)))
      {
	if(devname)
	{
	  LONG i;
	  for(i = 0; devname[i]; ++i)
	    ;
	  if(devname[--i] == ':')
	    devname[i] = 0;

          if((dsl = FindDosEntry(dosl, devname, LDF_DEVICES)))
	  {
            MakeMountList(dsl, DOSBase); ret = 0;
	  }
          else
            Printf("Handler \"%s:\" not available\n", devname);
        }
	if(ret)
	{
	  dsl = dosl;
	  Printf("Available handlers: ");
	  while((dsl = NextDosEntry(dsl, LDF_DEVICES)))
            Printf("%b ", dsl->dol_Name);
	  Printf("\n");
	}

        UnLockDosList(LDF_DEVICES|LDF_READ);
      }
      FreeArgs(rda);
    }
    CloseLibrary((struct Library *) DOSBase);
  }
  return ret;
}

/* Return length of BSTR. */
static LONG Bstrlen(BSTR bstr)
{
  if(((LONG) bstr) > HIGHMEMAREA && bstr < LOWMEMAREA)
    return 0;
  else
    return (LONG) (*((STRPTR) BADDR(bstr)));
}

/* Do a bit clever checking, hope that helps */
static struct FileSysStartupMsg *GetFileSysStartupMsg(struct DosList *dosl)
{
  struct FileSysStartupMsg *fssm;
  struct DosEnvec *denv;

  fssm = (struct FileSysStartupMsg *)
  BADDR(dosl->dol_misc.dol_handler.dol_Startup);
  if((LONG) fssm > LOWMEMAREA)
  {
    denv = GetDosEnvec(fssm);

    /* test if the entry is a correct fssm -> check for valid data */
    if(denv && denv->de_TableSize < 64 &&
    !(denv->de_SizeBlock & 0x127) && (denv->de_LowCyl <= denv->de_HighCyl))
      return fssm;
    else
      return 0;
  }
  else
    return 0;
}

static void MakeMountList(struct DosList *dosl, struct DosLibrary *DOSBase)
{
  struct FileSysStartupMsg *fssm;
  struct DosEnvec *denv;

  Printf("%b:\n", dosl->dol_Name);

  if((fssm = GetFileSysStartupMsg(dosl)))
  {
    /* device name is zero ended */
    Printf("\tDevice\t\t= %s\n", 1 + (fssm->fssm_Device<<2));
    if(fssm->fssm_Unit > LOWMEMAREA)
      Printf("\tUnit\t\t= \"%s\"\n", fssm->fssm_Unit);
    else
      Printf("\tUnit\t\t= %ld\n", fssm->fssm_Unit);
    if(fssm->fssm_Flags)
      Printf("\tFlags\t\t= 0x%ld\n", fssm->fssm_Flags);
    if(Bstrlen(dosl->dol_misc.dol_handler.dol_Handler))
      Printf("\tFileSystem\t= %b\n", dosl->dol_misc.dol_handler.dol_Handler);
  }
  else if(Bstrlen(dosl->dol_misc.dol_handler.dol_Handler))
    Printf("\tHandler\t\t= %b\n", dosl->dol_misc.dol_handler.dol_Handler);

  Printf("\tPriority\t= %ld\n", dosl->dol_misc.dol_handler.dol_Priority);
  Printf("\tStackSize\t= %ld\n", dosl->dol_misc.dol_handler.dol_StackSize);
  Printf("\tGlobVec\t\t= %ld\n", dosl->dol_misc.dol_handler.dol_GlobVec);

  if(dosl->dol_misc.dol_handler.dol_Startup && !fssm)
  {
    if(Bstrlen(dosl->dol_misc.dol_handler.dol_Startup))
      Printf("\tStartup\t\t= \"%b\"\n", dosl->dol_misc.dol_handler.dol_Startup);
    else
      Printf("\tStartup\t\t= 0x%ld\n", dosl->dol_misc.dol_handler.dol_Startup);
  }
  else if(fssm)
  {
    denv = GetDosEnvec(fssm);

    if(denv->de_SizeBlock != 128)
      Printf("\tBlockSize\t= %ld\n", denv->de_SizeBlock*4);
    Printf("\tSurfaces\t= %ld\n", denv->de_Surfaces);
    if(denv->de_SectorPerBlock != 1)
      Printf("\tSectorsPerBlock\t= %ld\n", denv->de_SectorPerBlock);
    Printf("\tBlocksPerTrack\t= %ld\n", denv->de_BlocksPerTrack);
    Printf("\tReserved\t= %ld\n", denv->de_Reserved);
    if(denv->de_PreAlloc)
      Printf("\tPreAlloc\t= %ld\n", denv->de_PreAlloc);
    if(denv->de_Interleave)
      Printf("\tInterleave\t= %ld\n", denv->de_Interleave);
    Printf("\tLowCyl\t\t= %ld\n", denv->de_LowCyl);
    Printf("\tHighCyl\t\t= %ld\n", denv->de_HighCyl);
    Printf("\tBuffers\t\t= %ld\n", denv->de_NumBuffers);
    if(denv->de_TableSize >= DE_BUFMEMTYPE)
      Printf("\tBufMemType\t= %ld\n", denv->de_BufMemType);
    if(denv->de_TableSize >= DE_MAXTRANSFER)
      Printf("\tMaxTransfer\t= 0x%lx\n", denv->de_MaxTransfer);
    if(denv->de_TableSize >= DE_MASK)
      Printf("\tMask\t\t= 0x%lx\n", denv->de_Mask);
    if(denv->de_TableSize >= DE_BOOTPRI && denv->de_BootPri)
      Printf("\tBootPri\t\t= %ld\n", denv->de_BootPri);
    if(denv->de_TableSize >= DE_DOSTYPE)
      Printf("\tDosType\t\t= 0x%lx\n", denv->de_DosType);
    if(denv->de_TableSize >= DE_BAUD && denv->de_Baud)
      Printf("\tBaud\t\t= %ld\n", denv->de_Baud);
    if(denv->de_TableSize >= DE_CONTROL && denv->de_Control)
      Printf("\tControl\t\t= %b\n", denv->de_Control);
    if(denv->de_TableSize >= DE_BOOTBLOCKS && denv->de_BootBlocks)
      Printf ("\tBootBlocks\t= %ld\n", denv->de_BootBlocks);
  }

  Printf ("#\n");
}

