#include "struct.c"

#define Fail(s) Printf("%s File %s Line %ld\n", s, __FILE__, __LINE__);

char   Version[]  = "$VER: DU 1.4 "__DATE__" "__TIME__;
char   Template[] = "DIR";

struct DosLibrary *DOSBase;
struct ExecBase   *SysBase;
       BOOL        Break = FALSE;

ULONG du(char *);


ULONG __saveds main(void)
{
  struct RDArgs *rd;
  ULONG          ArgArray[1];
  char          *Dir;
  ULONG		 Total;
  ULONG          RC;

  SysBase = (*((struct ExecBase **)4));
  if (DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37))
    {
      ArgArray[0] = NULL;
      rd = ReadArgs(Template, ArgArray, NULL);
      if (!(Dir = (char *)ArgArray[0])) Dir = "";

      Total = du(Dir);
      if (!Break)
       {
	Printf("Total %8ld\n", Total);
	RC = 0;
       }
      else
       {
	Printf("<Break>\n",NULL);
	RC = 5;
       }
  
      if (rd) FreeArgs(rd);
      CloseLibrary(DOSBase);
    }
  else RC = 20;
  return RC;
}

ULONG du(char *DirName)
{
  struct ExAllControl *eac;
  struct ExAllData    *ead;
  BPTR          lock;
  void         *Buffer;
  BOOL          more;
  ULONG         Total = 0;
  ULONG         SubDir;
  char         *NewDir;
  LONG          NewDirLength;

  Break |= SetSignal(0, 0) & SIGBREAKF_CTRL_C;
  if (lock = Lock(DirName, ACCESS_READ))
    {
      if (eac = AllocDosObject(DOS_EXALLCONTROL,NULL))
	{
	  eac->eac_LastKey = 0;
	  if (Buffer = AllocVec(1024, NULL))
	    {
	      do
		{
		  more = ExAll(lock, Buffer, 1024, ED_SIZE, eac);
		  if ((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES)) break;
		  if (eac->eac_Entries == 0) continue;
		  ead = (struct ExAllData *)Buffer;
		  do 
		    {
		      Break |= SetSignal(0, 0) & SIGBREAKF_CTRL_C;
		      switch (ead->ed_Type)
			{
			case ST_USERDIR :
			  NewDirLength = strlen(DirName)+strlen(ead->ed_Name)+3;
			  NewDir = AllocVec(NewDirLength, NULL);
			  strcpy(NewDir, DirName);
			  AddPart(NewDir, ead->ed_Name, NewDirLength);
			  SubDir = du(NewDir);
			  Printf("%8ld %s\n", SubDir, NewDir);
			  Total += SubDir;
			  FreeVec(NewDir);
			  break;
			case ST_FILE :
			  Total += ead->ed_Size;
			  break;
			  default :
			  break;
			}
		      ead = ead->ed_Next;
		    } while (ead && !Break);
		} while (more && !Break);
	      FreeVec(Buffer);
	    }
	  else Fail("Can't get memory for ExAllBuffer!");
	  FreeDosObject(DOS_EXALLCONTROL, eac);
	}
      else Fail("Can't get ExAllControl!");
      UnLock(lock);
    } else Fail("Can't get lock on dir!");
  return Total;
}

